You had three problems:
From the manpage: The array
pipefd
is used to return two file descriptors referring to the ends of the pipe.pipefd[0]
refers to the read end of the pipe.pipefd[1]
refers to the write end of the pipe. You were usingpipefd[0]
to write andpipefd[1]
to read. That won't work. This was the root cause of theEBADF
(bad file descriptor) error. If you want bidirectionality, usesocketpair()
When you
fork()
, you need to close the file descriptors you don't need. That's the other end of the pipe.I believe you should
close()
an fd before youdup2
over it, though the man page is not explicit. In this caseclose()
the existingSTDOUT
before you usedup2()
.
Here is an amended version that works (minimal amendments made to get it working annotated with comments, there is more you could do to make it perfect):
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int
main ()
{
int pipe_ends[2];
if (pipe (pipe_ends))
{
printf ("Could not create pipe\n");
return -1;
}
pid_t pid = fork ();
if (pid < 0)
{
perror ("fork");
exit (1);
}
if (!pid)
{
close (1); /* close previous stdout */
/* dup write end of pipe */
dup2 (pipe_ends[1], 1);
/* close read end */
close (pipe_ends[0]);
char *args[3];
args[0] = "/bin/ls";
args[1] = "-l";
args[2] = NULL;
execv ("/bin/ls", args);
printf ("something went wrong\n");
}
close (pipe_ends[1]); /* close write end of pipe */
char buff[10240];
int count = read (pipe_ends[0], buff, 10240);
buff[count] = '\0';
printf ("here goes nothing......\n");
printf ("%s", buff);
return 0;
}
And the proof of the pudding:
amb@nimrod-ubuntu:~/so$ ./p
here goes nothing......
total 32
-rwxrwxr-x 1 amb amb 8889 Jan 19 09:19 p
-rw-rw-r-- 1 amb amb 853 Jan 19 09:19 p.c
-rwxrwxr-x 1 amb amb 8456 Jan 18 20:47 test
-rw-rw-r-- 1 amb amb 243 Jan 18 20:47 test.c