By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,654 Members | 1,816 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,654 IT Pros & Developers. It's quick & easy.

Redirecting perror

P: n/a
Hello all,
I have some error checking using the function 'perror', which writes
messages on stderr. I'd like to send all error messages to a file instead.
Is there some way to do this, short of replacing all the perror calls with a
custom function ?
--
Guillaume Dargaud
http://www.gdargaud.net/
Aug 7 '07 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Guillaume Dargaud wrote:
Hello all,
I have some error checking using the function 'perror', which writes
messages on stderr. I'd like to send all error messages to a file instead.
Is there some way to do this, short of replacing all the perror calls with a
custom function ?
reopen stderr to point to a file
Aug 7 '07 #2

P: n/a
"Guillaume Dargaud" <us*****************************@www.gdargaud.ne t>
writes:
Hello all,
I have some error checking using the function 'perror', which writes
messages on stderr. I'd like to send all error messages to a file instead.
Is there some way to do this, short of replacing all the perror calls with a
custom function ?
strerror is standard:

#include <string.h>
char *strerror(int errnum);

The strerror function maps the number in errnum to a message
string. Typically, the values for errnum come from errno, but
strerror shall map any value of type int to a message.

Returns: The strerror function returns a pointer to the string,
the contents of which are locale- specific. The array pointed to
shall not be modified by the program, but may be overwritten by a
subsequent call to the strerror function.

--
Ben.
Aug 7 '07 #3

P: n/a
On Aug 7, 7:32 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
"Guillaume Dargaud" <use_the_form_on_my_contact_p...@www.gdargaud.ne t>
writes:
Hello all,
I have some error checking using the function 'perror', which writes
messages on stderr. I'd like to send all error messages to a file instead.
Is there some way to do this, short of replacing all the perror calls with a
custom function ?

strerror is standard:

#include <string.h>
char *strerror(int errnum);

The strerror function maps the number in errnum to a message
string. Typically, the values for errnum come from errno, but
strerror shall map any value of type int to a message.

Returns: The strerror function returns a pointer to the string,
the contents of which are locale- specific. The array pointed to
shall not be modified by the program, but may be overwritten by a
subsequent call to the strerror function.

--
Ben.


just close(stderr)
and try to open a file immediately .......

Aug 7 '07 #4

P: n/a
alex wrote:
just close(stderr)
and try to open a file immediately .......
We all know that close() is not a standard C function, so
we cannot tell whether this advice is correct for the
OP's environment.

<OT>
Just out of curiosity: which extension are *you* using,
where close() accepts an argument of type FILE*?
</OT>

Ralf
Aug 7 '07 #5

P: n/a
alex wrote:
>>"Guillaume Dargaud" <use_the_form_on_my_contact_p...@www.gdargaud.ne t>
writes:

>>>Hello all,
I have some error checking using the function 'perror', which writes
messages on stderr. I'd like to send all error messages to a file instead.
Is there some way to do this, short of replacing all the perror calls with a
custom function ?
....
>
just close(stderr)
and try to open a file immediately .......
By no means guaranteed.

Ben's solution is the right one but doesn't mean Guillaume's requirement
not to replace all the perror calls.

Jacob got it right, IMHO - use freopen. Indeed the spec describes this
as the primary use for freopen. Naturally, all output written to stderr
will now go to this file.

The alternative, if only perror() is to be affected, is some fun with a
function and a macro, something like this (untested) :-

#include <errno.h>
#include <stdio.h>
static FILE *errorstream; /* opened somewhere */
void my_perror(char *string) {
char *buffer;
char *errtxt = strerror(errno);
int buflen = strlen(errtxt) + strlen(string) + 4;
buffer = malloc(buflen);
if (buffer == NULL) {
/* Your choice! */
}
sprintf(buffer,"%s: %s\n",string,errtxt);
fputs(buffer,errorstream);
free(buffer);
}

#define perror(x) my_perror(x)
....
Aug 7 '07 #6

P: n/a
Mark Bluemel <ma**********@pobox.comwrites:
alex wrote:
>>>"Guillaume Dargaud" <use_the_form_on_my_contact_p...@www.gdargaud.ne t>
writes:
Hello all,
I have some error checking using the function 'perror', which writes
messages on stderr. I'd like to send all error messages to a file instead.
Is there some way to do this, short of replacing all the perror calls with a
custom function ?
...
>>
just close(stderr)
and try to open a file immediately .......

By no means guaranteed.

