diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /usr.bin/xargs |
initial import of NetBSD tree
Diffstat (limited to 'usr.bin/xargs')
-rw-r--r-- | usr.bin/xargs/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/xargs/pathnames.h | 45 | ||||
-rw-r--r-- | usr.bin/xargs/xargs.1 | 184 | ||||
-rw-r--r-- | usr.bin/xargs/xargs.c | 321 |
4 files changed, 556 insertions, 0 deletions
diff --git a/usr.bin/xargs/Makefile b/usr.bin/xargs/Makefile new file mode 100644 index 00000000000..a6d1261223c --- /dev/null +++ b/usr.bin/xargs/Makefile @@ -0,0 +1,6 @@ +# $NetBSD: Makefile,v 1.3 1994/11/14 06:51:37 jtc Exp $ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= xargs + +.include <bsd.prog.mk> diff --git a/usr.bin/xargs/pathnames.h b/usr.bin/xargs/pathnames.h new file mode 100644 index 00000000000..fe034b610c9 --- /dev/null +++ b/usr.bin/xargs/pathnames.h @@ -0,0 +1,45 @@ +/* $NetBSD: pathnames.h,v 1.3 1994/11/14 06:51:38 jtc Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * +<<<<<<< pathnames.h + * from: @(#)pathnames.h 5.1 (Berkeley) 4/17/90 + * $Id: pathnames.h,v 1.1 1995/10/18 08:47:00 deraadt Exp $ +||||||| 1.1.1.2 + * @(#)pathnames.h 5.1 (Berkeley) 4/17/90 +======= + * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 +>>>>>>> /var/tmp/T4001951 + */ + +#define _PATH_ECHO "/bin/echo" diff --git a/usr.bin/xargs/xargs.1 b/usr.bin/xargs/xargs.1 new file mode 100644 index 00000000000..312c7f0165b --- /dev/null +++ b/usr.bin/xargs/xargs.1 @@ -0,0 +1,184 @@ +.\" $NetBSD: xargs.1,v 1.6 1994/11/14 06:51:40 jtc Exp $ +.\" +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" John B. Roll Jr. and the Institute of Electrical and Electronics +.\" Engineers, Inc. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)xargs.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt XARGS 1 +.Os +.Sh NAME +.Nm xargs +.Nd "construct argument list(s) and execute utility" +.Sh SYNOPSIS +.Nm xargs +.Op Fl t +.Oo Op Fl x +.Fl n Ar number +.Oc +.Op Fl s Ar size +.Op Ar utility Op Ar arguments ... +.Sh DESCRIPTION +The +.Nm xargs +utility reads space, tab, newline and end-of-file delimited arguments +from the standard input and executes the specified +.Ar utility +with them as +arguments. +.Pp +The utility and any arguments specified on the command line are given +to the +.Ar utility +upon each invocation, followed by some number of the arguments read +from standard input. +The +.Ar utility +is repeatedly executed until standard input is exhausted. +.Pp +Spaces, tabs and newlines may be embedded in arguments using single +(``\ '\ '') +.Ek +or double (``"'') quotes or backslashes (``\e''). +Single quotes escape all non-single quote characters, excluding newlines, +up to the matching single quote. +Double quotes escape all non-double quote characters, excluding newlines, +up to the matching double quote. +Any single character, including newlines, may be escaped by a backslash. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl n Ar number +Set the maximum number of arguments taken from standard input for each +invocation of the utility. +An invocation of +.Ar utility +will use less than +.Ar number +standard input arguments if the number of bytes accumulated (see the +.Fl s +option) exceeds the specified +.Ar size +or there are fewer than +.Ar number +arguments remaining for the last invocation of +.Ar utility . +The current default value for +.Ar number +is 5000. +.It Fl s Ar size +Set the maximum number of bytes for the command line length provided to +.Ar utility . +The sum of the length of the utility name and the arguments passed to +.Ar utility +(including +.Dv NULL +terminators) will be less than or equal to this number. +The current default value for +.Ar size +is +.Dv ARG_MAX +- 2048. +.It Fl t +Echo the command to be executed to standard error immediately before it +is executed. +.It Fl x +Force +.Nm xargs +to terminate immediately if a command line containing +.Ar number +arguments will not fit in the specified (or default) command line length. +.El +.Pp +If no +.Ar utility +is specified, +.Xr echo 1 +is used. +.Pp +Undefined behavior may occur if +.Ar utility +reads from the standard input. +.Pp +The +.Nm xargs +utility exits immediately (without processing any further input) if a +command line cannot be assembled, +.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. +.Sh DIAGNOSTICS +.Nm xargs +exits with one of the following values: +.Bl -tag -width Ds -compact +.It 0 +All invocations of +.Ar utility +returned a zero exit status. +.It 123 +One or more invocations of +.Ar utility +returned a nonzero exit status. +.It 124 +The +.Ar utility +exited with a 255 exit status. +.It 125 +The +.Ar utility +was killed or stopped by a signal. +.It 126 +The +.Ar utility +was found but could not be invoked. +.It 127 +The +.Ar utility +could not be found. +.It 1 +Some other error occurred. +.El +.Sh SEE ALSO +.Xr echo 1 , +.Xr find 1 +.Sh STANDARDS +The +.Nm xargs +utility is expected to be +.St -p1003.2 +compliant. +.Sh HISTORY +The meaning of 123, 124, and 125 exit values were taken from GNU xargs. diff --git a/usr.bin/xargs/xargs.c b/usr.bin/xargs/xargs.c new file mode 100644 index 00000000000..73910240dcc --- /dev/null +++ b/usr.bin/xargs/xargs.c @@ -0,0 +1,321 @@ +/* $NetBSD: xargs.c,v 1.7 1994/11/14 06:51:41 jtc Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * John B. Roll Jr. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)xargs.c 8.1 (Berkeley) 6/6/93"; +#endif +static char rcsid[] = "$NetBSD: xargs.c,v 1.7 1994/11/14 06:51:41 jtc Exp $"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <locale.h> +#include <err.h> +#include "pathnames.h" + +int tflag, rval; + +void run __P((char **)); +void usage __P((void)); + +int +main(argc, argv) + int argc; + char **argv; +{ + register int ch; + register char *p, *bbp, *ebp, **bxp, **exp, **xp; + int cnt, indouble, insingle, nargs, nflag, nline, xflag; + char **av, *argp; + + setlocale(LC_ALL, ""); + + /* + * POSIX.2 limits the exec line length to ARG_MAX - 2K. Running that + * caused some E2BIG errors, so it was changed to ARG_MAX - 4K. Given + * that the smallest argument is 2 bytes in length, this means that + * the number of arguments is limited to: + * + * (ARG_MAX - 4K - LENGTH(utility + arguments)) / 2. + * + * We arbitrarily limit the number of arguments to 5000. This is + * allowed by POSIX.2 as long as the resulting minimum exec line is + * at least LINE_MAX. Realloc'ing as necessary is possible, but + * probably not worthwhile. + */ + nargs = 5000; + nline = ARG_MAX - 4 * 1024; + nflag = xflag = 0; + while ((ch = getopt(argc, argv, "n:s:tx")) != EOF) + switch(ch) { + case 'n': + nflag = 1; + if ((nargs = atoi(optarg)) <= 0) + errx(1, "illegal argument count"); + break; + case 's': + nline = atoi(optarg); + break; + case 't': + tflag = 1; + break; + case 'x': + xflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (xflag && !nflag) + usage(); + + /* + * Allocate pointers for the utility name, the utility arguments, + * the maximum arguments to be read from stdin and the trailing + * NULL. + */ + if (!(av = bxp = + malloc((u_int)(1 + argc + nargs + 1) * sizeof(char **)))) + err(1, NULL); + + /* + * Use the user's name for the utility as argv[0], just like the + * shell. Echo is the default. Set up pointers for the user's + * arguments. + */ + if (!*argv) + cnt = strlen(*bxp++ = _PATH_ECHO); + else { + cnt = 0; + do { + cnt += strlen(*bxp++ = *argv) + 1; + } while (*++argv); + } + + /* + * Set up begin/end/traversing pointers into the array. The -n + * count doesn't include the trailing NULL pointer, so the malloc + * added in an extra slot. + */ + exp = (xp = bxp) + nargs; + + /* + * Allocate buffer space for the arguments read from stdin and the + * trailing NULL. Buffer space is defined as the default or specified + * space, minus the length of the utility name and arguments. Set up + * begin/end/traversing pointers into the array. The -s count does + * include the trailing NULL, so the malloc didn't add in an extra + * slot. + */ + nline -= cnt; + if (nline <= 0) + errx(1, "insufficient space for command"); + + if (!(bbp = malloc((u_int)nline + 1))) + err(1, NULL); + ebp = (argp = p = bbp) + nline - 1; + + for (insingle = indouble = 0;;) + switch(ch = getchar()) { + case EOF: + /* No arguments since last exec. */ + if (p == bbp) + exit(rval); + + /* Nothing since end of last argument. */ + if (argp == p) { + *xp = NULL; + run(av); + exit(rval); + } + goto arg1; + case ' ': + case '\t': + /* Quotes escape tabs and spaces. */ + if (insingle || indouble) + goto addch; + goto arg2; + case '\n': + /* Empty lines are skipped. */ + if (argp == p) + continue; + + /* Quotes do not escape newlines. */ +arg1: if (insingle || indouble) + errx(1, "unterminated quote"); + +arg2: *p = '\0'; + *xp++ = argp; + + /* + * If max'd out on args or buffer, or reached EOF, + * run the command. If xflag and max'd out on buffer + * but not on args, object. + */ + if (xp == exp || p == ebp || ch == EOF) { + if (xflag && xp != exp && p == ebp) + errx(1, "insufficient space for arguments"); + *xp = NULL; + run(av); + if (ch == EOF) + exit(rval); + p = bbp; + xp = bxp; + } else + ++p; + argp = p; + break; + case '\'': + if (indouble) + goto addch; + insingle = !insingle; + break; + case '"': + if (insingle) + goto addch; + indouble = !indouble; + break; + case '\\': + /* Backslash escapes anything, is escaped by quotes. */ + if (!insingle && !indouble && (ch = getchar()) == EOF) + errx(1, "backslash at EOF"); + /* FALLTHROUGH */ + default: +addch: if (p < ebp) { + *p++ = ch; + break; + } + + /* If only one argument, not enough buffer space. */ + if (bxp == xp) + errx(1, "insufficient space for argument"); + /* Didn't hit argument limit, so if xflag object. */ + if (xflag) + errx(1, "insufficient space for arguments"); + + *xp = NULL; + run(av); + xp = bxp; + cnt = ebp - argp; + bcopy(argp, bbp, cnt); + p = (argp = bbp) + cnt; + *p++ = ch; + break; + } + /* NOTREACHED */ +} + +void +run(argv) + char **argv; +{ + volatile int noinvoke; + register char **p; + pid_t pid; + int status; + + if (tflag) { + (void)fprintf(stderr, "%s", *argv); + for (p = argv + 1; *p; ++p) + (void)fprintf(stderr, " %s", *p); + (void)fprintf(stderr, "\n"); + (void)fflush(stderr); + } + noinvoke = 0; + switch(pid = vfork()) { + case -1: + err(1, "vfork"); + case 0: + execvp(argv[0], argv); + noinvoke = (errno == ENOENT) ? 127 : 126; + warn("%s", argv[0]);; + _exit(1); + } + pid = waitpid(pid, &status, 0); + if (pid == -1) + err(1, "waitpid"); + + /* + * If we couldn't invoke the utility or the utility didn't exit + * properly, quit with 127 or 126 respectively. + */ + 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) { + warnx ("%s exited with status 255", argv[0]); + exit(124); + } else if (WEXITSTATUS (status) != 0) { + rval = 123; + } + } else if (WIFSIGNALED (status)) { + warnx ("%s terminated by signal %d", argv[0], WTERMSIG(status)); + exit(125); + } +} + +void +usage() +{ + (void)fprintf(stderr, +"usage: xargs [-t] [-n number [-x]] [-s size] [utility [argument ...]]\n"); + exit(1); +} |