Add the -P option which executes multiple copies of the specified utility
in parallel. Idea from GNU xargs.
This commit is contained in:
parent
fabf7ce58c
commit
330d23f50e
@ -57,6 +57,7 @@
|
|||||||
.Fl n Ar number
|
.Fl n Ar number
|
||||||
.Op Fl x
|
.Op Fl x
|
||||||
.Oc
|
.Oc
|
||||||
|
.Op Fl P Ar maxjobs
|
||||||
.Op Fl s Ar size
|
.Op Fl s Ar size
|
||||||
.Op Ar utility Op Ar argument ...
|
.Op Ar utility Op Ar argument ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
@ -191,6 +192,12 @@ arguments remaining for the last invocation of
|
|||||||
The current default value for
|
The current default value for
|
||||||
.Ar number
|
.Ar number
|
||||||
is 5000.
|
is 5000.
|
||||||
|
.It Fl P Ar maxprocs
|
||||||
|
Parallel mode: run at most
|
||||||
|
.Ar maxprocs
|
||||||
|
invocations of
|
||||||
|
.Ar utility
|
||||||
|
at once.
|
||||||
.It Fl p
|
.It Fl p
|
||||||
Echo each command to be executed and ask the user whether it should be
|
Echo each command to be executed and ask the user whether it should be
|
||||||
executed.
|
executed.
|
||||||
@ -273,7 +280,8 @@ utility is expected to be
|
|||||||
.St -p1003.2
|
.St -p1003.2
|
||||||
compliant.
|
compliant.
|
||||||
The
|
The
|
||||||
.Fl J
|
.Fl J ,
|
||||||
|
.Fl P
|
||||||
and
|
and
|
||||||
.Fl R
|
.Fl R
|
||||||
options are non-standard
|
options are non-standard
|
||||||
|
@ -76,6 +76,7 @@ static int prompt(void);
|
|||||||
static void run(char **);
|
static void run(char **);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
void strnsubst(char **, const char *, const char *, size_t);
|
void strnsubst(char **, const char *, const char *, size_t);
|
||||||
|
static void waitchildren(const char *, int);
|
||||||
|
|
||||||
static char echo[] = _PATH_ECHO;
|
static char echo[] = _PATH_ECHO;
|
||||||
static char **av, **bxp, **ep, **exp, **xp;
|
static char **av, **bxp, **ep, **exp, **xp;
|
||||||
@ -83,6 +84,9 @@ static char *argp, *bbp, *ebp, *inpline, *p, *replstr;
|
|||||||
static const char *eofstr;
|
static const char *eofstr;
|
||||||
static int count, insingle, indouble, pflag, tflag, Rflag, rval, zflag;
|
static int count, insingle, indouble, pflag, tflag, Rflag, rval, zflag;
|
||||||
static int cnt, Iflag, jfound, Lflag, wasquoted, xflag;
|
static int cnt, Iflag, jfound, Lflag, wasquoted, xflag;
|
||||||
|
static int curprocs, maxprocs;
|
||||||
|
|
||||||
|
static volatile int childerr;
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
@ -121,7 +125,8 @@ main(int argc, char *argv[])
|
|||||||
/* 1 byte for each '\0' */
|
/* 1 byte for each '\0' */
|
||||||
nline -= strlen(*ep++) + 1 + sizeof(*ep);
|
nline -= strlen(*ep++) + 1 + sizeof(*ep);
|
||||||
}
|
}
|
||||||
while ((ch = getopt(argc, argv, "0E:I:J:L:n:pR:s:tx")) != -1)
|
maxprocs = 1;
|
||||||
|
while ((ch = getopt(argc, argv, "0E:I:J:L:n:P:pR:s:tx")) != -1)
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
case 'E':
|
case 'E':
|
||||||
eofstr = optarg;
|
eofstr = optarg;
|
||||||
@ -145,6 +150,10 @@ main(int argc, char *argv[])
|
|||||||
if ((nargs = atoi(optarg)) <= 0)
|
if ((nargs = atoi(optarg)) <= 0)
|
||||||
errx(1, "illegal argument count");
|
errx(1, "illegal argument count");
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
if ((maxprocs = atoi(optarg)) <= 0)
|
||||||
|
errx(1, "max. processes must be >0");
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pflag = 1;
|
pflag = 1;
|
||||||
break;
|
break;
|
||||||
@ -249,8 +258,10 @@ parse_input(int argc, char *argv[])
|
|||||||
switch(ch = getchar()) {
|
switch(ch = getchar()) {
|
||||||
case EOF:
|
case EOF:
|
||||||
/* No arguments since last exec. */
|
/* No arguments since last exec. */
|
||||||
if (p == bbp)
|
if (p == bbp) {
|
||||||
|
waitchildren(*argv, 1);
|
||||||
exit(rval);
|
exit(rval);
|
||||||
|
}
|
||||||
goto arg1;
|
goto arg1;
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
@ -327,8 +338,10 @@ arg2:
|
|||||||
*xp++ = *avj;
|
*xp++ = *avj;
|
||||||
}
|
}
|
||||||
prerun(argc, av);
|
prerun(argc, av);
|
||||||
if (ch == EOF || foundeof)
|
if (ch == EOF || foundeof) {
|
||||||
|
waitchildren(*argv, 1);
|
||||||
exit(rval);
|
exit(rval);
|
||||||
|
}
|
||||||
p = bbp;
|
p = bbp;
|
||||||
xp = bxp;
|
xp = bxp;
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -467,10 +480,8 @@ prerun(int argc, char *argv[])
|
|||||||
static void
|
static void
|
||||||
run(char **argv)
|
run(char **argv)
|
||||||
{
|
{
|
||||||
volatile int childerr;
|
|
||||||
char **avec;
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
char **avec;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the user wants to be notified of each command before it is
|
* If the user wants to be notified of each command before it is
|
||||||
@ -512,17 +523,35 @@ exec:
|
|||||||
childerr = errno;
|
childerr = errno;
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
pid = waitpid(pid, &status, 0);
|
curprocs++;
|
||||||
if (pid == -1)
|
waitchildren(*argv, 0);
|
||||||
err(1, "waitpid");
|
}
|
||||||
/* If we couldn't invoke the utility, exit. */
|
|
||||||
if (childerr != 0)
|
static void
|
||||||
err(childerr == ENOENT ? 127 : 126, "%s", *argv);
|
waitchildren(const char *name, int waitall)
|
||||||
/* If utility signaled or exited with a value of 255, exit 1-125. */
|
{
|
||||||
if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
|
pid_t pid;
|
||||||
exit(1);
|
int status;
|
||||||
if (WEXITSTATUS(status))
|
|
||||||
rval = 1;
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -564,6 +593,7 @@ usage(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: xargs [-0pt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n"
|
"usage: xargs [-0pt] [-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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user