Ben's solution is the right one but doesn't mean Guillaume's
requirement not to replace all the perror calls.
Perfectly true. I just (deliberately) ignored that part! It is rare
that one should pass up an opportunity to make ones code more
flexible, so while the reopen path is fast, it sends everything to the
file (which may, one day, be the wrong thing to do) and it passes up a
chance to make the error reporting more flexible (e.g. one might need
it to more configurable one day).

Of course, if the perror calls are not available (because the OP does
not have the source), then Jacob's solution is pretty much the ony way
to go.
Jacob got it right, IMHO - use freopen. Indeed the spec describes this
as the primary use for freopen. Naturally, all output written to
stderr will now go to this file.
If sending all stderr out to a file is OK, that is indeed the way to go.

--
Ben.
Aug 7 '07 #7

P: n/a
On Tue, 07 Aug 2007 17:06:27 +0100, Mark Bluemel wrote:
alex wrote:
>>>"Guillaume Dargaud" <use_the_form_on_my_contact_p...@www.gdargaud.ne t>
writes:
Hello all,
I have some error checking using the function 'perror', which writes
messages on stderr. I'd like to send all error messages to a file instead.
Is there some way to do this, short of replacing all the perror calls with a
custom function ?
...
>>
just close(stderr)
and try to open a file immediately .......

By no means guaranteed.

Ben's solution is the right one but doesn't mean Guillaume's requirement
not to replace all the perror calls.

Jacob got it right, IMHO - use freopen. Indeed the spec describes this
as the primary use for freopen. Naturally, all output written to stderr
will now go to this file.

The alternative, if only perror() is to be affected, is some fun with a
function and a macro, something like this (untested) :-

#include <errno.h>
#include <stdio.h>
static FILE *errorstream; /* opened somewhere */
void my_perror(char *string) {
char *buffer;
char *errtxt = strerror(errno);
int buflen = strlen(errtxt) + strlen(string) + 4;
buffer = malloc(buflen);
if (buffer == NULL) {
/* Your choice! */
}
sprintf(buffer,"%s: %s\n",string,errtxt);
Why not doing a fprintf on errorstream, so eliminating the need
for a malloc()ated buffer?
fputs(buffer,errorstream);
free(buffer);
}

#define perror(x) my_perror(x)
#define perror(x) ( fprintf(errorstream, "%s: %s\n", (x), \
strerror(errno)), fflush(errorstream) )
This doesn't handle the case in which x == NULL || *x == '\0', in
which the "real" perror() simply writes strerror(errno) and a
newline. But neither does your function...

--
Army1987 (Replace "NOSPAM" with "email")
"Never attribute to malice that which can be adequately explained
by stupidity." -- R. J. Hanlon (?)

Aug 7 '07 #8

P: n/a
just close(stderr)
and try to open a file immediately .......
I didn't know you could do that... Seems like a good solution for me. Thanks
for all who contributed, I'd thought of the macro solution but it's not so
elegant as I also have custom error messages such as fprintf(stderr, ...)
which I want redirected along perror.
--
Guillaume Dargaud
http://www.gdargaud.net/Antarctica/
Aug 8 '07 #9

P: n/a
"Guillaume Dargaud" <us*****************************@www.gdargaud.ne t>
writes:
>just close(stderr)
and try to open a file immediately .......

I didn't know you could do that...
You can't! If re-directing all error output to the file is what you
want, ignore my (previous) answer and follow Jacob Navia's.
Seems like a good solution for me.
close is not a standard C function, and relying on what happens
"immediately" after a close is highly suspect. freopen is the way to go.

--
Ben.
Aug 8 '07 #10

P: n/a
"Guillaume Dargaud" <us*****************************@www.gdargaud.netw rites:
>just close(stderr)
and try to open a file immediately .......

I didn't know you could do that...
[...]

And you were right. Even assuming it's 'fclose(stderr)' rather than
'close(stderr)', there's no guarantee that a newly opened file will
have any relationship to the one you just closed. Any attempt to
write to stderr after you've closed it (unless you've opened it again)
will invoke undefined behavior. The worst case is that it will do
exactly what you want it to do, failing only at the most inconvenient
possible moment (either during an important demo, or after you've
ported the code to another implementation and forgotten what you did).

See freopen() if you want all writes to stderr to go somewhere else
(<OT>or redirect stderr when you invoke the program</OT>), or use a
macro or some other replacement for perror() if you want only perror
calls to be affected.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 8 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.