blob: be1fada78ba458c79ac1476fe577bf114345e5e7 [file] [log] [blame]
/* minix xargs - Make and execute commands
* Author: Ian Nicholls: 1 Mar 90 */
/*
* xargs - Accept words from stdin until, combined with the arguments
* given on the command line, just fit into the command line limit.
* Then, execute the result.
* e.g. ls | xargs compress
* find . -name '*.s' -print | xargs ar qv libc.a
*
* flags: -t Print the command just before it is run
* -l len Use len as maximum line length (default 490, max 1023)
* -e ending Append ending to the command before executing it.
*
* Exits with: 0 No errors.
* 1 If any system(3) call returns a nonzero status.
* 2 Usage error
* 3 Line length too short to contain some single argument.
*
* Examples: xargs ar qv libc.a < liborder # Create a new libc.a
* find . -name '*.s' -print | xargs rm # Remove all .s files
* find . -type f ! -name '*.Z' \ # Compress old files.
* -atime +60 -print | xargs compress -v
*
* Bugs: If the command contains unquoted wildflags, then the system(3) call
* call may expand this to larger than the maximum line size.
* The command is not executed if nothing was read from stdin.
* xargs may give up too easily when the command returns nonzero.
*/
#define USAGE "usage: xargs [-t] [-l len] [-e endargs] command [args...]\n"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <getopt.h>
#ifndef MAX_ARGLINE
# define MAX_ARGLINE 1023
#endif
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
char outlin[MAX_ARGLINE];
char inlin[MAX_ARGLINE];
char startlin[MAX_ARGLINE];
char *ending = NULL;
char traceflag = 0;
int xargs_main(int ac, char **av)
{
int outlen, inlen, startlen, endlen=0, i;
char errflg = 0;
int maxlin = MAX_ARGLINE;
while ((i = getopt(ac, av, "tl:e:")) != EOF)
switch (i) {
case 't': traceflag = 1; break;
case 'l': maxlin = min(MAX_ARGLINE, atoi(optarg)); break;
case 'e': ending = optarg; break;
case '?': errflg++; break;
}
if (errflg) {
fprintf(stderr, USAGE);
exit(2);
}
startlin[0] = 0;
if (optind == ac) {
strcat(startlin, "echo ");
}
else for ( ; optind < ac; optind++) {
strcat(startlin, av[optind]);
strcat(startlin, " ");
}
startlen = strlen(startlin);
if (ending) endlen = strlen(ending);
maxlin = maxlin - 1 - endlen; /* Pre-compute */
strcpy(outlin, startlin);
outlen = startlen;
while (gets(inlin) != NULL) {
inlen = strlen(inlin);
if (maxlin <= (outlen + inlen)) {
if (outlen == startlen) {
fprintf(stderr, "%s: Line length too short to process '%s'\n",
av[0], inlin);
exit(3);
}
if (ending) strcat(outlin, ending);
if (traceflag) fputs(outlin,stderr);
errno = 0;
if (0 != system(outlin)) {
if (errno != 0) perror("xargs");
exit(1);
}
strcpy(outlin, startlin);
outlen = startlen;
}
strcat(outlin, inlin);
strcat(outlin, " ");
outlen = outlen + inlen + 1;
}
if (outlen != startlen) {
if (ending) strcat(outlin, ending);
if (traceflag) fputs(outlin,stderr);
errno = 0;
if (0 != system(outlin)) {
if (errno != 0) perror("xargs");
exit(1);
}
}
return 0;
}