#include #include #include #include #include extern char ** environ; void dupclose (int closeonly, int in, int out) { if (!closeonly && (dup2 (in, out) == -1)) { perror ("dup2()"); _exit (1); } if (close (in)) { perror ("close()"); _exit (1); } } int 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: perror ("fork()"); return -1; case 0: /* child */ if (in) dupclose (0, in[0], 0); if (out) dupclose (0, out[1], 1); execve (args[0], args, environ); /* never returns (unless...) */ fprintf (stderr, "can't execve %s\n", program); perror ("execl()"); _exit (1); default: /* parent */ if (in) dupclose (1, in[0], -1); if (out) dupclose (1, out[1], -1); } free (args[0]); return 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"))) { printf ("fopen()"); return 1; } 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)) { perror ("pipe()"); return 1; } if (myfork (commands[count], count ? fdin : (int *) NULL, count < (cmdcount-1) ? fdout : (int *) NULL) == -1) return 1; memcpy (fdin, fdout, sizeof(fdout)); } return 0; }