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