An assignment in my Operating Systems class requires me to build a binary process tree by recursively calling exec on the same program. The goal is to split some arbitrary task
As Jonathon Reinhart says you should change this lines:
char *argv2[] = {"some random arg to make sure that argc == 2 in the child", NULL};
execvp("two_way_pipes", argv2);
to:
char *argv2[] = {argv[0], "some random arg...", NULL};
execvp(argv[0], argv2);
then it works as expected:
echo test | ./two_way_pipes
in parent | message received: test
In your program you wrote "two_way_pipes" but it is not in your PATH so you really need the extra ./ so argv[0] then is ("./two_way_pipes").
Besides the issue mentioned by Jonathon Reinhart, most probably the call to execv()
fails.
To test this modify these lines
execvp("two_way_pipes", argv2);
_exit(0);
to be
...
#include <errno.h>
...
execvp("two_way_pipes", argv2); /* On sucess exec*() functions never return. */
perror("execvp() failed); /* Getting here means execvp() failed. */
_exit(errno);
Expect to receive
execvp() failed: No such file or directory
To fix this change
execvp("two_way_pipes", argv2);
to be
execvp("./two_way_pipes", argv2);
Also if the child was not exec*()
ed then this line
read(PARENT_READ, buff, 4); // should read "test" which was written by the child to stdout
fails and in turn buff
is not initialised and therefore this line
fprintf(stderr, "in parent | message received: %s\n", buff);
provokes undefined behaviour.
To fix this at least properly initialise buff
by changing
char buff[5];
to be
char buff[5] = "";
The first entry in your argv2
should be the name of the executable (just like your incoming argv[0]
.
char *argv2[] = {"two_way_pipes", "some random arg...", NULL};
execvp("two_way_pipes", argv2);
From the execvp man page:
The
execv()
,execvp()
, andexecvpe()
functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.