summaryrefslogtreecommitdiffstats
path: root/usr.bin/xargs
diff options
context:
space:
mode:
authorrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
committerrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
commitf9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch)
treeadd7e996bac5289cdc55e6935750c352505560a9 /usr.bin/xargs
parentbe22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff)
downloadFreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip
FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/xargs')
-rw-r--r--usr.bin/xargs/Makefile5
-rw-r--r--usr.bin/xargs/pathnames.h36
-rw-r--r--usr.bin/xargs/xargs.1161
-rw-r--r--usr.bin/xargs/xargs.c325
4 files changed, 527 insertions, 0 deletions
diff --git a/usr.bin/xargs/Makefile b/usr.bin/xargs/Makefile
new file mode 100644
index 0000000..0bfb074
--- /dev/null
+++ b/usr.bin/xargs/Makefile
@@ -0,0 +1,5 @@
+# @(#)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 0000000..3f05b3d
--- /dev/null
+++ b/usr.bin/xargs/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * 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 8.1 (Berkeley) 6/6/93
+ */
+
+#define _PATH_ECHO "/bin/echo"
diff --git a/usr.bin/xargs/xargs.1 b/usr.bin/xargs/xargs.1
new file mode 100644
index 0000000..e703c43
--- /dev/null
+++ b/usr.bin/xargs/xargs.1
@@ -0,0 +1,161 @@
+.\" 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.
+.Pp
+The
+.Nm xargs
+utility exits with a value of 0 if no error occurs.
+If
+.Ar utility
+cannot be invoked,
+.Nm xargs
+exits with a value of 127.
+If any other error occurs,
+.Nm xargs
+exits with a value of 1.
+.Sh SEE ALSO
+.Xr echo 1 ,
+.Xr find 1
+.Sh STANDARDS
+The
+.Nm xargs
+utility is expected to be
+.St -p1003.2
+compliant.
diff --git a/usr.bin/xargs/xargs.c b/usr.bin/xargs/xargs.c
new file mode 100644
index 0000000..e28e840
--- /dev/null
+++ b/usr.bin/xargs/xargs.c
@@ -0,0 +1,325 @@
+/*-
+ * 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
+static char sccsid[] = "@(#)xargs.c 8.1 (Berkeley) 6/6/93";
+#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 "pathnames.h"
+
+int tflag, rval;
+
+void err __P((const char *, ...));
+void run __P((char **));
+void usage __P((void));
+
+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;
+
+ /*
+ * 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)
+ err("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("%s", strerror(errno));
+
+ /*
+ * 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)
+ err("insufficient space for command");
+
+ if (!(bbp = malloc((u_int)nline + 1)))
+ err("%s", strerror(errno));
+ 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)
+ err("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)
+ err("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)
+ err("backslash at EOF");
+ /* FALLTHROUGH */
+ default:
+addch: if (p < ebp) {
+ *p++ = ch;
+ break;
+ }
+
+ /* If only one argument, not enough buffer space. */
+ if (bxp == xp)
+ err("insufficient space for argument");
+ /* Didn't hit argument limit, so if xflag object. */
+ if (xflag)
+ err("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("vfork: %s", strerror(errno));
+ case 0:
+ execvp(argv[0], argv);
+ (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));
+ /* If we couldn't invoke the utility, exit 127. */
+ if (noinvoke)
+ exit(127);
+ /* 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;
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr,
+"usage: xargs [-t] [-n number [-x]] [-s size] [utility [argument ...]]\n");
+ exit(1);
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+err(const char *fmt, ...)
+#else
+err(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)fprintf(stderr, "xargs: ");
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ exit(1);
+ /* NOTREACHED */
+}
OpenPOWER on IntegriCloud