I fork and set up a command like this:
pid_t pid;
pid = fork();
if (pid == 0)
{ // I am the child
freopen("/input_pipe","r",stdin);
freopen("/output_pip","w",stdout);
execl("/bin/sh", "sh", "-c", command, (char *)NULL); // using execv is probably faster
// Should never get here
perror("execl");
exit(1);
}
The /input_pipe has been created and filled with data before the processs is forked.
This works in almost all cases absolutely fine. The command reads (with read()
) from its stdin and gets the data that was written to the pipe by another process.
But sometimes the command cannot read from its stdin stream and gets the "Bad file descriptor" error when trying to do so.
What could cause this error?
Edit: I have changed the freopen parts to this:
pipe_in = open(pipename_in, O_RDONLY);
pipe_out = open(pipename_out, O_WRONLY);
dup2(pipe_in, 0);
dup2(pipe_out, 1);
I will test this for a couple of days though as the error was only appearing very seldom.
One possible source of issues is that "stdin" an "stdout" don't correspond necessarily with file descriptors 0 and 1 respectively. In many implementations of the runtime library freopen
may change the file descriptor belonging to the FILE*. File descriptors belong to the kernel, while FILEs belong to the runtime library, and they are not necessarily aligned.
Please have a look here:
http://man7.org/linux/man-pages/man3/stdout.3.html
"Applying freopen(3) to one of these streams can change the file descriptor number associated with the stream"
After execl, child process only expects that file descriptor 0 and 1 are standard input and output, but it may happen that freopen closed fd 0 and connected onother fd to (FILE*)stdin. I recommend you to use the "open", "close", "dup" etc... system call and deal with file descriptors 0 an 1 directly (or, better, the standard macros STDIN_FILENO and STDOUT_FILENO).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With