Bug #1953 ยป xargs-P.patch
usr.bin/xargs/xargs.1 | ||
---|---|---|
.Fl n Ar number
|
||
.Op Fl x
|
||
.Oc
|
||
.Op Fl P Ar maxjobs
|
||
.Op Fl s Ar size
|
||
.Op Ar utility Op Ar argument ...
|
||
.Sh DESCRIPTION
|
||
... | ... | |
The current default value for
|
||
.Ar number
|
||
is 5000.
|
||
.It Fl P Ar maxprocs
|
||
Parallel mode: run at most
|
||
.Ar maxprocs
|
||
invocations of
|
||
.Ar utility
|
||
at once.
|
||
.It Fl o
|
||
Reopen stdin as
|
||
.Pa /dev/tty
|
||
... | ... | |
.St -p1003.2
|
||
compliant.
|
||
The
|
||
.Fl J , o
|
||
.Fl J , o , P
|
||
and
|
||
.Fl R
|
||
options are non-standard
|
usr.bin/xargs/xargs.c | ||
---|---|---|
static void run(char **);
|
||
static void usage(void);
|
||
void strnsubst(char **, const char *, const char *, size_t);
|
||
static void waitchildren(const char *, int);
|
||
static char echo[] = _PATH_ECHO;
|
||
static char **av, **bxp, **ep, **expx, **xp;
|
||
... | ... | |
static const char *eofstr;
|
||
static int count, insingle, indouble, oflag, pflag, tflag, Rflag, rval, zflag;
|
||
static int cnt, Iflag, jfound, Lflag, wasquoted, xflag;
|
||
static int curprocs, maxprocs;
|
||
static volatile int childerr;
|
||
extern char **environ;
|
||
... | ... | |
/* 1 byte for each '\0' */
|
||
nline -= strlen(*ep++) + 1 + sizeof(*ep);
|
||
}
|
||
while ((ch = getopt(argc, argv, "0E:I:J:L:n:opR:s:tx")) != -1)
|
||
maxprocs = 1;
|
||
while ((ch = getopt(argc, argv, "0E:I:J:L:n:P:opR:s:tx")) != -1)
|
||
switch(ch) {
|
||
case 'E':
|
||
eofstr = optarg;
|
||
... | ... | |
case 'p':
|
||
pflag = 1;
|
||
break;
|
||
case 'P':
|
||
if ((maxprocs = atoi(optarg)) <= 0)
|
||
errx(1, "max.processes must be >0");
|
||
break;
|
||
case 'R':
|
||
if ((Rflag = atoi(optarg)) <= 0)
|
||
errx(1, "illegal number of replacements");
|
||
... | ... | |
switch(ch = getchar()) {
|
||
case EOF:
|
||
/* No arguments since last exec. */
|
||
if (p == bbp)
|
||
if (p == bbp) {
|
||
waitchildren(*argv, 1);
|
||
exit(rval);
|
||
}
|
||
goto arg1;
|
||
case ' ':
|
||
case '\t':
|
||
... | ... | |
*xp++ = *avj;
|
||
}
|
||
prerun(argc, av);
|
||
if (ch == EOF || foundeof)
|
||
if (ch == EOF || foundeof) {
|
||
waitchildren(*argv, 1);
|
||
exit(rval);
|
||
}
|
||
p = bbp;
|
||
xp = bxp;
|
||
count = 0;
|
||
... | ... | |
static void
|
||
run(char **argv)
|
||
{
|
||
volatile int childerr;
|
||
char **avec;
|
||
pid_t pid;
|
||
int status;
|
||
/*
|
||
* If the user wants to be notified of each command before it is
|
||
... | ... | |
childerr = errno;
|
||
_exit(1);
|
||
}
|
||
pid = waitpid(pid, &status, 0);
|
||
if (pid == -1)
|
||
err(1, "waitpid");
|
||
/* If we couldn't invoke the utility, exit. */
|
||
if (childerr != 0)
|
||
err(childerr == ENOENT ? 127 : 126, "%s", *argv);
|
||
/* If utility signaled or exited with a value of 255, exit 1-125. */
|
||
if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
|
||
exit(1);
|
||
if (WEXITSTATUS(status))
|
||
rval = 1;
|
||
curprocs++;
|
||
waitchildren(*argv, 0);
|
||
}
|
||
/*
|
||
* Handle child processes.
|
||
*/
|
||
static void
|
||
waitchildren(const char *name, int waitall)
|
||
{
|
||
pid_t pid;
|
||
int status;
|
||
while ((pid = wait3(&status, !waitall && curprocs < maxprocs ?
|
||
WNOHANG : 0, NULL)) > 0) {
|
||
curprocs--;
|
||
/* If we couldn't invoke the utility, exit. */
|
||
if (childerr != 0) {
|
||
errno = childerr;
|
||
err(errno == ENOENT ? 127 : 126, "%s", name);
|
||
}
|
||
/*
|
||
* If utility signaled or exited with a value of 255,
|
||
* exit 1-125.
|
||
*/
|
||
if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
|
||
exit(1);
|
||
if (WEXITSTATUS(status))
|
||
rval = 1;
|
||
}
|
||
if (pid == -1 && errno != ECHILD)
|
||
err(1, "wait3");
|
||
}
|
||
/*
|
||
... | ... | |
{
|
||
fprintf(stderr,
|
||
"usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n"
|
||
" [-L number] [-n number [-x] [-s size] [utility [argument ...]]\n");
|
||
" [-L number] [-n number [-x] [-P maxprocs] [-s size]\n"
|
||
" [utility [argument ...]]\n");
|
||
exit(1);
|
||
}
|