All pastes #945051 Raw Edit

I BLAME KARJALA

public text v1 · immutable
·published 2008-03-16 17:34 UTC
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;
}