[mod.sources] xargs - execute a command with many arguments

sources-request@panda.UUCP (02/06/86)

Mod.sources:  Volume 3, Issue 106
Submitted by: seismo!amdahl!gam (Gordon A. Moffett)

Here is a reimplementation of the System V utility xargs.  I haven't
heard any complaints about it, though [1] There is room for improvement
regarding the command buffer size (tho' it is better than the System V
area in that particular regard) [2] It does not have all the features
of the System V version (as the man page points out).

                               Gordon A. Moffett
                               {ihnp4,seismo,hplabs}!amdahl!gam

--------------------------------------------------------------------

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by gam on Wed Feb  5 13:15:01 PST 1986
# Contents:  xargs.1 xargs.c
 
echo x - xargs.1
sed 's/^@//' > "xargs.1" <<'@//E*O*F xargs.1//'
@.TH XARGS 1
@.SH NAME
xargs \- execute a command with many arguments
@.SH SYNOPSIS
@.B xargs
command ...
@.SH DESCRIPTION
@.I Xargs
is based on the System V command of the same name.  This
version performs the default function of
@.IR xargs ,
which is also the simplest function.
@.PP
Because Unix imposes a limit on how much space the arguments
of a command may use, that if the argument list were too
large the system prohibits the
command from being executed (in System V, this error is
@.BR E2BIG ,
@.B errno
= 7).
@.PP
To avoid this problem,
@.I xargs
will take arguments which are themselves a command and
@.I its
arguments (options), and then read standard input and
apply it to the command with its given arguments.
@.I Xargs
is careful not to excede the system-imposed limit, which
is expected to be greater than the system's stream file
buffer size,
@.B BUFSIZ
in
@.IR /usr/include/stdio.h .
(The true upper limit can be found in the manual page
@.IR intro(2),
where the
@.B E2BIG
error is described).
It continues to execute the command with the read-in arguments
until it reaches end-of-file.
@.SH "SEE ALSO"
intro(2), exec(2)
@.SH BUGS
Not really the System V Release 2 version at all, but just
looks like it.
@.SH NOTES
@//E*O*F xargs.1//
chmod u=rw,g=r,o=r xargs.1
 
echo x - xargs.c
sed 's/^@//' > "xargs.c" <<'@//E*O*F xargs.c//'
/* xargs -- quickie version of System V xargs(1): read a list of
 *	arguments from stdin, apply to the command which is
 *	the argument(s) of xargs
 */

#include <stdio.h>

char *cmdname;		/* should point to argv[0] */

char command[BUFSIZ];	/* command given to xargs */
char line[BUFSIZ];	/* current input line */	
char cmdbuf[BUFSIZ];	/* command + input lines */

main(argc, argv)
	int argc;
	char *argv[];
{
	char *gets();
	char *strcat(), *strcpy();

	cmdname = argv[0];

	/* skip (xargs) command name */

	argv++, argc--;

	/* construct command from arguments */

	strcpy(command, "exec");
	while (argc--) {
		(void) strcat(command, " ");
		(void) strcat(command, *argv++);
	}

	/* initialize for command execution loop */

	(void) strcpy(cmdbuf, command);

	/* here's where all the action is: read in arguments
	 * from stdin, appending to the current command buffer
	 * if next line would overflow command buffer, execute
	 * command buffer and reinitialize
	 */

	while (gets(line) != NULL) {

		/* the "+2" is for the blank and trailing null char */

		if (strlen(cmdbuf)+strlen(line)+2 > BUFSIZ) {
			docmd(cmdbuf);
			(void) strcpy(cmdbuf, command);
		}
		(void) strcat(cmdbuf, " ");
		(void) strcat(cmdbuf, line);
	}

	/* see if there is any left to do */

	if (strlen(cmdbuf) != strlen(command)) {
		docmd(cmdbuf);
	}
}

docmd(cmdbuf)
char *cmdbuf;
{
	return system(cmdbuf);
}
@//E*O*F xargs.c//
chmod u=rw,g=r,o=r xargs.c
 
exit 0