]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/xargs.c
resample: improve performance (thanks José Miguel Sánchez García)
[plan9front.git] / sys / src / cmd / xargs.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 void
6 usage(void)
7 {
8         fprint(2, "usage: xargs [ -n lines ] [ -p procs ] args ...\n");
9         exits("usage");
10 }
11
12 void
13 dowait(void)
14 {
15         while(waitpid() != -1)
16                 ;
17 }
18
19 void
20 main(int argc, char **argv)
21 {
22         int lines, procs, i, j, run;
23         char **nargv, **args, **p;
24         static Biobuf bp;
25         
26         lines = 10;
27         procs = 1;
28         ARGBEGIN {
29         case 'n': lines = atoi(EARGF(usage())); break;
30         case 'p': procs = atoi(EARGF(usage())); break;
31         default: usage();
32         } ARGEND;
33         if(argc < 1)
34                 usage();
35         
36         nargv = malloc(sizeof(char *) * (argc + lines + 1));
37         if(nargv == nil)
38                 sysfatal("malloc: %r");
39         memcpy(nargv, argv, sizeof(char *) * argc);
40         args = nargv + argc;
41         if(Binit(&bp, 0, OREAD) < 0)
42                 sysfatal("Binit: %r");
43         Blethal(&bp, nil);
44         atexit(dowait);
45         for(j = 0, run = 1; run; j++){
46                 if(j >= procs)
47                         waitpid();
48                 memset(args, 0, sizeof(char *) * (lines + 1));
49                 for(i = 0; i < lines; i++)
50                         if((args[i] = Brdstr(&bp, '\n', 1)) == nil){
51                                 if(i == 0)
52                                         exits(nil);
53                                 run = 0;
54                                 break;
55                         }
56                 switch(fork()){
57                 case -1:
58                         sysfatal("fork: %r");
59                 case 0:
60                         exec(*nargv, nargv);
61                         if(**nargv != '/' && strncmp(*nargv, "./", 2) != 0 &&
62                                         strncmp(*nargv, "../", 3) != 0){
63                                 *nargv = smprint("/bin/%s", *nargv);
64                                 exec(*nargv, nargv);
65                         }
66                         sysfatal("exec: %r");
67                 }
68                 for(p = args; *p; p++)
69                         free(*p);
70         }
71         exits(nil);
72 }