From 1ba43dd3696e76fefc2efbf2500ebd0594502887 Mon Sep 17 00:00:00 2001 From: aiju Date: Sat, 27 Aug 2011 11:19:54 +0200 Subject: [PATCH] rewrote xargs in C; implemented parallelization --- rc/bin/xargs | 23 --------------- sys/src/cmd/xargs.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 23 deletions(-) delete mode 100755 rc/bin/xargs create mode 100644 sys/src/cmd/xargs.c diff --git a/rc/bin/xargs b/rc/bin/xargs deleted file mode 100755 index 4255b3440..000000000 --- a/rc/bin/xargs +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/rc -fn usage { - echo usage: $0 [-n num] program [arguments] - exit usage -} -rfork e -ifs=' -' -nargs=1 -while(~ $1 -*) { - switch($1) { - case -n - nargs=$2 - shift 2 - case * - echo bla - usage - } -} -while(x = `{read -n $nargs}) - $* $x -if(! ~ $#x 0) - $* $x diff --git a/sys/src/cmd/xargs.c b/sys/src/cmd/xargs.c new file mode 100644 index 000000000..6c9c19274 --- /dev/null +++ b/sys/src/cmd/xargs.c @@ -0,0 +1,72 @@ +#include +#include +#include + +void +usage(void) +{ + fprint(2, "usage: xargs [ -n lines ] [ -p procs ] args ...\n"); + exits("usage"); +} + +void +dowait(void) +{ + while(waitpid() != -1) + ; +} + +void +main(int argc, char **argv) +{ + int lines, procs, i, j, run; + char **nargv, **args, **p; + static Biobuf bp; + + lines = 10; + procs = 1; + ARGBEGIN { + case 'n': lines = atoi(EARGF(usage())); break; + case 'p': procs = atoi(EARGF(usage())); break; + default: usage(); + } ARGEND; + if(argc < 1) + usage(); + + nargv = malloc(sizeof(char *) * (argc + lines + 1)); + if(nargv == nil) + sysfatal("malloc: %r"); + memcpy(nargv, argv, sizeof(char *) * argc); + args = nargv + argc; + if(Binit(&bp, 0, OREAD) < 0) + sysfatal("Binit: %r"); + Blethal(&bp, nil); + atexit(dowait); + for(j = 0, run = 1; run; j++){ + if(j >= procs) + waitpid(); + memset(args, 0, sizeof(char *) * (lines + 1)); + for(i = 0; i < lines; i++) + if((args[i] = Brdstr(&bp, '\n', 1)) == nil){ + if(i == 0) + exits(nil); + run = 0; + break; + } + switch(fork()){ + case -1: + sysfatal("fork: %r"); + case 0: + exec(*nargv, nargv); + if(**nargv != '/' && strncmp(*nargv, "./", 2) != 0 && + strncmp(*nargv, "../", 3) != 0){ + *nargv = smprint("/bin/%s", *nargv); + exec(*nargv, nargv); + } + sysfatal("exec: %r"); + } + for(p = args; *p; p++) + free(*p); + } + exits(nil); +}