All pastes #945034 Raw Edit

I BLAME KARJALA

public text v1 · immutable
·published 2008-03-16 17:24 UTC
rendered paste body
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

extern char ** environ;

void dupclose (int in, int out) {
  if (out != -1 && (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 (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);
    perror ("execl()");
    _exit (1);
  default: /* parent */
    if (in) dupclose (in[0], -1);
    if (out) dupclose (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;
}