I am writting a C program formed by a parent and his child (using fork). They comunicate through a pipe. Parent writes into the pipe through the standard output and child reads from the pipe through the standard input. Once they are connected, parent writes "hello world" into the pipe, and son calls exec. My code looks like this:
int main(int argc, char *argv[])
{
int p, a;
char buf[1024];
FILE *file;
size_t nread;
int fd[2];
char argument[PATH_MAX];
if(pipe(fd)<0){
return 1;
}
p = fork();
switch(p){
case -1: perror("Error en el fork()"); return 1;
case 0:
close(fd[1]);
close (0);
dup(fd[0]);
close(fd[0]);
sprintf(argument,"/usr/bin/%s",argv[1]);
execvp(argument,argv);
perror("Error en el execv");
exit(1);
default: break;
}
close(fd[0]);
close(1);
a = dup(fd[1]);
close(fd[1]);
write(1,"Hello World\n",12);
close(a);
wait(NULL);
return 0;
}
exec function executed by the son calls functions rev or wc. If called without arguments, rev and wc should be applied to the standard input ("hello world" in my case). But this is not working and I don't know why. Any help would be really appreciated.
this is not working and I don't know why
Because you are using
dup()
. To redirect the standard input of the child process to the pipe, the correct system call to use isdup2()
Note that you don't need the
dup()
call at all in the parent code branch. Just write to the write-end of the pipe:However, if you want to use execvp in the parent branch also, to launch another program with its standard output redirected, then you would have to use
dup2()
here also:Read the manpage for
dup2
for details.Also, another problem with your code is the use of execvp with
argv
as the argument list. This will cause programs likerev
andwc
to receive the entire command line of the parent program and thus find an argument to process rather than read from standard input. You probably wantYou are using
execvp()
wrongly in the following code:If you run your program by
./a.out wc
, then in this case the arguments to/usr/bin/wc
would be./a.out wc
, i.e. the original argument list to./a.out
, then/usr/bin/wc
will try to open a file namedwc
in current working directory instead of reading from standard input.So change the above code to
should fix the problem, this time the argument list to
/usr/bin/wc
will be a empty list.