xargs-P.patch

axel, 01/05/2011 10:12 PM

Download (4.2 KB)

View differences:

usr.bin/xargs/xargs.1
58 58
.Fl n Ar number
59 59
.Op Fl x
60 60
.Oc
61
.Op Fl P Ar maxjobs
61 62
.Op Fl s Ar size
62 63
.Op Ar utility Op Ar argument ...
63 64
.Sh DESCRIPTION
......
192 193
The current default value for
193 194
.Ar number
194 195
is 5000.
196
.It Fl P Ar maxprocs
197
Parallel mode: run at most
198
.Ar maxprocs
199
invocations of
200
.Ar utility
201
at once.
195 202
.It Fl o
196 203
Reopen stdin as
197 204
.Pa /dev/tty
......
285 292
.St -p1003.2
286 293
compliant.
287 294
The
288
.Fl J , o
295
.Fl J , o , P
289 296
and
290 297
.Fl R
291 298
options are non-standard
usr.bin/xargs/xargs.c
66 66
static void	run(char **);
67 67
static void	usage(void);
68 68
void		strnsubst(char **, const char *, const char *, size_t);
69
static void	waitchildren(const char *, int);
69 70

  
70 71
static char echo[] = _PATH_ECHO;
71 72
static char **av, **bxp, **ep, **expx, **xp;
......
73 74
static const char *eofstr;
74 75
static int count, insingle, indouble, oflag, pflag, tflag, Rflag, rval, zflag;
75 76
static int cnt, Iflag, jfound, Lflag, wasquoted, xflag;
77
static int curprocs, maxprocs;
78
static volatile int childerr;
76 79

  
77 80
extern char **environ;
78 81

  
......
112 115
		/* 1 byte for each '\0' */
113 116
		nline -= strlen(*ep++) + 1 + sizeof(*ep);
114 117
	}
115
	while ((ch = getopt(argc, argv, "0E:I:J:L:n:opR:s:tx")) != -1)
118

  
119
	maxprocs = 1;
120
	while ((ch = getopt(argc, argv, "0E:I:J:L:n:P:opR:s:tx")) != -1)
116 121
		switch(ch) {
117 122
		case 'E':
118 123
			eofstr = optarg;
......
144 149
		case 'p':
145 150
			pflag = 1;
146 151
			break;
152
		case 'P':
153
			if ((maxprocs = atoi(optarg)) <= 0)
154
				errx(1, "max.processes must be >0");
155
			break;
147 156
		case 'R':
148 157
			if ((Rflag = atoi(optarg)) <= 0)
149 158
				errx(1, "illegal number of replacements");
......
245 254
	switch(ch = getchar()) {
246 255
	case EOF:
247 256
		/* No arguments since last exec. */
248
		if (p == bbp)
257
		if (p == bbp) {
258
			waitchildren(*argv, 1);
249 259
			exit(rval);
260
		}
250 261
		goto arg1;
251 262
	case ' ':
252 263
	case '\t':
......
323 334
					*xp++ = *avj;
324 335
			}
325 336
			prerun(argc, av);
326
			if (ch == EOF || foundeof)
337
			if (ch == EOF || foundeof) {
338
				waitchildren(*argv, 1);
327 339
				exit(rval);
340
			}
328 341
			p = bbp;
329 342
			xp = bxp;
330 343
			count = 0;
......
463 476
static void
464 477
run(char **argv)
465 478
{
466
	volatile int childerr;
467 479
	char **avec;
468 480
	pid_t pid;
469
	int status;
470 481

  
471 482
	/*
472 483
	 * If the user wants to be notified of each command before it is
......
516 527
		childerr = errno;
517 528
		_exit(1);
518 529
	}
519
	pid = waitpid(pid, &status, 0);
520
	if (pid == -1)
521
		err(1, "waitpid");
522
	/* If we couldn't invoke the utility, exit. */
523
	if (childerr != 0)
524
		err(childerr == ENOENT ? 127 : 126, "%s", *argv);
525
	/* If utility signaled or exited with a value of 255, exit 1-125. */
526
	if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
527
		exit(1);
528
	if (WEXITSTATUS(status))
529
		rval = 1;
530
	curprocs++;
531
	waitchildren(*argv, 0);
532
}
533

  
534
/*
535
 * Handle child processes.
536
 */
537
static void
538
waitchildren(const char *name, int waitall)
539
{
540
	pid_t pid;
541
	int status;
542

  
543
	while ((pid = wait3(&status, !waitall && curprocs < maxprocs ?
544
		WNOHANG : 0, NULL)) > 0) {
545
		curprocs--;
546

  
547
		/* If we couldn't invoke the utility, exit. */
548
		if (childerr != 0) {
549
			errno = childerr;
550
			err(errno == ENOENT ? 127 : 126, "%s", name);
551
		}
552

  
553
		/* 
554
		 * If utility signaled or exited with a value of 255,
555
		 * exit 1-125.
556
		 */
557
		if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
558
			exit(1);
559
		if (WEXITSTATUS(status))
560
			rval = 1;
561
        }
562
	if (pid == -1 && errno != ECHILD)
563
		err(1, "wait3");
530 564
}
531 565

  
532 566
/*
......
567 601
{
568 602
	fprintf(stderr,
569 603
"usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n"
570
"             [-L number] [-n number [-x] [-s size] [utility [argument ...]]\n");
604
"             [-L number] [-n number [-x] [-P maxprocs] [-s size]\n"
605
"             [utility [argument ...]]\n");
571 606
	exit(1);
572 607
}