Reading stderr

K

Kenny McCormack

Common? Really? This is the first time I remember this question
being asked here.

In fairness, common problems are not all posted here.[/QUOTE]

Pretty obvious, isn't it?

But then, Pfaffy's ignorance knows no bounds.

(I was, quite frankly, speechless when I saw his post)
 
L

Larry Gates

In fairness, common problems are not all posted here.

Pretty obvious, isn't it?

But then, Pfaffy's ignorance knows no bounds.

(I was, quite frankly, speechless when I saw his post)[/QUOTE]

Ben comes from Dewitt, publishes in theoretical computer science, and
probably had the misfortune of cheering for the Eagles.

I wonder what he hears of Knuth.

I wonder what he might say about academic funding at Stanford.
--
larry

As pointed out in a followup, Real Perl Programmers prefer things to be
visually distinct.
-- Larry Wall in <[email protected]>
 
P

Peter Nilsson

Ben Pfaff said:
Ben Pfaff said:
stderr is an output stream.  Reading from it will,
portably, have no useful effect.

I remember I've been told it is undefined behavior. [...]

That would not surprise me, but in a quick scan through
C99 I couldn't find anything that says so.  Anyone have
a cite?

7.19.3p7 [Files] "At program startup, three text streams
are predefined and need not be opened explicitly - standard
input (for reading conventional input), standard output
(for writing conventional output), and standard error (for
writing diagnostic output). ..."

7.19.7.1p1 [fgetc] "If the end-of-file indicator for the
*input stream* pointed to by stream..." [emphasis mine]

Seems pretty clear there is no standard behaviour for
reading from an output stream.
 
B

Bumbala

Not in standard C, but most systems will provide some way to output to
memory.  You will need to study your C implementation's
documentation to see if there is one.

The static library is a Win32 project in VS2005 without MFC support.
Is there any support on this system?
 
K

Keith Thompson

Bumbala said:
The static library is a Win32 project in VS2005 without MFC support.
Is there any support on this system?o

As Ben wrote, "You will need to study your C implementation's
documentation to see if there is one."

Or you could post to comp.os.ms-windows.programmer.win32, or to one of
the microsoft.* groups.
 
R

Richard Tobin

Ben Pfaff said:
Common? Really? This is the first time I remember this question
being asked here.

I don't know whether it's been asked *here*, but it's certainly a very
common problem. Writers of libraries should think twice before
writing error messages to a FILE, just as they should think twice
before using glibal variables. Error messages are part of a library's
interface.

-- Richard
 
R

Richard Tobin

Kenny McCormack said:
Now, I won't go into the full details (it is much more fun to work it
out on your own), but the basic method is to use some variation of the
setbuf() call to create a large buffer (large enough to contain as much
as output as you ever expect to get - i.e., so that it never actually
gets written out) for the stream(s) in question.

.... and hope the library never calls fflush(stderr).

-- Richard
 
M

mohi

The static library performs some operations and outputs to "stderr" if
an error is occured. I want to log the messages in stderr in the main
library. However, when I try to read stderr as given below:
char buffer[4096];
fscanf(stderr, "%s", buffer);

First up, unless you're *sure* that the messages produced by the library
won't exceed 4096 bytes, an unbounded string scan like this could lead
to a buffer overflow.
I get strange characters in the buffer, not the message. However, when
I quick watch stderr, I see the message in stderr->_base member.
What am I doing wrong? Thanks.

As people have said, this is difficult to do portably.

One solution on POSIX-like systems would be to use an anonymous pipe to
temporarily replace stderr's file descriptor. Here is some example code
to give you the idea:

#include <stdio.h>
#include <unistd.h>

void some_library_function(void)
{
  fputs("hello!\n", stderr);

}

int main(void)
{
  int stderr_backup, pipefd[2];
  char buf[4096];
  if(pipe(pipefd) == -1) {
    perror("pipe");
    return 1;
  }
  if((stderr_backup = dup(STDERR_FILENO)) == -1) {
    perror("dup");
    return 1;
  }
  if(dup2(pipefd[1], STDERR_FILENO) == -1) {
    perror("dup2");
    return 1;
  }
  some_library_function();
  if(read(pipefd[0], buf, sizeof(buf)) == -1) {
    perror("read");
    return 1;
  }
  buf[sizeof(buf)-1]='\0';
  printf("read from stderr: %s", buf);
  close(pipefd[0]);
  close(pipefd[1]);
  if(dup2(stderr_backup, STDERR_FILENO) == -1) {
    perror("dup2");
    return 1;
  }
  puts("== original stderr now restored ==");
  some_library_function();
  return 0;

}

