Re: wayward system() call errors
- From: Barry Margolin <barmar@xxxxxxxxxxxx>
- Date: Mon, 19 Mar 2007 21:07:30 -0400
In article <1174340649.985470.171540@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>,
thosjohnson@xxxxxxxxxxxxx wrote:
(Long post):
Hi -
1. I have a question regarding the C "system" call in a UNIX
environment. My question arises from a problem I discovered using HP-
UX 11.0.
The problem: In an existing application, I added a function to write
a transaction log to a new, separate file. During testing I sometimes
saw some extraneous messages in this new output file. Here's what I
believe was causing them:
2. The program (which I "inherited" as existing code) logs certain
errors to a file by making system calls. The essence of what happens
in the error logger is:
void log_err( char * errorMessage)
{
char buffer[256];
char * log_dir, * log_file;
...
sprintf(buffer,"echo %s >> %s/%s", errorMessage, log_dir, log_file);
system(buffer);
}
So, if errorMessage points to "Error xyz"
log_dir points to "/prod/foo/logs"
and log_file points to "bar
then the message "Error xyz" gets appended to file /prod/foo/logs/bar.
And this seems to work OK. (The question of whether this is a
sensible way to write to the log file is beyond the scope of this
post).
3. But suppose errorMessage points to "before \n after" when the
sprintf and system calls (above) are made. The system call gets the
string "echo before \n after >> /prod/foo/logs/bar"
What I believe happens is that "before" gets echoed to stdout
and then the shell tries to do "after >> /prod/foo/logs/bar" as
a separate shell command.....
But since 'after' is not a valid command, the shell attempts to write
an error message to stderr. Somehow, the error message from the shell
gets written to my new transaction log file mentioned in paragraph 1.
I'm not making any explicit association between the transaction log
file and stderr. The
transaction log is intended to be known only to one function
that is essentially:
Is it possible that something is CLOSING stderr before the first time
you call log_trans()? When a file is opened it gets the lowest
available descriptor, so of stderr is closed then the next open() will
cause stderr to be associated with that file.
If you close any of the standard 3 file descriptors, it's generally best
to connect them to /dev/null to avoid accidents like this.
void log_trans( char * some_message)
{
static FILE * trans_log = 0;
...
if (trans_log == (FILE *)0)
{
trans_log = fopen("my_log_file", "a");
}
...
fprintf(trans_log, "%s", some_message);
fflush(trans_log);
...
}
The file "my_log_file" and its associated FILE object are not supposed
to be used by anything other than function log_trans (code immediately
above). What I'm trying to understand is how the system function
error messages are getting written to my
transaction log. I'm guessing that UNIX is looking for any open file
handle that it can find and writing its error messages there (rather
than simply discarding them).
BTW, I have fixed the problem by removing all newline characters from
the strings being passed to the log_err function. The fix seems to
work. What's more, I can make the bug come back simply by adding the
statement
system((char *)">> This is an intentional error.");
to the original log_err function. Still puzzling, because function
log_err knows nothing about "my_log_file" or its associated FILE
object.
Thanks for any info you all can provide. I'm also curious if anyone
has encountered this sort of thing on any other versions of UNIX.
TKJ
--
Barry Margolin, barmar@xxxxxxxxxxxx
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
.
- References:
- wayward system() call errors
- From: thosjohnson
- wayward system() call errors
- Prev by Date: Re: multiple tcp server and client execution with close problem
- Next by Date: Re: Unix Programmer's Manual
- Previous by thread: wayward system() call errors
- Next by thread: Re: wayward system() call errors
- Index(es):
Relevant Pages
|