/* * Run n commands in parallel. * * $Id: by.c,v 1.5 2016/04/15 04:31:26 grog Exp $ * * Usage: by [] * * Read args from stdin, prepend ] if present, and run n processes in * parallel until done. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef ARG_MAX /* Linux, for example */ #define ARG_MAX 131072 /* maximum arglist length */ #endif #define BUFSIZE ARG_MAX /* maximum command length */ #define MAXPARALLEL 100 /* maximum number of parallel tasks */ char prepend [BUFSIZE]; /* command to prepend */ char buf [BUFSIZE]; /* buffer to hand to system () */ int eof = 0; /* set when we have processed all input */ int verbose = 0; /* XXX make this an option */ int active = 0; /* number of currently active processes */ int proccount = 0; /* sequential count of processes */ void usage (char *name) { fprintf (stderr, "Usage:\n" "%s [-v] count [commands]\n", name ); exit (1); } /* * Read in a command line and fire it off. */ void fireoff () { pid_t pid; eof = (fgets (buf, ARG_MAX, stdin) == NULL); if (! eof) { proccount++; /* next process */ active++; /* one more active */ if (verbose) fprintf (stderr, "fireoff: launching process %d (%d now active):\n%s %s\n", proccount, active, prepend, buf ); switch (pid = fork ()) { case -1: /* error */ perror ("Can't fork"); exit (1); case 0: /* child */ { char command [BUFSIZE]; if (prepend [0]) /* we have something to prepend */ { sprintf (command, "%s %s", prepend, buf); exit (system (command)); } else exit (system (buf)); /* NOTREACHED */ } } } } int main (int argc, char *argv []) { int count; /* number to start */ int status; /* wait status */ pid_t pid; int i; i = 1; /* parameter count */ if (argc < 2) /* no first parameter */ usage (argv [0]); if (strcmp (argv [i], "-v") == 0) { verbose = 1; if (argc < 2) /* no first parameter */ usage (argv [0]); i = 2; } count = atoi (argv [i]); if ((count < 1) || (count > MAXPARALLEL)) usage (argv [0]); /* Build up the command to prepend. */ while (++i < argc) sprintf (&prepend [strlen (prepend)], "%s ", argv [i]); while ((active < count) && (! eof)) { if (! eof) fireoff (); } while (active) { pid = wait (&status); active--; if (verbose) fprintf (stderr, "reaping pid %d (%d still active)\n", pid, active ); if (status != 0) fprintf (stderr, "Process %d exited with status %x\n", pid, status); if (! eof) fireoff (); else if (verbose) fprintf (stderr, "(no more commands)\n"); } return 0; }