rendered paste body#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
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;
}