All pastes #945152 Raw Edit

I BLAME KARJALA

public c v1 · immutable
·published 2008-03-16 18:55 UTC
rendered paste body
#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/types.h>#include <sys/wait.h>extern char ** environ;/* Errexit prints the supplied error message via perror, then exits the program, returning 1. */void errexit (const char * message) {  perror (message);  fprintf (stderr, "I BLAME KARJALA FOR THIS!\n");  _exit (1);}/* Dupclose duplicates the fd "in" to "out" if "out" is different from -1,   and closes "in" afterwards. If "out" is -1, "in" is just closed. */void dupclose (int in, int out) {   if (out != -1 && (dup2 (in, out) ==  -1))    errexit ("dup2()");  if (close (in))     errexit ("close()");}/* Myfork parses the command line, forks the process, performs stdin/stdout redirection and   closes unneccessary FDs. */pid_t myfork (char * program, int * in, int * out) {  char * args [256];  int i;  pid_t childpid;  /* Tokenize command line */  for (i=0; i < 256 && (args[i] = strtok (i ? NULL : program, " ")); i++) ;    /* Fork */  switch (childpid = fork ()) {  case -1:    errexit ("fork()");    /* child: duplicate & close FDs, exec program */  case 0:     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()");    /* parent: just close FDs */  default:     if (in) dupclose (in[0], -1);    if (out) dupclose (out[1], -1);  }  return childpid;}int main (int argc, char ** argv) {  FILE * file;  int fdin[2], fdout[2];  char line[255], * commands [256];  pid_t pids [256];  int retvals [256];  int count, cmdcount = 0;  if (argc != 2) {    fprintf (stderr, "need one argument: file containing commands to chain\n");    return 1;  }  if (!(file = fopen (argv[1], "r")))    errexit("fopen()");  /* Read commands */  while (cmdcount < 256 && fgets (line, sizeof(line), file)) {    line[strlen(line)-1] = 0; // remove cariage return    if (line[0])      commands[cmdcount++] = strdup (line);  }  /* Execute commands, piped into each other */  for (count = 0; count < cmdcount; count++) {    if (count < (cmdcount-1) && pipe (fdout))              /* No new output pipe for last command */      errexit ("pipe()");    pids[count] = myfork (commands[count], 			  count ? fdin : (int *) NULL,     /* First command will only have stdout redirected */			  count < (cmdcount-1) ? fdout : (int *) NULL); /* Last command will only have stdin redirected */    memcpy (fdin, fdout, sizeof(fdout));                   /* Current output pipe will be next command's input pipe */  }  /* Wait for commands to terminate, in order */  for (count = 0; count < cmdcount; count++)    waitpid (pids [count], &retvals[count], 0);  /* Print return values */  for (count = 0; count < cmdcount; count++)    printf ("Process %d (%s) exited with status %d\n", count, commands[count], WEXITSTATUS(retvals [count]));  return 0;}