@antoninus.....
may be i am wrong but wont creating a pipe would be problematic.....


what i mean is say at the place where the library_function() is call
all there will be just writes to the pipe and no one will be reading
at that point as it is only a single process thats using the both ends
of the pipe...
so won't it be the case that the process writting to the pipe multiple
times will get blocked or there could be a chance that the maximum
size of the pipe buffer will get
over and create problem????

Mohan gupta
 
K

Kenny McCormack

... and hope the library never calls fflush(stderr).

True, but then again, you have to work with that which you have to work with.

Note that in my case, I did, in fact, have the source of the library, so
I was able to verify that it didn't do anything evil (like calling fflush()).
The point was that it generated output all over the place, so that
simply re-writing it to "not do that" was not a feasible option.
 
K

Kenny McCormack

I don't know whether it's been asked *here*, but it's certainly a very
common problem. Writers of libraries should think twice before
writing error messages to a FILE, just as they should think twice
before using glibal variables. Error messages are part of a library's
interface.

Indeed. As is, ultimately, the (standard) output as well.
In my case, I was going for capturing the stdout.
 
F

Falcon Kirtaran

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
The static library performs some operations and outputs to "stderr" if
an error is occured. I want to log the messages in stderr in the main
library. However, when I try to read stderr as given below:
char buffer[4096];
fscanf(stderr, "%s", buffer);
First up, unless you're *sure* that the messages produced by the library
won't exceed 4096 bytes, an unbounded string scan like this could lead
to a buffer overflow.
I get strange characters in the buffer, not the message. However, when
I quick watch stderr, I see the message in stderr->_base member.
What am I doing wrong? Thanks.
As people have said, this is difficult to do portably.

One solution on POSIX-like systems would be to use an anonymous pipe to
temporarily replace stderr's file descriptor. Here is some example code
to give you the idea:

#include <stdio.h>
#include <unistd.h>

void some_library_function(void)
{
fputs("hello!\n", stderr);

}

int main(void)
{
int stderr_backup, pipefd[2];
char buf[4096];
if(pipe(pipefd) == -1) {
perror("pipe");
return 1;
}
if((stderr_backup = dup(STDERR_FILENO)) == -1) {
perror("dup");
return 1;
}
if(dup2(pipefd[1], STDERR_FILENO) == -1) {
perror("dup2");
return 1;
}
some_library_function();
if(read(pipefd[0], buf, sizeof(buf)) == -1) {
perror("read");
return 1;
}
buf[sizeof(buf)-1]='\0';
printf("read from stderr: %s", buf);
close(pipefd[0]);
close(pipefd[1]);
if(dup2(stderr_backup, STDERR_FILENO) == -1) {
perror("dup2");
return 1;
}
puts("== original stderr now restored ==");
some_library_function();
return 0;

}

@antoninus.....
may be i am wrong but wont creating a pipe would be problematic.....


what i mean is say at the place where the library_function() is call
all there will be just writes to the pipe and no one will be reading
at that point as it is only a single process thats using the both ends
of the pipe...
so won't it be the case that the process writting to the pipe multiple
times will get blocked or there could be a chance that the maximum
size of the pipe buffer will get
over and create problem????

Mohan gupta

You can use O_NONBLOCK (or was that O_ASYNC?) to prevent the blocking.
Using pipes to pass errors inside the program is a pretty clumsy thing,
though; I would not recommend it.

