ref: 9f9fa320571a4e2cb5514d4ec064bb1e904a94a3
parent: 67aceaa6d7355b1e0bf2a3b94556986f3602bcce
author: aiju <aiju@phicode.de>
date: Sat Aug 27 07:19:54 EDT 2011
rewrote xargs in C; implemented parallelization
--- a/rc/bin/xargs
+++ /dev/null
@@ -1,23 +1,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
--- /dev/null
+++ b/sys/src/cmd/xargs.c
@@ -1,0 +1,72 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+
+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);
+}
--
⑨