An example of using pipe and fork in C
This is an example C program which illustrates use of the pipe
and vfork
system calls to run an external command.
#include <stdio.h> #include <errno.h> /* For strerrno. */ #include <string.h> #include <sys/wait.h> #include <fcntl.h> /* For "pipe". */ #include <unistd.h> /* For "exit". */ #include <stdlib.h> /* 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; }
The output of the example looks like this:
total 88 -rw-r--r-- 1 ben ben 500 Dec 18 12:58 index.html -rw-r--r-- 1 ben ben 332 Dec 18 13:08 links-table -rw-r--r-- 1 ben ben 134 Dec 18 12:55 makefile -rwxr-xr-x 1 ben ben 11612 Dec 18 13:08 pfc -rw-r--r-- 1 ben ben 1948 Dec 18 12:54 pfc.c -rw-r--r-- 1 ben ben 0 Dec 18 13:08 pfc.txt -rw-r--r-- 1 ben ben 8912 Dec 18 13:08 pfc_c.html -rw-r--r-- 1 ben ben 55 Dec 18 11:42 tags
Acknowledgements
I wrote the above example looking at the code of W. Richard Stevens' book "Advanced Programming in the Unix Environment" and then modified it by comparing it to the FreeBSD popen source code.
Web links
-
FreeBSD popen
This is the exact version of the FreeBSD source code I referred to. I wanted to write a replacement for popen with better error messages due to a failure in a system I am working on.
Copyright © Ben Bullock 2009-2024. All
rights reserved.
For comments, questions, and corrections, please email
Ben Bullock
(benkasminbullock@gmail.com).
/
Privacy /
Disclaimer