#include #include /* For strerrno. */ #include #include #include /* For "pipe". */ #include /* For "exit". */ #include /* Close a file descriptor, and exit if there was an error. */ static void close_or_die (int fd) { int status; status = close (fd); if (status != 0) { fprintf (stderr, "close %d failed: %s\n", fd, strerror (errno)); exit (EXIT_FAILURE); } } /* Run the command and print it to the pipe's write descriptor "outfd". */ static void run_command (int outfd) { int status; char * command; char * argv[4] = { "sh", "-c", 0, 0, }; if (outfd != STDOUT_FILENO) { status = dup2 (outfd, STDOUT_FILENO); if (status == -1) { fprintf (stderr, "dup2 %d failed: %s\n", outfd, strerror (errno)); exit (EXIT_FAILURE); } } close_or_die (outfd); command = "ls -l"; argv[2] = command; execve ("/bin/sh", argv, 0); fprintf (stderr, "execve %s returned.\n", command); exit (EXIT_FAILURE); } #define SIZE 0x100 static void read_print_pipe (FILE * p) { char buf[SIZE]; while (! feof (p)) { int bytes; bytes = fread (buf, sizeof (char), SIZE, p); printf ("%.*s", bytes, buf); } } int main () { pid_t pid; int status; int pfd[2]; FILE * p; status = pipe (pfd); if (status != 0) { fprintf (stderr, "Error with pipe: %s\n", strerror (errno)); exit (EXIT_FAILURE); } pid = vfork (); if (pid < 0) { fprintf (stderr, "Error with fork: %s\n", strerror (errno)); exit (EXIT_FAILURE); } if (pid == 0) { close_or_die (pfd[0]); run_command (pfd[1]); exit (EXIT_SUCCESS); } close_or_die (pfd[1]); p = fdopen (pfd[0], "r"); read_print_pipe (p); fclose (p); wait4 (pid, & status, 0, 0); if (status != 0) { fprintf (stderr, "Bad status %d from child.\n", status); exit (EXIT_FAILURE); } return 0; }