#include #include #include #include #include extern char ** environ; void errexit (const char * message) { perror (message); _exit (1); } void dupclose (int in, int out) { if (out != -1 && (dup2 (in, out) == -1)) errexit ("dup2()"); if (close (in)) errexit ("close()"); } void myfork (char * program, int * in, int * out) { char * args [255]; int i; for (i=0; (args[i] = strtok (i ? NULL : program, " ")); i++) ; switch (fork ()) { case -1: errexit ("fork()"); case 0: /* child */ if (in) dupclose (in[0], 0); if (out) dupclose (out[1], 1); execve (args[0], args, environ); /* never returns (unless...) */ fprintf (stderr, "can't execve %s\n", program); errexit ("execve()"); default: /* parent */ if (in) dupclose (in[0], -1); if (out) dupclose (out[1], -1); } free (args[0]); } int main (int argc, char ** argv) { FILE * file; int fdin[2], fdout[2]; char line[255]; int count, cmdcount = 0; char * commands [256]; if (argc != 2) { fprintf (stderr, "need one argument: file containing commands to chain\n"); return 1; } if (!(file = fopen (argv[1], "r"))) errexit("fopen()"); while (fgets (line, sizeof(line), file)) { line[strlen(line)-1] = 0; // remove cariage return if (line[0]) commands[cmdcount++] = strdup (line); } for (count = 0; count < cmdcount; count++) { if (pipe (fdout)) errexit ("pipe()"); myfork (commands[count], count ? fdin : (int *) NULL, count < (cmdcount-1) ? fdout : (int *) NULL); memcpy (fdin, fdout, sizeof(fdout)); } return 0; }