- --
- --Falcon Darkstar Kirtaran
- --
- --OpenPGP: (7902:4457) 9282:A431

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIcBAEBAgAGBQJJdIvXAAoJEKmxP9YxEE4r1OQQAMi8I2uP02AK0O6+9+MZeAU4
2xp0BpWKFSxIc4WOi0Z7F5/ESo4iHOGwKQnhblP4NUr8zpQoMkgtlsdqyYmH9pF6
DNVI9kBLpKZSfcBHE0EjkVa4z5uG/X14x3L7cJSGYa+1T6gR36LSI0SHWkPI64Ti
auOK+0gSndGBYlt6uJ74XT5z16DzvC0iJBAla2vyUqLYwD6m9O5yXrBYi7rD0hCh
Prg/Mwc4/m1yaYvFdOWQYrlCZ6E2CT5u3nHxjgb9G+jEcQpT+FlKTRRlAcH3PXy7
l4GyfASEs1vD5gtg95cjbY4x59diEOCHgjk3Vw9SFkBp77NG3nqZT45UdLBIaxrK
KzAweuwTH1EkZ+PTnVIRGG+6gA8rO9jSRnr7aPESbuJpNodY+O6hFod6G6M9k6Yf
E8eaa8EnkxV3E71nmpCfunk2Lvyc6Fyyz6/6FoaRBt3g/OY3GEvNqI5vgpgUcL2U
FD6zyitGjekUjTrdR2WyJWGsn9IQljOtN1leSo24pLEOwXZsdAohiIQF06iOgKGk
4qo7bLujFbtDpHo1Gq6Hmz1PdGV6MYVzoKErcThC9rgBDzxJTEU3KouEYdRw7TSh
qt+d65Q0nd+qTtePOSlj+31RVM27XeVGo5SNMUQjswjVlvj/t/H0TaBCBcanulr4
G4O/iYKywqZVOhU8ULdD
=E1oA
-----END PGP SIGNATURE-----
 
B

Ben Pfaff

I don't know whether it's been asked *here*, but it's certainly a very
common problem. Writers of libraries should think twice before
writing error messages to a FILE, just as they should think twice
before using glibal variables. Error messages are part of a library's
interface.

But the question, as I saw it, was "how do I read from stderr?",
to which the answer is, "You don't."

I agree that the higher-level issue is fairly common, but that is
in my opinion not a C problem but a library design issue.
 
R

Richard Tobin

Ben Pfaff said:
But the question, as I saw it, was "how do I read from stderr?",
to which the answer is, "You don't."
I agree that the higher-level issue is fairly common, but that is
in my opinion not a C problem but a library design issue.

Well, it's because of a lack of a feature in C that libraries have
to address this issue. If there was a standard way to open a "file"
that was really memory, libraries could use output in the natural
way while still allowing callers to capture the message. And as
has been pointed out, it's a common extension.

-- Richard
 
B

Ben Pfaff

Well, it's because of a lack of a feature in C that libraries have
to address this issue. If there was a standard way to open a "file"
that was really memory, libraries could use output in the natural
way while still allowing callers to capture the message.

I suppose that could be useful, if the goal is just to capture a
formatted error message so that it can be sent somewhere other
than stderr. But that is not normally sufficient because,
usually, the library's client wants to know the details of what
went wrong so that it can decide how to handle the problem. For
that, a formatted error message is not a nice form to work from.
Instead, you want an error code or something else that is easy
for the client to work with, possibly coupled with an interface
to translate an error code into an error message.
And as has been pointed out, it's a common extension.

Sure.
 
C

CBFalconer

Ben said:
(e-mail address removed) (Richard Tobin) writes:
.... snip ...


But the question, as I saw it, was "how do I read from stderr?",
to which the answer is, "You don't."

I agree that the higher-level issue is fairly common, but that is
in my opinion not a C problem but a library design issue.

Actually, the file is a quite flexible means. It is up to the OS
what is actually done with the output to stderr, and some systems
have the ability to reassign that output (or a copy of it). Of
course the easiest thing is to first design your system in a manner
appropriate to its intended use.
 
C

CBFalconer

Richard said:
... and hope the library never calls fflush(stderr).

Why? fflush just empties the buffers. stderr is not buffered, so
those non-existent buffers are automatically empty.

See what you get for corresponding with trolls.
 
B

Ben Pfaff

CBFalconer said:
Why? fflush just empties the buffers. stderr is not buffered, so
those non-existent buffers are automatically empty.

stderr is not fully buffered. It may be line buffered.
 
R

Richard Tobin

... and hope the library never calls fflush(stderr).
[/QUOTE]
Why? fflush just empties the buffers. stderr is not buffered, so
those non-existent buffers are automatically empty.

Read the underlined text above.
See what you get for corresponding with trolls.

See what you get for, as usual, not reading the thread you are
replying to.

-- Richard
 
K

Kenny McCormack

Why? fflush just empties the buffers. stderr is not buffered, so
those non-existent buffers are automatically empty.

Read the underlined text above.
See what you get for corresponding with trolls.

See what you get for, as usual, not reading the thread you are
replying to.[/QUOTE]

More succinctly, this is what CBF gets for being completely retarded.
I assume his mother drank heavily (and probably did much worse things)
while he was inside.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,140
Latest member
SweetcalmCBDreview
Top