问题
I wrote the following code in order to use pipes in c unix:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
int main ()
{
int fds[2];
pid_t pid;
/* Create a pipe. File descriptors for the two ends of the pipe are
placed in fds. */
pipe (fds);
/* Fork a child process. */
pid = fork ();
if (pid == (pid_t) 0) {
//char abc[10]; - **Uncommenting this cause the program not to work.**
/* This is the child process. Close our copy of the write end of
the file descriptor. */
close (fds[1]);
// Read params
FILE * stream;
stream = fdopen (fds[0], "r");
char* args[4]={"avg3.out","4","3","5"};
/* Replace the child process with the “avg3” program. */
execv("avg3.out", args);
} else {
/* This is the parent process. */
FILE* stream;
/* Close our copy of the read end of the file descriptor. */
close (fds[0]);
/* Convert the write file descriptor to a FILE object, and write
to it. */
dup2(fds[0], STDOUT_FILENO);
stream = fdopen (fds[1], "w");
fprintf (stream, "5 4 3");
fflush (stream);
close (fds[1]);
/* Wait for the child process to finish. */
waitpid (pid, NULL, 0);
}
return 0;
}
avg3.out is a file I compiled before. It simply calculate the average of the 3 params sent to it.
The output was 4, but when I tried to actually read from the stream, I added a declaration for char buffer[10]
The code stopped working. That is, no output provided. I tried to rename it, to move the decleration to the start of the if statement. but nothing worked.
So, why does the program stop working when adding just an array declaration?
回答1:
The parameter-array to go with calls to exec*()
needs to be (char*)NULL
-terminated.
This line
char* args[4]={"avg3.out","4","3","5"};
should be
char* args[] = {"avg3.out", "4", "3", "5", NULL};
As it isn't in your code, exec()
might get lost searching for it.
By bad luck the stack might have been clean (0
filled) for the version of your code not declaring a
and execv()
found a NULL
right after the pointer pointing to "5"
. Having a
created on the stack then changed the content of the stack which made execv()
getting lost searching for the NULL
.
Additionally its worth mentioning that the OP's code misses error checking on most of the relevant system call.
Having done so together with a detailed examation of the errors' causes, probably by using calls to perror()
might have led to solving this issue by providing relevant information.
In particular placing it after the call to execv()
it soon would have been obvious what's wrong:
execv("avg3.out", args);
perror("execv() failed");
来源:https://stackoverflow.com/questions/20220825/declaring-char-array-causes-execv-to-not-work