This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[unix-history] / usr.bin / xargs / xargs.c
index e4d3a23..3bae9b6 100644 (file)
@@ -54,7 +54,8 @@ static char sccsid[] = "@(#)xargs.c   5.11 (Berkeley) 6/19/91";
 #include <limits.h>
 #include "pathnames.h"
 
 #include <limits.h>
 #include "pathnames.h"
 
-int fflag, tflag;
+int exit_status = 0;
+int tflag;
 void err __P((const char *, ...));
 void run(), usage();
 
 void err __P((const char *, ...));
 void run(), usage();
 
@@ -85,11 +86,8 @@ main(argc, argv)
        nargs = 5000;
        nline = ARG_MAX - 4 * 1024;
        nflag = xflag = 0;
        nargs = 5000;
        nline = ARG_MAX - 4 * 1024;
        nflag = xflag = 0;
-       while ((ch = getopt(argc, argv, "fn:s:tx")) != EOF)
+       while ((ch = getopt(argc, argv, "n:s:tx")) != EOF)
                switch(ch) {
                switch(ch) {
-               case 'f':
-                       fflag = 1;
-                       break;
                case 'n':
                        nflag = 1;
                        if ((nargs = atoi(optarg)) <= 0)
                case 'n':
                        nflag = 1;
                        if ((nargs = atoi(optarg)) <= 0)
@@ -165,13 +163,13 @@ main(argc, argv)
                case EOF:
                        /* No arguments since last exec. */
                        if (p == bbp)
                case EOF:
                        /* No arguments since last exec. */
                        if (p == bbp)
-                               exit(0);
+                               exit(exit_status);
 
                        /* Nothing since end of last argument. */
                        if (argp == p) {
                                *xp = NULL;
                                run(av);
 
                        /* Nothing since end of last argument. */
                        if (argp == p) {
                                *xp = NULL;
                                run(av);
-                               exit(0);
+                               exit(exit_status);
                        }
                        goto arg1;
                case ' ':
                        }
                        goto arg1;
                case ' ':
@@ -203,7 +201,7 @@ arg2:                       *p = '\0';
                                *xp = NULL;
                                run(av);
                                if (ch == EOF)
                                *xp = NULL;
                                run(av);
                                if (ch == EOF)
-                                       exit(0);
+                                       exit(exit_status);
                                p = bbp;
                                xp = bxp;
                        } else
                                p = bbp;
                                xp = bxp;
                        } else
@@ -272,31 +270,52 @@ run(argv)
                err("vfork: %s", strerror(errno));
        case 0:
                execvp(argv[0], argv);
                err("vfork: %s", strerror(errno));
        case 0:
                execvp(argv[0], argv);
+               noinvoke = (errno == ENOENT) ? 127 : 126;
                (void)fprintf(stderr,
                    "xargs: %s: %s.\n", argv[0], strerror(errno));
                (void)fprintf(stderr,
                    "xargs: %s: %s.\n", argv[0], strerror(errno));
-               noinvoke = 1;
                _exit(1);
        }
        pid = waitpid(pid, &status, 0);
        if (pid == -1)
                err("waitpid: %s", strerror(errno));
                _exit(1);
        }
        pid = waitpid(pid, &status, 0);
        if (pid == -1)
                err("waitpid: %s", strerror(errno));
+
        /*
         * If we couldn't invoke the utility or the utility didn't exit
        /*
         * If we couldn't invoke the utility or the utility didn't exit
-        * properly, quit with 127.
-        * Otherwise, if not specified otherwise, and the utility exits
-        * non-zero, exit with that value.
+        * properly, quit with 127 or 126 respectively.
         */
         */
-       if (noinvoke || !WIFEXITED(status) || WIFSIGNALED(status))
-               exit(127);
-       if (!fflag && WEXITSTATUS(status))
-               exit(WEXITSTATUS(status));
+       if (noinvoke)
+               exit(noinvoke);
+
+       /*
+        * According to POSIX, we have to exit if the utility exits with
+        * a 255 status, or is interrupted by a signal.   xargs is allowed
+        * to return any exit status between 1 and 125 in these cases, but
+        * we'll use 124 and 125, the same values used by GNU xargs.
+        */
+       if (WIFEXITED(status)) {
+               if (WEXITSTATUS (status) == 255) {
+                       fprintf (stderr, "xargs: %s exited with status 255\n",
+                                argv[0]);
+                       exit(124);
+               } else if (WEXITSTATUS (status) != 0) {
+                       exit_status = 123;
+               }
+       } else if (WIFSTOPPED (status)) {
+               fprintf (stderr, "xargs: %s terminated by signal %d\n",
+                        argv[0], WSTOPSIG (status));
+               exit(125);
+       } else if (WIFSIGNALED (status)) {
+               fprintf (stderr, "xargs: %s terminated by signal %d\n",
+                        argv[0], WTERMSIG (status));
+               exit(125);
+       }
 }
 
 void
 usage()
 {
        (void)fprintf(stderr,
 }
 
 void
 usage()
 {
        (void)fprintf(stderr,
-"usage: xargs [-ft] [[-x] -n number] [-s size] [utility [argument ...]]\n");
+"usage: xargs [-t] [[-x] -n number] [-s size] [utility [argument ...]]\n");
        exit(1);
 }
 
        exit(1);
 }