Date: Wed, 13 Feb 2002 16:16:34 +1100 From: Tim Robbins <tim@robbins.dropbear.id.au> To: freebsd-standards@FreeBSD.ORG Subject: xargs(1) -E, -p options and exit status Message-ID: <20020213161634.A4626@descent.robbins.dropbear.id.au>
next in thread | raw e-mail | index | archive | help
This patch corrects the exit status of xargs as well as adds the P1003.1-2001 -E and -p options. I have not added -L and -I options because jmallett is already working on those. It's worth pointing out that the versions of xargs in -STABLE and -CURRENT are NOT POSIX.2 compliant as they claim. Revision 1.7 to xargs.c totally broke the documented 127 exit status by switching from vfork() to fork(). tim@descent$ echo 'hello' | xargs /no xargs: /no: No such file or directory tim@descent$ echo $? 1 Additionally, it would never exit 126 as required by P1003.2. Tim Index: xargs/xargs.1 =================================================================== RCS file: /home/ncvs/src/usr.bin/xargs/xargs.1,v retrieving revision 1.15 diff -u -r1.15 xargs.1 --- xargs/xargs.1 2001/07/05 08:51:08 1.15 +++ xargs/xargs.1 2002/02/13 05:15:34 @@ -44,14 +44,14 @@ .Nd "construct argument list(s) and execute utility" .Sh SYNOPSIS .Nm -.Op Fl 0 +.Op Fl 0pt +.Op Fl E Ar eofstr .Op Fl J Ar replstr .Oo .Fl n Ar number .Op Fl x .Oc .Op Fl s Ar size -.Op Fl t .Op Ar utility Op Ar argument ... .Sh DESCRIPTION The @@ -92,6 +92,10 @@ .Fl print0 function in .Xr find 1 . +.It Fl E Ar eofstr +Use +.Ar eofstr +as a logical EOF marker. .It Fl J Ar replstr If this option is specified, .Nm @@ -142,6 +146,13 @@ The current default value for .Ar number is 5000. +.It Fl p +Echo each command to be executed and ask the user whether it should be +executed. +A response of +.Ql y +causes the command to be executed, any other response causes it to be +skipped. .It Fl s Ar size Set the maximum number of bytes for the command line length provided to .Ar utility . @@ -184,15 +195,19 @@ .Ar utility cannot be invoked, an invocation of the utility is terminated by a signal or an invocation of the utility exits with a value of 255. -.Pp +.Sh DIAGNOSTICS The .Nm utility exits with a value of 0 if no error occurs. If +.Ar utility +cannot be found, +.Nm +exits with a value of 127, otherwise if .Ar utility -cannot be invoked, +cannot be executed, .Nm -exits with a value of 127. +exits with a value of 126. If any other error occurs, .Nm exits with a value of 1. Index: xargs/xargs.c =================================================================== RCS file: /home/ncvs/src/usr.bin/xargs/xargs.c,v retrieving revision 1.11 diff -u -r1.11 xargs.c --- xargs/xargs.c 2001/12/11 22:36:26 1.11 +++ xargs/xargs.c 2002/02/13 05:15:36 @@ -52,6 +52,7 @@ #include <sys/wait.h> #include <err.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -59,7 +60,7 @@ #include "pathnames.h" -int tflag, rval; +int pflag, tflag, rval; int zflag; void run __P((char **)); @@ -74,14 +75,16 @@ { int ch; char *p, *bbp, **bxp, *ebp, **exp, **xp; - int cnt, jfound, indouble, insingle; + int cnt, jfound, indouble, insingle, foundeof; int nargs, nflag, nline, xflag, wasquoted; char **av, **avj, *argp, **ep, *replstr; + const char *eofstr; long arg_max; ep = env; jfound = 0; replstr = NULL; /* set if user requests -J */ + eofstr = ""; /* * POSIX.2 limits the exec line length to ARG_MAX - 2K. Running that @@ -105,8 +108,11 @@ nline -= strlen(*ep++) + 1 + sizeof(*ep); } nflag = xflag = wasquoted = 0; - while ((ch = getopt(argc, argv, "0J:n:s:tx")) != -1) + while ((ch = getopt(argc, argv, "0E:J:n:ps:tx")) != -1) switch(ch) { + case 'E': + eofstr = optarg; + break; case 'J': replstr = optarg; break; @@ -115,6 +121,9 @@ if ((nargs = atoi(optarg)) <= 0) errx(1, "illegal argument count"); break; + case 'p': + pflag = 1; + break; case 's': nline = atoi(optarg); break; @@ -216,8 +225,11 @@ errx(1, "unterminated quote"); arg2: + foundeof = *eofstr != '\0' && + strcmp(argp, eofstr) == 0; + /* Do not make empty args unless they are quoted */ - if (argp != p || wasquoted) { + if ((argp != p || wasquoted) && !foundeof) { *p++ = '\0'; *xp++ = argp; } @@ -227,7 +239,7 @@ * run the command. If xflag and max'd out on buffer * but not on args, object. */ - if (xp == exp || p > ebp || ch == EOF) { + if (xp == exp || p > ebp || ch == EOF || foundeof) { if (xflag && xp != exp && p > ebp) errx(1, "insufficient space for arguments"); if (jfound) { @@ -236,7 +248,7 @@ } *xp = NULL; run(av); - if (ch == EOF) + if (ch == EOF || foundeof) exit(rval); p = bbp; xp = bxp; @@ -296,34 +308,51 @@ run(argv) char **argv; { - volatile int noinvoke; char **p; + FILE *ttyfp; pid_t pid; - int status; + int ch, status, sverrno; - if (tflag) { + if (tflag || pflag) { (void)fprintf(stderr, "%s", *argv); for (p = argv + 1; *p; ++p) (void)fprintf(stderr, " %s", *p); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); + if (pflag) { + if ((ttyfp = fopen("/dev/tty", "r")) != NULL) { + (void)fprintf(stderr, "?"); + (void)fflush(stderr); + ch = getc(ttyfp); + fclose(ttyfp); + if (ch != 'y') + return; + } + } else { + (void)fprintf(stderr, "\n"); + (void)fflush(stderr); + } } - noinvoke = 0; switch(pid = fork()) { case -1: err(1, "fork"); case 0: execvp(argv[0], argv); + sverrno = errno; warn("%s", argv[0]); - noinvoke = 1; - _exit(1); + /* + * XXX Parent needs to know whether the utility couldn't be + * found, or if it was found but could not be invoked. + */ + _exit(sverrno == ENOENT ? 254 : 253); } pid = waitpid(pid, &status, 0); if (pid == -1) err(1, "waitpid"); - /* If we couldn't invoke the utility, exit 127. */ - if (noinvoke) + /* Exit 127 if the utility could not be found */ + if (WEXITSTATUS(status) == 254) exit(127); + /* Exit 126 if the utility was found but not could be invoked */ + if (WEXITSTATUS(status) == 253) + exit(126); /* If utility signaled or exited with a value of 255, exit 1-125. */ if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255) exit(1); @@ -335,7 +364,7 @@ usage() { fprintf(stderr, - "usage: xargs [-0t] [-J replstr] [-n number [-x]] [-s size]\n" - " [utility [argument ...]]\n"); +"usage: xargs [-0pt] [-E eofstr] [-J replstr] [-n number [-x]] [-s size]\n" +" [utility [argument ...]]\n"); exit(1); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020213161634.A4626>