mirror of
https://github.com/darlinghq/darling-shell_cmds.git
synced 2024-11-26 21:10:22 +00:00
Update Source To shell_cmds-216.60.1
This commit is contained in:
parent
eecd2ebfba
commit
8700997f3f
4
.upstream_base_commits
Normal file
4
.upstream_base_commits
Normal file
@ -0,0 +1,4 @@
|
||||
xargs/pathname.h freebsd usr.bin/xargs/pathname.h 872b698bd4a1bfc0bf008c09228e6fd238809c75
|
||||
xargs/strnsubst.c freebsd usr.bin/xargs/strnsubst.c 56640efcbe39386a0152f14fb18a314b85e7e014
|
||||
xargs/xargs.1 freebsd usr.bin/xargs/xargs.1 7e6cabd06e6caa6a02eeb86308dc0cb3f27e10da
|
||||
xargs/xargs.c freebsd usr.bin/xargs/xargs.c 872b698bd4a1bfc0bf008c09228e6fd238809c75
|
195
echo/echo.c
195
echo/echo.c
@ -41,97 +41,142 @@ static char sccsid[] = "@(#)echo.c 8.1 (Berkeley) 5/31/93";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/bin/echo/echo.c,v 1.18 2005/01/10 08:39:22 imp Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
|
||||
/*
|
||||
* Report an error and exit.
|
||||
* Use it instead of err(3) to avoid linking-in stdio.
|
||||
*/
|
||||
static void
|
||||
errexit(const char *prog, const char *reason)
|
||||
flush_and_exit(void)
|
||||
{
|
||||
char *errstr = strerror(errno);
|
||||
write(STDERR_FILENO, prog, strlen(prog));
|
||||
write(STDERR_FILENO, ": ", 2);
|
||||
write(STDERR_FILENO, reason, strlen(reason));
|
||||
write(STDERR_FILENO, ": ", 2);
|
||||
write(STDERR_FILENO, errstr, strlen(errstr));
|
||||
write(STDERR_FILENO, "\n", 1);
|
||||
exit(1);
|
||||
if (fflush(stdout) != 0)
|
||||
err(1, "fflush");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
print_one_char(char *cur, int posix, int *bytes_len_out)
|
||||
{
|
||||
char *next;
|
||||
wchar_t wc;
|
||||
int bytes_len = mbtowc(&wc, cur, MB_CUR_MAX);
|
||||
if (bytes_len <= 0) {
|
||||
putchar(*cur);
|
||||
bytes_len = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If this is not an escape sequence, just print the character */
|
||||
if (wc != '\\') {
|
||||
putwchar(wc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
next = cur + bytes_len;
|
||||
|
||||
if (!posix) {
|
||||
/* In non-POSIX mode, the only valid escape sequence is \c */
|
||||
if (*next == 'c') {
|
||||
flush_and_exit();
|
||||
} else {
|
||||
putchar(wc);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
cur = next;
|
||||
bytes_len = 1;
|
||||
}
|
||||
|
||||
switch (*cur) {
|
||||
case 'a':
|
||||
putchar('\a');
|
||||
goto out;
|
||||
|
||||
case 'b':
|
||||
putchar('\b');
|
||||
goto out;
|
||||
|
||||
case 'c':
|
||||
flush_and_exit();
|
||||
|
||||
case 'f':
|
||||
putchar('\f');
|
||||
goto out;
|
||||
|
||||
case 'n':
|
||||
putchar('\n');
|
||||
goto out;
|
||||
|
||||
case 'r':
|
||||
putchar('\r');
|
||||
goto out;
|
||||
|
||||
case 't':
|
||||
putchar('\t');
|
||||
goto out;
|
||||
|
||||
case 'v':
|
||||
putchar('\v');
|
||||
goto out;
|
||||
|
||||
case '\\':
|
||||
putchar('\\');
|
||||
goto out;
|
||||
|
||||
case '0': {
|
||||
int j = 0, num = 0;
|
||||
while ((*++cur >= '0' && *cur <= '7') &&
|
||||
j++ < 3) {
|
||||
num <<= 3;
|
||||
num |= (*cur - '0');
|
||||
}
|
||||
putchar(num);
|
||||
--cur;
|
||||
goto out;
|
||||
}
|
||||
default:
|
||||
--cur;
|
||||
putchar(*cur);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (bytes_len_out)
|
||||
*bytes_len_out = bytes_len;
|
||||
return cur;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int nflag; /* if not set, output a trailing newline. */
|
||||
int veclen; /* number of writev arguments. */
|
||||
struct iovec *iov, *vp; /* Elements to write, current element. */
|
||||
char space[] = " ";
|
||||
char newline[] = "\n";
|
||||
char *progname = argv[0];
|
||||
int nflag = 0;
|
||||
int posix = (getenv("POSIXLY_CORRECT") != NULL || getenv("POSIX_PEDANTIC") != NULL);
|
||||
|
||||
/* This utility may NOT do getopt(3) option parsing. */
|
||||
if (*++argv && !strcmp(*argv, "-n")) {
|
||||
++argv;
|
||||
--argc;
|
||||
if (!posix && argv[1] && strcmp(argv[1], "-n") == 0)
|
||||
nflag = 1;
|
||||
} else
|
||||
nflag = 0;
|
||||
|
||||
veclen = (argc >= 2) ? (argc - 2) * 2 + 1 : 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
/* argv[0] == progname */
|
||||
int ignore_arg = (i == 0 || (i == 1 && nflag == 1));
|
||||
int last_arg = (i == (argc - 1));
|
||||
if (!ignore_arg) {
|
||||
char *cur = argv[i];
|
||||
size_t arg_len = strlen(cur);
|
||||
int bytes_len = 0;
|
||||
|
||||
if ((vp = iov = malloc((veclen + 1) * sizeof(struct iovec))) == NULL)
|
||||
errexit(progname, "malloc");
|
||||
|
||||
while (argv[0] != NULL) {
|
||||
size_t len;
|
||||
|
||||
len = strlen(argv[0]);
|
||||
|
||||
/*
|
||||
* If the next argument is NULL then this is this
|
||||
* the last argument, therefore we need to check
|
||||
* for a trailing \c.
|
||||
*/
|
||||
if (argv[1] == NULL) {
|
||||
/* is there room for a '\c' and is there one? */
|
||||
if (len >= 2 &&
|
||||
argv[0][len - 2] == '\\' &&
|
||||
argv[0][len - 1] == 'c') {
|
||||
/* chop it and set the no-newline flag. */
|
||||
len -= 2;
|
||||
nflag = 1;
|
||||
for (const char *end = cur + arg_len; cur < end; cur += bytes_len) {
|
||||
cur = print_one_char(cur, posix, &bytes_len);
|
||||
}
|
||||
}
|
||||
vp->iov_base = *argv;
|
||||
vp++->iov_len = len;
|
||||
if (*++argv) {
|
||||
vp->iov_base = space;
|
||||
vp++->iov_len = 1;
|
||||
}
|
||||
}
|
||||
if (!nflag) {
|
||||
veclen++;
|
||||
vp->iov_base = newline;
|
||||
vp++->iov_len = 1;
|
||||
}
|
||||
/* assert(veclen == (vp - iov)); */
|
||||
while (veclen) {
|
||||
int nwrite;
|
||||
if (last_arg && !nflag)
|
||||
putchar('\n');
|
||||
else if (!last_arg && !ignore_arg)
|
||||
putchar(' ');
|
||||
|
||||
nwrite = (veclen > IOV_MAX) ? IOV_MAX : veclen;
|
||||
if (writev(STDOUT_FILENO, iov, nwrite) == -1)
|
||||
errexit(progname, "write");
|
||||
iov += nwrite;
|
||||
veclen -= nwrite;
|
||||
if (fflush(stdout) != 0)
|
||||
err(1, "fflush");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the mkbuiltins program.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "shell.h"
|
||||
#include "builtins.h"
|
||||
|
||||
int (*const builtinfunc[])(int, char **) = {
|
||||
bltincmd,
|
||||
aliascmd,
|
||||
bgcmd,
|
||||
bindcmd,
|
||||
breakcmd,
|
||||
cdcmd,
|
||||
commandcmd,
|
||||
dotcmd,
|
||||
echocmd,
|
||||
evalcmd,
|
||||
execcmd,
|
||||
exitcmd,
|
||||
letcmd,
|
||||
exportcmd,
|
||||
falsecmd,
|
||||
fgcmd,
|
||||
freebsd_wordexpcmd,
|
||||
getoptscmd,
|
||||
hashcmd,
|
||||
histcmd,
|
||||
jobidcmd,
|
||||
jobscmd,
|
||||
killcmd,
|
||||
localcmd,
|
||||
printfcmd,
|
||||
pwdcmd,
|
||||
readcmd,
|
||||
returncmd,
|
||||
setcmd,
|
||||
setvarcmd,
|
||||
shiftcmd,
|
||||
testcmd,
|
||||
timescmd,
|
||||
trapcmd,
|
||||
truecmd,
|
||||
typecmd,
|
||||
ulimitcmd,
|
||||
umaskcmd,
|
||||
unaliascmd,
|
||||
unsetcmd,
|
||||
waitcmd,
|
||||
wordexpcmd,
|
||||
};
|
||||
|
||||
const unsigned char builtincmd[] = {
|
||||
"\007\000builtin"
|
||||
"\005\001alias"
|
||||
"\002\002bg"
|
||||
"\004\003bind"
|
||||
"\005\204break"
|
||||
"\010\204continue"
|
||||
"\002\005cd"
|
||||
"\005\005chdir"
|
||||
"\007\006command"
|
||||
"\001\207."
|
||||
"\004\010echo"
|
||||
"\004\211eval"
|
||||
"\004\212exec"
|
||||
"\004\213exit"
|
||||
"\003\014let"
|
||||
"\006\215export"
|
||||
"\010\215readonly"
|
||||
"\005\016false"
|
||||
"\002\017fg"
|
||||
"\017\020freebsd_wordexp"
|
||||
"\007\021getopts"
|
||||
"\004\022hash"
|
||||
"\002\023fc"
|
||||
"\005\024jobid"
|
||||
"\004\025jobs"
|
||||
"\004\026kill"
|
||||
"\005\027local"
|
||||
"\006\030printf"
|
||||
"\003\031pwd"
|
||||
"\004\032read"
|
||||
"\006\233return"
|
||||
"\003\234set"
|
||||
"\006\035setvar"
|
||||
"\005\236shift"
|
||||
"\004\037test"
|
||||
"\001\037["
|
||||
"\005\240times"
|
||||
"\004\241trap"
|
||||
"\001\242:"
|
||||
"\004\042true"
|
||||
"\004\043type"
|
||||
"\006\044ulimit"
|
||||
"\005\045umask"
|
||||
"\007\046unalias"
|
||||
"\005\247unset"
|
||||
"\004\050wait"
|
||||
"\007\051wordexp"
|
||||
};
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the mkbuiltins program.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#define BLTINCMD 0
|
||||
#define ALIASCMD 1
|
||||
#define BGCMD 2
|
||||
#define BINDCMD 3
|
||||
#define BREAKCMD 4
|
||||
#define CDCMD 5
|
||||
#define COMMANDCMD 6
|
||||
#define DOTCMD 7
|
||||
#define ECHOCMD 8
|
||||
#define EVALCMD 9
|
||||
#define EXECCMD 10
|
||||
#define EXITCMD 11
|
||||
#define LETCMD 12
|
||||
#define EXPORTCMD 13
|
||||
#define FALSECMD 14
|
||||
#define FGCMD 15
|
||||
#define FREEBSD_WORDEXPCMD 16
|
||||
#define GETOPTSCMD 17
|
||||
#define HASHCMD 18
|
||||
#define HISTCMD 19
|
||||
#define JOBIDCMD 20
|
||||
#define JOBSCMD 21
|
||||
#define KILLCMD 22
|
||||
#define LOCALCMD 23
|
||||
#define PRINTFCMD 24
|
||||
#define PWDCMD 25
|
||||
#define READCMD 26
|
||||
#define RETURNCMD 27
|
||||
#define SETCMD 28
|
||||
#define SETVARCMD 29
|
||||
#define SHIFTCMD 30
|
||||
#define TESTCMD 31
|
||||
#define TIMESCMD 32
|
||||
#define TRAPCMD 33
|
||||
#define TRUECMD 34
|
||||
#define TYPECMD 35
|
||||
#define ULIMITCMD 36
|
||||
#define UMASKCMD 37
|
||||
#define UNALIASCMD 38
|
||||
#define UNSETCMD 39
|
||||
#define WAITCMD 40
|
||||
#define WORDEXPCMD 41
|
||||
|
||||
#define BUILTIN_SPECIAL 0x80
|
||||
|
||||
extern int (*const builtinfunc[])(int, char **);
|
||||
extern const unsigned char builtincmd[];
|
||||
|
||||
int bltincmd(int, char **);
|
||||
int aliascmd(int, char **);
|
||||
int bgcmd(int, char **);
|
||||
int bindcmd(int, char **);
|
||||
int breakcmd(int, char **);
|
||||
int cdcmd(int, char **);
|
||||
int commandcmd(int, char **);
|
||||
int dotcmd(int, char **);
|
||||
int echocmd(int, char **);
|
||||
int evalcmd(int, char **);
|
||||
int execcmd(int, char **);
|
||||
int exitcmd(int, char **);
|
||||
int letcmd(int, char **);
|
||||
int exportcmd(int, char **);
|
||||
int falsecmd(int, char **);
|
||||
int fgcmd(int, char **);
|
||||
int freebsd_wordexpcmd(int, char **);
|
||||
int getoptscmd(int, char **);
|
||||
int hashcmd(int, char **);
|
||||
int histcmd(int, char **);
|
||||
int jobidcmd(int, char **);
|
||||
int jobscmd(int, char **);
|
||||
int killcmd(int, char **);
|
||||
int localcmd(int, char **);
|
||||
int printfcmd(int, char **);
|
||||
int pwdcmd(int, char **);
|
||||
int readcmd(int, char **);
|
||||
int returncmd(int, char **);
|
||||
int setcmd(int, char **);
|
||||
int setvarcmd(int, char **);
|
||||
int shiftcmd(int, char **);
|
||||
int testcmd(int, char **);
|
||||
int timescmd(int, char **);
|
||||
int trapcmd(int, char **);
|
||||
int truecmd(int, char **);
|
||||
int typecmd(int, char **);
|
||||
int ulimitcmd(int, char **);
|
||||
int umaskcmd(int, char **);
|
||||
int unaliascmd(int, char **);
|
||||
int unsetcmd(int, char **);
|
||||
int waitcmd(int, char **);
|
||||
int wordexpcmd(int, char **);
|
||||
|
||||
static inline int
|
||||
safe_builtin_always(int idx)
|
||||
{
|
||||
if (idx == BLTINCMD ||
|
||||
idx == COMMANDCMD ||
|
||||
idx == ECHOCMD ||
|
||||
idx == FALSECMD ||
|
||||
idx == JOBIDCMD ||
|
||||
idx == JOBSCMD ||
|
||||
idx == KILLCMD ||
|
||||
idx == PRINTFCMD ||
|
||||
idx == PWDCMD ||
|
||||
idx == TESTCMD ||
|
||||
idx == TIMESCMD ||
|
||||
idx == TRUECMD ||
|
||||
idx == TYPECMD)
|
||||
return (1);
|
||||
return(0);
|
||||
}
|
376
gen/sh/nodes.c
376
gen/sh/nodes.c
@ -1,376 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the mknodes program.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Kenneth Almquist.
|
||||
*
|
||||
* 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. 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.
|
||||
*
|
||||
* @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95
|
||||
* $FreeBSD: head/bin/sh/nodes.c.pat 314436 2017-02-28 23:42:47Z imp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
/*
|
||||
* Routine for dealing with parsed shell commands.
|
||||
*/
|
||||
|
||||
#include "shell.h"
|
||||
#include "nodes.h"
|
||||
#include "memalloc.h"
|
||||
#include "mystring.h"
|
||||
|
||||
|
||||
struct nodesize {
|
||||
int blocksize; /* size of structures in function */
|
||||
int stringsize; /* size of strings in node */
|
||||
};
|
||||
|
||||
struct nodecopystate {
|
||||
pointer block; /* block to allocate function from */
|
||||
char *string; /* block to allocate strings from */
|
||||
};
|
||||
|
||||
static const short nodesize[27] = {
|
||||
ALIGN(sizeof (struct nbinary)),
|
||||
ALIGN(sizeof (struct ncmd)),
|
||||
ALIGN(sizeof (struct npipe)),
|
||||
ALIGN(sizeof (struct nredir)),
|
||||
ALIGN(sizeof (struct nredir)),
|
||||
ALIGN(sizeof (struct nredir)),
|
||||
ALIGN(sizeof (struct nbinary)),
|
||||
ALIGN(sizeof (struct nbinary)),
|
||||
ALIGN(sizeof (struct nif)),
|
||||
ALIGN(sizeof (struct nbinary)),
|
||||
ALIGN(sizeof (struct nbinary)),
|
||||
ALIGN(sizeof (struct nfor)),
|
||||
ALIGN(sizeof (struct ncase)),
|
||||
ALIGN(sizeof (struct nclist)),
|
||||
ALIGN(sizeof (struct nclist)),
|
||||
ALIGN(sizeof (struct narg)),
|
||||
ALIGN(sizeof (struct narg)),
|
||||
ALIGN(sizeof (struct nfile)),
|
||||
ALIGN(sizeof (struct nfile)),
|
||||
ALIGN(sizeof (struct nfile)),
|
||||
ALIGN(sizeof (struct nfile)),
|
||||
ALIGN(sizeof (struct nfile)),
|
||||
ALIGN(sizeof (struct ndup)),
|
||||
ALIGN(sizeof (struct ndup)),
|
||||
ALIGN(sizeof (struct nhere)),
|
||||
ALIGN(sizeof (struct nhere)),
|
||||
ALIGN(sizeof (struct nnot)),
|
||||
};
|
||||
|
||||
|
||||
static void calcsize(union node *, struct nodesize *);
|
||||
static void sizenodelist(struct nodelist *, struct nodesize *);
|
||||
static union node *copynode(union node *, struct nodecopystate *);
|
||||
static struct nodelist *copynodelist(struct nodelist *, struct nodecopystate *);
|
||||
static char *nodesavestr(const char *, struct nodecopystate *);
|
||||
|
||||
|
||||
struct funcdef {
|
||||
unsigned int refcount;
|
||||
union node n;
|
||||
};
|
||||
|
||||
/*
|
||||
* Make a copy of a parse tree.
|
||||
*/
|
||||
|
||||
struct funcdef *
|
||||
copyfunc(union node *n)
|
||||
{
|
||||
struct nodesize sz;
|
||||
struct nodecopystate st;
|
||||
struct funcdef *fn;
|
||||
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
sz.blocksize = offsetof(struct funcdef, n);
|
||||
sz.stringsize = 0;
|
||||
calcsize(n, &sz);
|
||||
fn = ckmalloc(sz.blocksize + sz.stringsize);
|
||||
fn->refcount = 1;
|
||||
st.block = (char *)fn + offsetof(struct funcdef, n);
|
||||
st.string = (char *)fn + sz.blocksize;
|
||||
copynode(n, &st);
|
||||
return fn;
|
||||
}
|
||||
|
||||
|
||||
union node *
|
||||
getfuncnode(struct funcdef *fn)
|
||||
{
|
||||
return fn == NULL ? NULL : &fn->n;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
calcsize(union node *n, struct nodesize *result)
|
||||
{
|
||||
if (n == NULL)
|
||||
return;
|
||||
result->blocksize += nodesize[n->type];
|
||||
switch (n->type) {
|
||||
case NSEMI:
|
||||
case NAND:
|
||||
case NOR:
|
||||
case NWHILE:
|
||||
case NUNTIL:
|
||||
calcsize(n->nbinary.ch2, result);
|
||||
calcsize(n->nbinary.ch1, result);
|
||||
break;
|
||||
case NCMD:
|
||||
calcsize(n->ncmd.redirect, result);
|
||||
calcsize(n->ncmd.args, result);
|
||||
break;
|
||||
case NPIPE:
|
||||
sizenodelist(n->npipe.cmdlist, result);
|
||||
break;
|
||||
case NREDIR:
|
||||
case NBACKGND:
|
||||
case NSUBSHELL:
|
||||
calcsize(n->nredir.redirect, result);
|
||||
calcsize(n->nredir.n, result);
|
||||
break;
|
||||
case NIF:
|
||||
calcsize(n->nif.elsepart, result);
|
||||
calcsize(n->nif.ifpart, result);
|
||||
calcsize(n->nif.test, result);
|
||||
break;
|
||||
case NFOR:
|
||||
result->stringsize += strlen(n->nfor.var) + 1;
|
||||
calcsize(n->nfor.body, result);
|
||||
calcsize(n->nfor.args, result);
|
||||
break;
|
||||
case NCASE:
|
||||
calcsize(n->ncase.cases, result);
|
||||
calcsize(n->ncase.expr, result);
|
||||
break;
|
||||
case NCLIST:
|
||||
case NCLISTFALLTHRU:
|
||||
calcsize(n->nclist.body, result);
|
||||
calcsize(n->nclist.pattern, result);
|
||||
calcsize(n->nclist.next, result);
|
||||
break;
|
||||
case NDEFUN:
|
||||
case NARG:
|
||||
sizenodelist(n->narg.backquote, result);
|
||||
result->stringsize += strlen(n->narg.text) + 1;
|
||||
calcsize(n->narg.next, result);
|
||||
break;
|
||||
case NTO:
|
||||
case NFROM:
|
||||
case NFROMTO:
|
||||
case NAPPEND:
|
||||
case NCLOBBER:
|
||||
calcsize(n->nfile.fname, result);
|
||||
calcsize(n->nfile.next, result);
|
||||
break;
|
||||
case NTOFD:
|
||||
case NFROMFD:
|
||||
calcsize(n->ndup.vname, result);
|
||||
calcsize(n->ndup.next, result);
|
||||
break;
|
||||
case NHERE:
|
||||
case NXHERE:
|
||||
calcsize(n->nhere.doc, result);
|
||||
calcsize(n->nhere.next, result);
|
||||
break;
|
||||
case NNOT:
|
||||
calcsize(n->nnot.com, result);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
sizenodelist(struct nodelist *lp, struct nodesize *result)
|
||||
{
|
||||
while (lp) {
|
||||
result->blocksize += ALIGN(sizeof(struct nodelist));
|
||||
calcsize(lp->n, result);
|
||||
lp = lp->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static union node *
|
||||
copynode(union node *n, struct nodecopystate *state)
|
||||
{
|
||||
union node *new;
|
||||
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
new = state->block;
|
||||
state->block = (char *)state->block + nodesize[n->type];
|
||||
switch (n->type) {
|
||||
case NSEMI:
|
||||
case NAND:
|
||||
case NOR:
|
||||
case NWHILE:
|
||||
case NUNTIL:
|
||||
new->nbinary.ch2 = copynode(n->nbinary.ch2, state);
|
||||
new->nbinary.ch1 = copynode(n->nbinary.ch1, state);
|
||||
break;
|
||||
case NCMD:
|
||||
new->ncmd.redirect = copynode(n->ncmd.redirect, state);
|
||||
new->ncmd.args = copynode(n->ncmd.args, state);
|
||||
break;
|
||||
case NPIPE:
|
||||
new->npipe.cmdlist = copynodelist(n->npipe.cmdlist, state);
|
||||
new->npipe.backgnd = n->npipe.backgnd;
|
||||
break;
|
||||
case NREDIR:
|
||||
case NBACKGND:
|
||||
case NSUBSHELL:
|
||||
new->nredir.redirect = copynode(n->nredir.redirect, state);
|
||||
new->nredir.n = copynode(n->nredir.n, state);
|
||||
break;
|
||||
case NIF:
|
||||
new->nif.elsepart = copynode(n->nif.elsepart, state);
|
||||
new->nif.ifpart = copynode(n->nif.ifpart, state);
|
||||
new->nif.test = copynode(n->nif.test, state);
|
||||
break;
|
||||
case NFOR:
|
||||
new->nfor.var = nodesavestr(n->nfor.var, state);
|
||||
new->nfor.body = copynode(n->nfor.body, state);
|
||||
new->nfor.args = copynode(n->nfor.args, state);
|
||||
break;
|
||||
case NCASE:
|
||||
new->ncase.cases = copynode(n->ncase.cases, state);
|
||||
new->ncase.expr = copynode(n->ncase.expr, state);
|
||||
break;
|
||||
case NCLIST:
|
||||
case NCLISTFALLTHRU:
|
||||
new->nclist.body = copynode(n->nclist.body, state);
|
||||
new->nclist.pattern = copynode(n->nclist.pattern, state);
|
||||
new->nclist.next = copynode(n->nclist.next, state);
|
||||
break;
|
||||
case NDEFUN:
|
||||
case NARG:
|
||||
new->narg.backquote = copynodelist(n->narg.backquote, state);
|
||||
new->narg.text = nodesavestr(n->narg.text, state);
|
||||
new->narg.next = copynode(n->narg.next, state);
|
||||
break;
|
||||
case NTO:
|
||||
case NFROM:
|
||||
case NFROMTO:
|
||||
case NAPPEND:
|
||||
case NCLOBBER:
|
||||
new->nfile.fname = copynode(n->nfile.fname, state);
|
||||
new->nfile.next = copynode(n->nfile.next, state);
|
||||
new->nfile.fd = n->nfile.fd;
|
||||
break;
|
||||
case NTOFD:
|
||||
case NFROMFD:
|
||||
new->ndup.vname = copynode(n->ndup.vname, state);
|
||||
new->ndup.dupfd = n->ndup.dupfd;
|
||||
new->ndup.next = copynode(n->ndup.next, state);
|
||||
new->ndup.fd = n->ndup.fd;
|
||||
break;
|
||||
case NHERE:
|
||||
case NXHERE:
|
||||
new->nhere.doc = copynode(n->nhere.doc, state);
|
||||
new->nhere.next = copynode(n->nhere.next, state);
|
||||
new->nhere.fd = n->nhere.fd;
|
||||
break;
|
||||
case NNOT:
|
||||
new->nnot.com = copynode(n->nnot.com, state);
|
||||
break;
|
||||
};
|
||||
new->type = n->type;
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
static struct nodelist *
|
||||
copynodelist(struct nodelist *lp, struct nodecopystate *state)
|
||||
{
|
||||
struct nodelist *start;
|
||||
struct nodelist **lpp;
|
||||
|
||||
lpp = &start;
|
||||
while (lp) {
|
||||
*lpp = state->block;
|
||||
state->block = (char *)state->block +
|
||||
ALIGN(sizeof(struct nodelist));
|
||||
(*lpp)->n = copynode(lp->n, state);
|
||||
lp = lp->next;
|
||||
lpp = &(*lpp)->next;
|
||||
}
|
||||
*lpp = NULL;
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
nodesavestr(const char *s, struct nodecopystate *state)
|
||||
{
|
||||
const char *p = s;
|
||||
char *q = state->string;
|
||||
char *rtn = state->string;
|
||||
|
||||
while ((*q++ = *p++) != '\0')
|
||||
continue;
|
||||
state->string = q;
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
reffunc(struct funcdef *fn)
|
||||
{
|
||||
if (fn)
|
||||
fn->refcount++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decrement the reference count of a function definition, freeing it
|
||||
* if it falls to 0.
|
||||
*/
|
||||
|
||||
void
|
||||
unreffunc(struct funcdef *fn)
|
||||
{
|
||||
if (fn) {
|
||||
fn->refcount--;
|
||||
if (fn->refcount > 0)
|
||||
return;
|
||||
ckfree(fn);
|
||||
}
|
||||
}
|
163
gen/sh/nodes.h
163
gen/sh/nodes.h
@ -1,163 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the mknodes program.
|
||||
*/
|
||||
|
||||
#define NSEMI 0
|
||||
#define NCMD 1
|
||||
#define NPIPE 2
|
||||
#define NREDIR 3
|
||||
#define NBACKGND 4
|
||||
#define NSUBSHELL 5
|
||||
#define NAND 6
|
||||
#define NOR 7
|
||||
#define NIF 8
|
||||
#define NWHILE 9
|
||||
#define NUNTIL 10
|
||||
#define NFOR 11
|
||||
#define NCASE 12
|
||||
#define NCLIST 13
|
||||
#define NCLISTFALLTHRU 14
|
||||
#define NDEFUN 15
|
||||
#define NARG 16
|
||||
#define NTO 17
|
||||
#define NFROM 18
|
||||
#define NFROMTO 19
|
||||
#define NAPPEND 20
|
||||
#define NCLOBBER 21
|
||||
#define NTOFD 22
|
||||
#define NFROMFD 23
|
||||
#define NHERE 24
|
||||
#define NXHERE 25
|
||||
#define NNOT 26
|
||||
|
||||
|
||||
|
||||
struct nbinary {
|
||||
int type;
|
||||
union node *ch1;
|
||||
union node *ch2;
|
||||
};
|
||||
|
||||
|
||||
struct ncmd {
|
||||
int type;
|
||||
union node *args;
|
||||
union node *redirect;
|
||||
};
|
||||
|
||||
|
||||
struct npipe {
|
||||
int type;
|
||||
int backgnd;
|
||||
struct nodelist *cmdlist;
|
||||
};
|
||||
|
||||
|
||||
struct nredir {
|
||||
int type;
|
||||
union node *n;
|
||||
union node *redirect;
|
||||
};
|
||||
|
||||
|
||||
struct nif {
|
||||
int type;
|
||||
union node *test;
|
||||
union node *ifpart;
|
||||
union node *elsepart;
|
||||
};
|
||||
|
||||
|
||||
struct nfor {
|
||||
int type;
|
||||
union node *args;
|
||||
union node *body;
|
||||
char *var;
|
||||
};
|
||||
|
||||
|
||||
struct ncase {
|
||||
int type;
|
||||
union node *expr;
|
||||
union node *cases;
|
||||
};
|
||||
|
||||
|
||||
struct nclist {
|
||||
int type;
|
||||
union node *next;
|
||||
union node *pattern;
|
||||
union node *body;
|
||||
};
|
||||
|
||||
|
||||
struct narg {
|
||||
int type;
|
||||
union node *next;
|
||||
char *text;
|
||||
struct nodelist *backquote;
|
||||
};
|
||||
|
||||
|
||||
struct nfile {
|
||||
int type;
|
||||
int fd;
|
||||
union node *next;
|
||||
union node *fname;
|
||||
char *expfname;
|
||||
};
|
||||
|
||||
|
||||
struct ndup {
|
||||
int type;
|
||||
int fd;
|
||||
union node *next;
|
||||
int dupfd;
|
||||
union node *vname;
|
||||
};
|
||||
|
||||
|
||||
struct nhere {
|
||||
int type;
|
||||
int fd;
|
||||
union node *next;
|
||||
union node *doc;
|
||||
const char *expdoc;
|
||||
};
|
||||
|
||||
|
||||
struct nnot {
|
||||
int type;
|
||||
union node *com;
|
||||
};
|
||||
|
||||
|
||||
union node {
|
||||
int type;
|
||||
struct nbinary nbinary;
|
||||
struct ncmd ncmd;
|
||||
struct npipe npipe;
|
||||
struct nredir nredir;
|
||||
struct nif nif;
|
||||
struct nfor nfor;
|
||||
struct ncase ncase;
|
||||
struct nclist nclist;
|
||||
struct narg narg;
|
||||
struct nfile nfile;
|
||||
struct ndup ndup;
|
||||
struct nhere nhere;
|
||||
struct nnot nnot;
|
||||
};
|
||||
|
||||
|
||||
struct nodelist {
|
||||
struct nodelist *next;
|
||||
union node *n;
|
||||
};
|
||||
|
||||
|
||||
struct funcdef;
|
||||
struct funcdef *copyfunc(union node *);
|
||||
union node *getfuncnode(struct funcdef *);
|
||||
void reffunc(struct funcdef *);
|
||||
void unreffunc(struct funcdef *);
|
192
gen/sh/syntax.c
192
gen/sh/syntax.c
@ -1,192 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the mksyntax program.
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#include "shell.h"
|
||||
#include "syntax.h"
|
||||
|
||||
/* syntax table used when not in quotes */
|
||||
const char basesyntax[SYNBASE + CHAR_MAX + 1] = {
|
||||
[SYNBASE + PEOF] = CEOF,
|
||||
[SYNBASE + CTLESC] = CCTL,
|
||||
[SYNBASE + CTLVAR] = CCTL,
|
||||
[SYNBASE + CTLENDVAR] = CCTL,
|
||||
[SYNBASE + CTLBACKQ] = CCTL,
|
||||
[SYNBASE + CTLBACKQ + CTLQUOTE] = CCTL,
|
||||
[SYNBASE + CTLARI] = CCTL,
|
||||
[SYNBASE + CTLENDARI] = CCTL,
|
||||
[SYNBASE + CTLQUOTEMARK] = CCTL,
|
||||
[SYNBASE + CTLQUOTEEND] = CCTL,
|
||||
[SYNBASE + '\n'] = CNL,
|
||||
[SYNBASE + '\\'] = CBACK,
|
||||
[SYNBASE + '\''] = CSQUOTE,
|
||||
[SYNBASE + '"'] = CDQUOTE,
|
||||
[SYNBASE + '`'] = CBQUOTE,
|
||||
[SYNBASE + '$'] = CVAR,
|
||||
[SYNBASE + '}'] = CENDVAR,
|
||||
[SYNBASE + '<'] = CSPCL,
|
||||
[SYNBASE + '>'] = CSPCL,
|
||||
[SYNBASE + '('] = CSPCL,
|
||||
[SYNBASE + ')'] = CSPCL,
|
||||
[SYNBASE + ';'] = CSPCL,
|
||||
[SYNBASE + '&'] = CSPCL,
|
||||
[SYNBASE + '|'] = CSPCL,
|
||||
[SYNBASE + ' '] = CSPCL,
|
||||
[SYNBASE + '\t'] = CSPCL,
|
||||
};
|
||||
|
||||
/* syntax table used when in double quotes */
|
||||
const char dqsyntax[SYNBASE + CHAR_MAX + 1] = {
|
||||
[SYNBASE + PEOF] = CEOF,
|
||||
[SYNBASE + CTLESC] = CCTL,
|
||||
[SYNBASE + CTLVAR] = CCTL,
|
||||
[SYNBASE + CTLENDVAR] = CCTL,
|
||||
[SYNBASE + CTLBACKQ] = CCTL,
|
||||
[SYNBASE + CTLBACKQ + CTLQUOTE] = CCTL,
|
||||
[SYNBASE + CTLARI] = CCTL,
|
||||
[SYNBASE + CTLENDARI] = CCTL,
|
||||
[SYNBASE + CTLQUOTEMARK] = CCTL,
|
||||
[SYNBASE + CTLQUOTEEND] = CCTL,
|
||||
[SYNBASE + '\n'] = CNL,
|
||||
[SYNBASE + '\\'] = CBACK,
|
||||
[SYNBASE + '"'] = CENDQUOTE,
|
||||
[SYNBASE + '`'] = CBQUOTE,
|
||||
[SYNBASE + '$'] = CVAR,
|
||||
[SYNBASE + '}'] = CENDVAR,
|
||||
[SYNBASE + '!'] = CCTL,
|
||||
[SYNBASE + '*'] = CCTL,
|
||||
[SYNBASE + '?'] = CCTL,
|
||||
[SYNBASE + '['] = CCTL,
|
||||
[SYNBASE + ']'] = CCTL,
|
||||
[SYNBASE + '='] = CCTL,
|
||||
[SYNBASE + '~'] = CCTL,
|
||||
[SYNBASE + ':'] = CCTL,
|
||||
[SYNBASE + '/'] = CCTL,
|
||||
[SYNBASE + '-'] = CCTL,
|
||||
[SYNBASE + '^'] = CCTL,
|
||||
};
|
||||
|
||||
/* syntax table used when in single quotes */
|
||||
const char sqsyntax[SYNBASE + CHAR_MAX + 1] = {
|
||||
[SYNBASE + PEOF] = CEOF,
|
||||
[SYNBASE + CTLESC] = CCTL,
|
||||
[SYNBASE + CTLVAR] = CCTL,
|
||||
[SYNBASE + CTLENDVAR] = CCTL,
|
||||
[SYNBASE + CTLBACKQ] = CCTL,
|
||||
[SYNBASE + CTLBACKQ + CTLQUOTE] = CCTL,
|
||||
[SYNBASE + CTLARI] = CCTL,
|
||||
[SYNBASE + CTLENDARI] = CCTL,
|
||||
[SYNBASE + CTLQUOTEMARK] = CCTL,
|
||||
[SYNBASE + CTLQUOTEEND] = CCTL,
|
||||
[SYNBASE + '\n'] = CNL,
|
||||
[SYNBASE + '\\'] = CSBACK,
|
||||
[SYNBASE + '\''] = CENDQUOTE,
|
||||
[SYNBASE + '!'] = CCTL,
|
||||
[SYNBASE + '*'] = CCTL,
|
||||
[SYNBASE + '?'] = CCTL,
|
||||
[SYNBASE + '['] = CCTL,
|
||||
[SYNBASE + ']'] = CCTL,
|
||||
[SYNBASE + '='] = CCTL,
|
||||
[SYNBASE + '~'] = CCTL,
|
||||
[SYNBASE + ':'] = CCTL,
|
||||
[SYNBASE + '/'] = CCTL,
|
||||
[SYNBASE + '-'] = CCTL,
|
||||
[SYNBASE + '^'] = CCTL,
|
||||
};
|
||||
|
||||
/* syntax table used when in arithmetic */
|
||||
const char arisyntax[SYNBASE + CHAR_MAX + 1] = {
|
||||
[SYNBASE + PEOF] = CEOF,
|
||||
[SYNBASE + CTLESC] = CCTL,
|
||||
[SYNBASE + CTLVAR] = CCTL,
|
||||
[SYNBASE + CTLENDVAR] = CCTL,
|
||||
[SYNBASE + CTLBACKQ] = CCTL,
|
||||
[SYNBASE + CTLBACKQ + CTLQUOTE] = CCTL,
|
||||
[SYNBASE + CTLARI] = CCTL,
|
||||
[SYNBASE + CTLENDARI] = CCTL,
|
||||
[SYNBASE + CTLQUOTEMARK] = CCTL,
|
||||
[SYNBASE + CTLQUOTEEND] = CCTL,
|
||||
[SYNBASE + '\n'] = CNL,
|
||||
[SYNBASE + '\\'] = CBACK,
|
||||
[SYNBASE + '`'] = CBQUOTE,
|
||||
[SYNBASE + '"'] = CIGN,
|
||||
[SYNBASE + '$'] = CVAR,
|
||||
[SYNBASE + '}'] = CENDVAR,
|
||||
[SYNBASE + '('] = CLP,
|
||||
[SYNBASE + ')'] = CRP,
|
||||
};
|
||||
|
||||
/* character classification table */
|
||||
const char is_type[SYNBASE + CHAR_MAX + 1] = {
|
||||
[SYNBASE + '0'] = ISDIGIT,
|
||||
[SYNBASE + '1'] = ISDIGIT,
|
||||
[SYNBASE + '2'] = ISDIGIT,
|
||||
[SYNBASE + '3'] = ISDIGIT,
|
||||
[SYNBASE + '4'] = ISDIGIT,
|
||||
[SYNBASE + '5'] = ISDIGIT,
|
||||
[SYNBASE + '6'] = ISDIGIT,
|
||||
[SYNBASE + '7'] = ISDIGIT,
|
||||
[SYNBASE + '8'] = ISDIGIT,
|
||||
[SYNBASE + '9'] = ISDIGIT,
|
||||
[SYNBASE + 'a'] = ISLOWER,
|
||||
[SYNBASE + 'b'] = ISLOWER,
|
||||
[SYNBASE + 'c'] = ISLOWER,
|
||||
[SYNBASE + 'd'] = ISLOWER,
|
||||
[SYNBASE + 'e'] = ISLOWER,
|
||||
[SYNBASE + 'f'] = ISLOWER,
|
||||
[SYNBASE + 'g'] = ISLOWER,
|
||||
[SYNBASE + 'h'] = ISLOWER,
|
||||
[SYNBASE + 'i'] = ISLOWER,
|
||||
[SYNBASE + 'j'] = ISLOWER,
|
||||
[SYNBASE + 'k'] = ISLOWER,
|
||||
[SYNBASE + 'l'] = ISLOWER,
|
||||
[SYNBASE + 'm'] = ISLOWER,
|
||||
[SYNBASE + 'n'] = ISLOWER,
|
||||
[SYNBASE + 'o'] = ISLOWER,
|
||||
[SYNBASE + 'p'] = ISLOWER,
|
||||
[SYNBASE + 'q'] = ISLOWER,
|
||||
[SYNBASE + 'r'] = ISLOWER,
|
||||
[SYNBASE + 's'] = ISLOWER,
|
||||
[SYNBASE + 't'] = ISLOWER,
|
||||
[SYNBASE + 'u'] = ISLOWER,
|
||||
[SYNBASE + 'v'] = ISLOWER,
|
||||
[SYNBASE + 'w'] = ISLOWER,
|
||||
[SYNBASE + 'x'] = ISLOWER,
|
||||
[SYNBASE + 'y'] = ISLOWER,
|
||||
[SYNBASE + 'z'] = ISLOWER,
|
||||
[SYNBASE + 'A'] = ISUPPER,
|
||||
[SYNBASE + 'B'] = ISUPPER,
|
||||
[SYNBASE + 'C'] = ISUPPER,
|
||||
[SYNBASE + 'D'] = ISUPPER,
|
||||
[SYNBASE + 'E'] = ISUPPER,
|
||||
[SYNBASE + 'F'] = ISUPPER,
|
||||
[SYNBASE + 'G'] = ISUPPER,
|
||||
[SYNBASE + 'H'] = ISUPPER,
|
||||
[SYNBASE + 'I'] = ISUPPER,
|
||||
[SYNBASE + 'J'] = ISUPPER,
|
||||
[SYNBASE + 'K'] = ISUPPER,
|
||||
[SYNBASE + 'L'] = ISUPPER,
|
||||
[SYNBASE + 'M'] = ISUPPER,
|
||||
[SYNBASE + 'N'] = ISUPPER,
|
||||
[SYNBASE + 'O'] = ISUPPER,
|
||||
[SYNBASE + 'P'] = ISUPPER,
|
||||
[SYNBASE + 'Q'] = ISUPPER,
|
||||
[SYNBASE + 'R'] = ISUPPER,
|
||||
[SYNBASE + 'S'] = ISUPPER,
|
||||
[SYNBASE + 'T'] = ISUPPER,
|
||||
[SYNBASE + 'U'] = ISUPPER,
|
||||
[SYNBASE + 'V'] = ISUPPER,
|
||||
[SYNBASE + 'W'] = ISUPPER,
|
||||
[SYNBASE + 'X'] = ISUPPER,
|
||||
[SYNBASE + 'Y'] = ISUPPER,
|
||||
[SYNBASE + 'Z'] = ISUPPER,
|
||||
[SYNBASE + '_'] = ISUNDER,
|
||||
[SYNBASE + '#'] = ISSPECL,
|
||||
[SYNBASE + '?'] = ISSPECL,
|
||||
[SYNBASE + '$'] = ISSPECL,
|
||||
[SYNBASE + '!'] = ISSPECL,
|
||||
[SYNBASE + '-'] = ISSPECL,
|
||||
[SYNBASE + '*'] = ISSPECL,
|
||||
[SYNBASE + '@'] = ISSPECL,
|
||||
};
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the mksyntax program.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* Syntax classes */
|
||||
#define CWORD 0 /* character is nothing special */
|
||||
#define CNL 1 /* newline character */
|
||||
#define CBACK 2 /* a backslash character */
|
||||
#define CSBACK 3 /* a backslash character in single quotes */
|
||||
#define CSQUOTE 4 /* single quote */
|
||||
#define CDQUOTE 5 /* double quote */
|
||||
#define CENDQUOTE 6 /* a terminating quote */
|
||||
#define CBQUOTE 7 /* backwards single quote */
|
||||
#define CVAR 8 /* a dollar sign */
|
||||
#define CENDVAR 9 /* a '}' character */
|
||||
#define CLP 10 /* a left paren in arithmetic */
|
||||
#define CRP 11 /* a right paren in arithmetic */
|
||||
#define CEOF 12 /* end of file */
|
||||
#define CCTL 13 /* like CWORD, except it must be escaped */
|
||||
#define CSPCL 14 /* these terminate a word */
|
||||
#define CIGN 15 /* character should be ignored */
|
||||
|
||||
/* Syntax classes for is_ functions */
|
||||
#define ISDIGIT 01 /* a digit */
|
||||
#define ISUPPER 02 /* an upper case letter */
|
||||
#define ISLOWER 04 /* a lower case letter */
|
||||
#define ISUNDER 010 /* an underscore */
|
||||
#define ISSPECL 020 /* the name of a special parameter */
|
||||
|
||||
#define SYNBASE (1 - CHAR_MIN)
|
||||
#define PEOF -SYNBASE
|
||||
|
||||
|
||||
#define BASESYNTAX (basesyntax + SYNBASE)
|
||||
#define DQSYNTAX (dqsyntax + SYNBASE)
|
||||
#define SQSYNTAX (sqsyntax + SYNBASE)
|
||||
#define ARISYNTAX (arisyntax + SYNBASE)
|
||||
|
||||
#define is_digit(c) ((unsigned int)((c) - '0') <= 9)
|
||||
#define is_eof(c) ((c) == PEOF)
|
||||
#define is_alpha(c) ((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER))
|
||||
#define is_name(c) ((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER|ISUNDER))
|
||||
#define is_in_name(c) ((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER|ISUNDER|ISDIGIT))
|
||||
#define is_special(c) ((is_type+SYNBASE)[(int)c] & (ISSPECL|ISDIGIT))
|
||||
#define digit_val(c) ((c) - '0')
|
||||
|
||||
extern const char basesyntax[];
|
||||
extern const char dqsyntax[];
|
||||
extern const char sqsyntax[];
|
||||
extern const char arisyntax[];
|
||||
extern const char is_type[];
|
112
gen/sh/token.h
112
gen/sh/token.h
@ -1,112 +0,0 @@
|
||||
#define TEOF 0
|
||||
#define TNL 1
|
||||
#define TSEMI 2
|
||||
#define TBACKGND 3
|
||||
#define TAND 4
|
||||
#define TOR 5
|
||||
#define TPIPE 6
|
||||
#define TLP 7
|
||||
#define TRP 8
|
||||
#define TENDCASE 9
|
||||
#define TFALLTHRU 10
|
||||
#define TREDIR 11
|
||||
#define TWORD 12
|
||||
#define TIF 13
|
||||
#define TTHEN 14
|
||||
#define TELSE 15
|
||||
#define TELIF 16
|
||||
#define TFI 17
|
||||
#define TWHILE 18
|
||||
#define TUNTIL 19
|
||||
#define TFOR 20
|
||||
#define TDO 21
|
||||
#define TDONE 22
|
||||
#define TBEGIN 23
|
||||
#define TEND 24
|
||||
#define TCASE 25
|
||||
#define TESAC 26
|
||||
#define TNOT 27
|
||||
|
||||
/* Array indicating which tokens mark the end of a list */
|
||||
static const char tokendlist[] = {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
};
|
||||
|
||||
static const char *const tokname[] = {
|
||||
"end of file",
|
||||
"newline",
|
||||
"\";\"",
|
||||
"\"&\"",
|
||||
"\"&&\"",
|
||||
"\"||\"",
|
||||
"\"|\"",
|
||||
"\"(\"",
|
||||
"\")\"",
|
||||
"\";;\"",
|
||||
"\";&\"",
|
||||
"redirection",
|
||||
"word",
|
||||
"\"if\"",
|
||||
"\"then\"",
|
||||
"\"else\"",
|
||||
"\"elif\"",
|
||||
"\"fi\"",
|
||||
"\"while\"",
|
||||
"\"until\"",
|
||||
"\"for\"",
|
||||
"\"do\"",
|
||||
"\"done\"",
|
||||
"\"{\"",
|
||||
"\"}\"",
|
||||
"\"case\"",
|
||||
"\"esac\"",
|
||||
"\"!\"",
|
||||
};
|
||||
|
||||
#define KWDOFFSET 13
|
||||
|
||||
const char *const parsekwd[] = {
|
||||
"if",
|
||||
"then",
|
||||
"else",
|
||||
"elif",
|
||||
"fi",
|
||||
"while",
|
||||
"until",
|
||||
"for",
|
||||
"do",
|
||||
"done",
|
||||
"{",
|
||||
"}",
|
||||
"case",
|
||||
"esac",
|
||||
"!",
|
||||
0
|
||||
};
|
27
kill/kill.c
27
kill/kill.c
@ -62,6 +62,7 @@ static void nosig(const char *);
|
||||
static void printsignals(FILE *);
|
||||
static int signame_to_signum(const char *);
|
||||
static void usage(void);
|
||||
static void print_signum(int, FILE *, char);
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define sys_nsig NSIG
|
||||
@ -93,7 +94,7 @@ main(int argc, char *argv[])
|
||||
numsig -= 128;
|
||||
if (numsig <= 0 || numsig >= sys_nsig)
|
||||
nosig(*argv);
|
||||
printf("%s\n", sys_signame[numsig]);
|
||||
print_signum(numsig, stdout, '\n');
|
||||
return (0);
|
||||
}
|
||||
printsignals(stdout);
|
||||
@ -155,6 +156,23 @@ main(int argc, char *argv[])
|
||||
return (errors);
|
||||
}
|
||||
|
||||
static void
|
||||
print_signum(int numsig, FILE *fp, char separator)
|
||||
{
|
||||
char *signame;
|
||||
int i;
|
||||
|
||||
signame = strdup(sys_signame[numsig]);
|
||||
|
||||
for(i = 0; signame[i] != '\0'; i++) {
|
||||
char upper = toupper(signame[i]);
|
||||
signame[i] = upper;
|
||||
}
|
||||
fprintf(fp, "%s%c", signame, separator);
|
||||
|
||||
free(signame);
|
||||
}
|
||||
|
||||
static int
|
||||
signame_to_signum(const char *sig)
|
||||
{
|
||||
@ -188,11 +206,10 @@ printsignals(FILE *fp)
|
||||
int n;
|
||||
|
||||
for (n = 1; n < sys_nsig; n++) {
|
||||
(void)fprintf(fp, "%s", sys_signame[n]);
|
||||
char sep = ' ';
|
||||
if (n == (sys_nsig / 2) || n == (sys_nsig - 1))
|
||||
(void)fprintf(fp, "\n");
|
||||
else
|
||||
(void)fprintf(fp, " ");
|
||||
sep = '\n';
|
||||
print_signum(n, fp, sep);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
.\" 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.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
@ -29,9 +29,9 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)printf.1 8.1 (Berkeley) 6/6/93
|
||||
.\" $FreeBSD: head/usr.bin/printf/printf.1 264743 2014-04-21 22:47:18Z pfg $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 21, 2014
|
||||
.Dd July 1, 2020
|
||||
.Dt PRINTF 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -87,8 +87,6 @@ are as follows:
|
||||
Write a <bell> character.
|
||||
.It Cm \eb
|
||||
Write a <backspace> character.
|
||||
.It Cm \ec
|
||||
Ignore remaining characters in this string.
|
||||
.It Cm \ef
|
||||
Write a <form-feed> character.
|
||||
.It Cm \en
|
||||
@ -289,7 +287,12 @@ The permitted escape sequences are slightly different in that
|
||||
octal escapes are
|
||||
.Cm \e0 Ns Ar num
|
||||
instead of
|
||||
.Cm \e Ns Ar num .
|
||||
.Cm \e Ns Ar num
|
||||
and that an additional escape sequence
|
||||
.Cm \ec
|
||||
stops further output from this
|
||||
.Nm
|
||||
invocation.
|
||||
.It Cm n$
|
||||
Allows reordering of the output according to
|
||||
.Ar argument .
|
||||
@ -313,12 +316,48 @@ Consult the
|
||||
manual page.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh EXAMPLES
|
||||
Print the string
|
||||
.Qq hello :
|
||||
.Bd -literal -offset indent
|
||||
$ printf "%s\en" hello
|
||||
hello
|
||||
.Ed
|
||||
.Pp
|
||||
Same as above, but notice that the format string is not quoted and hence we
|
||||
do not get the expected behavior:
|
||||
.Bd -literal -offset indent
|
||||
$ printf %s\en hello
|
||||
hellon$
|
||||
.Ed
|
||||
.Pp
|
||||
Print arguments forcing sign only for the first argument:
|
||||
.Bd -literal -offset indent
|
||||
$ printf "%+d\en%d\en%d\en" 1 -2 13
|
||||
+1
|
||||
-2
|
||||
13
|
||||
.Ed
|
||||
.Pp
|
||||
Same as above, but the single format string will be applied to the three
|
||||
arguments:
|
||||
.Bd -literal -offset indent
|
||||
$ printf "%+d\en" 1 -2 13
|
||||
+1
|
||||
-2
|
||||
+13
|
||||
.Ed
|
||||
.Pp
|
||||
Print number using only two digits after the decimal point:
|
||||
.Bd -literal -offset indent
|
||||
$ printf "%.2f\en" 31.7456
|
||||
31.75
|
||||
.Ed
|
||||
.Sh COMPATIBILITY
|
||||
The traditional
|
||||
.Bx
|
||||
behavior of converting arguments of numeric formats not beginning
|
||||
with a digit to the
|
||||
.Tn ASCII
|
||||
with a digit to the ASCII
|
||||
code of the first character is not supported.
|
||||
.Sh SEE ALSO
|
||||
.Xr builtin 1 ,
|
||||
@ -340,8 +379,7 @@ It is modeled
|
||||
after the standard library function,
|
||||
.Xr printf 3 .
|
||||
.Sh CAVEATS
|
||||
.Tn ANSI
|
||||
hexadecimal character constants were deliberately not provided.
|
||||
ANSI hexadecimal character constants were deliberately not provided.
|
||||
.Pp
|
||||
Trying to print a dash ("-") as the first character causes
|
||||
.Nm
|
||||
@ -361,10 +399,8 @@ and
|
||||
formats with a precision
|
||||
may not operate as expected.
|
||||
.Sh BUGS
|
||||
Since the floating point numbers are translated from
|
||||
.Tn ASCII
|
||||
to floating-point and
|
||||
then back again, floating-point precision may be lost.
|
||||
Since the floating point numbers are translated from ASCII
|
||||
to floating-point and then back again, floating-point precision may be lost.
|
||||
(By default, the number is translated to an IEEE-754 double-precision
|
||||
value before being printed.
|
||||
The
|
||||
|
@ -1,4 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
|
||||
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -12,7 +15,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. 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.
|
||||
*
|
||||
@ -46,7 +49,7 @@ static char const copyright[] =
|
||||
static char const sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD: head/usr.bin/printf/printf.c 279503 2015-03-01 21:46:55Z jilles $";
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -70,20 +73,15 @@ static const char rcsid[] =
|
||||
#endif
|
||||
|
||||
#define PF(f, func) do { \
|
||||
char *b = NULL; \
|
||||
if (havewidth) \
|
||||
if (haveprec) \
|
||||
(void)asprintf(&b, f, fieldwidth, precision, func); \
|
||||
(void)printf(f, fieldwidth, precision, func); \
|
||||
else \
|
||||
(void)asprintf(&b, f, fieldwidth, func); \
|
||||
(void)printf(f, fieldwidth, func); \
|
||||
else if (haveprec) \
|
||||
(void)asprintf(&b, f, precision, func); \
|
||||
(void)printf(f, precision, func); \
|
||||
else \
|
||||
(void)asprintf(&b, f, func); \
|
||||
if (b) { \
|
||||
(void)fputs(b, stdout); \
|
||||
free(b); \
|
||||
} \
|
||||
(void)printf(f, func); \
|
||||
} while (0)
|
||||
|
||||
static int asciicode(void);
|
||||
@ -378,13 +376,25 @@ printf_doformat(char *fmt, int *rval)
|
||||
char *p;
|
||||
int getout;
|
||||
|
||||
p = strdup(getstr());
|
||||
if (p == NULL) {
|
||||
/* Convert "b" to "s" for output. */
|
||||
start[strlen(start) - 1] = 's';
|
||||
if ((p = strdup(getstr())) == NULL) {
|
||||
warnx("%s", strerror(ENOMEM));
|
||||
return (NULL);
|
||||
}
|
||||
getout = escape(p, 0, &len);
|
||||
fputs(p, stdout);
|
||||
/*
|
||||
* Special-case conversion of zero; print it instead of
|
||||
* feeding an empty string to printf("%s") which would not
|
||||
* print anything.
|
||||
*/
|
||||
if (len == 1 && p[0] == '\0') {
|
||||
putchar(p[0]);
|
||||
} else {
|
||||
PF(start, p);
|
||||
}
|
||||
/* Restore format for next loop. */
|
||||
|
||||
free(p);
|
||||
if (getout)
|
||||
return (end_fmt);
|
||||
@ -394,7 +404,8 @@ printf_doformat(char *fmt, int *rval)
|
||||
char p;
|
||||
|
||||
p = getchr();
|
||||
PF(start, p);
|
||||
if (p != '\0')
|
||||
PF(start, p);
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
|
@ -2,15 +2,16 @@
|
||||
<key>OpenSourceProject</key>
|
||||
<string>printf</string>
|
||||
<key>OpenSourceVersion</key>
|
||||
<string>2015-03-01</string>
|
||||
<string>2020-07-01</string>
|
||||
<key>OpenSourceWebsiteURL</key>
|
||||
<string>http://svnweb.freebsd.org/base/head/usr.bin/printf/</string>
|
||||
<string>https://github.com/freebsd/freebsd/tree/master/usr.bin/printf</string>
|
||||
<key>OpenSourceSCM</key>
|
||||
<string>svn co http://svn.freebsd.org/base/head/usr.bin/printf/</string>
|
||||
<string>https://github.com/freebsd/freebsd/tree/master/usr.bin/printf</string>
|
||||
<key>OpenSourceImportDate</key>
|
||||
<string>2015-07-23</string>
|
||||
<string>2020-07-23</string>
|
||||
<key>OpenSourceModifications</key>
|
||||
<array>
|
||||
<string>65959587: UNIX Conformance | /usr/bin/printf, multiple format assertion failures in VSC</string>
|
||||
</array>
|
||||
<key>OpenSourceLicense</key>
|
||||
<string>bsd</string>
|
||||
|
@ -1,10 +1,11 @@
|
||||
# $FreeBSD: head/usr.bin/printf/tests/Makefile 299094 2016-05-04 23:20:53Z ngie $
|
||||
# $FreeBSD$
|
||||
|
||||
PACKAGE= tests
|
||||
|
||||
TAP_TESTS_SH= legacy_test
|
||||
|
||||
${PACKAGE}FILES+= regress.b.out
|
||||
${PACKAGE}FILES+= regress.bwidth.out
|
||||
${PACKAGE}FILES+= regress.d.out
|
||||
${PACKAGE}FILES+= regress.f.out
|
||||
${PACKAGE}FILES+= regress.l1.out
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $FreeBSD: head/usr.bin/printf/tests/Makefile.depend 296587 2016-03-09 22:46:01Z bdrewery $
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# $FreeBSD: head/usr.bin/printf/tests/legacy_test.sh 263227 2014-03-16 08:04:06Z jmmv $
|
||||
# $FreeBSD$
|
||||
|
||||
SRCDIR="$(dirname "${0}")"; export SRCDIR
|
||||
|
||||
|
1
printf/tests/regress.bwidth.out
Normal file
1
printf/tests/regress.bwidth.out
Normal file
@ -0,0 +1 @@
|
||||
a
|
@ -1,10 +1,8 @@
|
||||
# $FreeBSD: head/usr.bin/printf/tests/regress.sh 266854 2014-05-29 19:48:18Z pfg $
|
||||
|
||||
enable -n printf
|
||||
# $FreeBSD$
|
||||
|
||||
REGRESSION_START($1)
|
||||
|
||||
echo '1..23'
|
||||
echo '1..24'
|
||||
|
||||
REGRESSION_TEST(`b', `printf "abc%b%b" "def\n" "\cghi"')
|
||||
REGRESSION_TEST(`d', `printf "%d,%5d,%.5d,%0*d,%.*d\n" 123 123 123 5 123 5 123')
|
||||
@ -29,5 +27,6 @@ REGRESSION_TEST(`missingpos1', `printf "%*.*1\$s" 1 1 1 2>&1')
|
||||
REGRESSION_TEST(`missingpos1', `printf "%1\$*2\$.*s" 1 1 1 2>&1')
|
||||
REGRESSION_TEST(`missingpos1', `printf "%*1\$.*2\$s" 1 1 1 2>&1')
|
||||
REGRESSION_TEST(`missingpos1', `printf "%1\$*.*2\$s" 1 1 1 2>&1')
|
||||
REGRESSION_TEST(`bwidth', `printf "%8.2b" "a\nb\n"')
|
||||
|
||||
REGRESSION_END()
|
||||
|
@ -1542,9 +1542,14 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
6C1C283E22FB822900E0AC67 /* su_entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = su_entitlements.plist; sourceTree = "<group>"; };
|
||||
C6868576154725700025D623 /* systime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = systime; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C6868579154725700025D623 /* systime.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = systime.c; sourceTree = "<group>"; };
|
||||
C686857B154725700025D623 /* systime.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = systime.1; sourceTree = "<group>"; };
|
||||
CE799E6024AD3B1B00E73238 /* test_time.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = test_time.sh; sourceTree = "<group>"; usesTabs = 1; };
|
||||
CE799E6224B3982200E73238 /* install-files.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-files.sh"; sourceTree = "<group>"; };
|
||||
CE799E6324B3982200E73238 /* builtins.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = builtins.txt; sourceTree = "<group>"; };
|
||||
CE799E6424B3982200E73238 /* builtins-manpages.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "builtins-manpages.txt"; sourceTree = "<group>"; };
|
||||
FC5D636814B9808E00123E48 /* conv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = conv.c; sourceTree = "<group>"; };
|
||||
FC5D636914B9808E00123E48 /* display.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = display.c; sourceTree = "<group>"; };
|
||||
FC5D636A14B9808E00123E48 /* hexdump.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = hexdump.1; sourceTree = "<group>"; };
|
||||
@ -1660,7 +1665,7 @@
|
||||
FCBA13FA14A141A300AA698B /* test.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = test.1; sourceTree = "<group>"; };
|
||||
FCBA13FB14A141A300AA698B /* test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = test.c; sourceTree = "<group>"; };
|
||||
FCBA13FF14A141A300AA698B /* time.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = time.1; sourceTree = "<group>"; };
|
||||
FCBA140014A141A300AA698B /* time.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = time.c; sourceTree = "<group>"; };
|
||||
FCBA140014A141A300AA698B /* time.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = time.c; sourceTree = "<group>"; usesTabs = 1; };
|
||||
FCBA140314A141A300AA698B /* true.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = true.1; sourceTree = "<group>"; };
|
||||
FCBA140414A141A300AA698B /* true.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = true.c; sourceTree = "<group>"; };
|
||||
FCBA140814A141A300AA698B /* uname.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = uname.1; sourceTree = "<group>"; };
|
||||
@ -2193,6 +2198,24 @@
|
||||
path = systime;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CE799E5F24AD3B1B00E73238 /* tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE799E6024AD3B1B00E73238 /* test_time.sh */,
|
||||
);
|
||||
path = tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CE799E6124B3982200E73238 /* xcodescripts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE799E6224B3982200E73238 /* install-files.sh */,
|
||||
CE799E6324B3982200E73238 /* builtins.txt */,
|
||||
CE799E6424B3982200E73238 /* builtins-manpages.txt */,
|
||||
);
|
||||
path = xcodescripts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FC5D636714B9808E00123E48 /* hexdump */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2221,6 +2244,7 @@
|
||||
FC80BF5514A05A2F00C6F7F5 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE799E6124B3982200E73238 /* xcodescripts */,
|
||||
FD60612F1B7D2DDE004BCA6A /* xcconfigs */,
|
||||
FCBA134014A141A300AA698B /* alias */,
|
||||
FCBA134514A141A300AA698B /* apply */,
|
||||
@ -2679,6 +2703,7 @@
|
||||
FCBA13EE14A141A300AA698B /* su */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6C1C283E22FB822900E0AC67 /* su_entitlements.plist */,
|
||||
FCBA13F014A141A300AA698B /* su.1 */,
|
||||
FCBA13F114A141A300AA698B /* su.c */,
|
||||
FCBA13F214A141A300AA698B /* su.pam */,
|
||||
@ -2710,6 +2735,7 @@
|
||||
FCBA13FD14A141A300AA698B /* time */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE799E5F24AD3B1B00E73238 /* tests */,
|
||||
FCBA13FF14A141A300AA698B /* time.1 */,
|
||||
FCBA140014A141A300AA698B /* time.c */,
|
||||
);
|
||||
@ -3904,7 +3930,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-files.sh";
|
||||
shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-files.sh\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FCE30F4D14B619C900CC0294 /* Run Script */ = {
|
||||
@ -3919,7 +3945,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-files.sh";
|
||||
shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-files.sh\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FD6060EF1B7C0590004BCA6A /* mkbuiltins */ = {
|
||||
@ -3957,7 +3983,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "env -i xcrun -sdk macosx cc ${SRCROOT}/sh/mknodes.c -o ${DERIVED_FILE_DIR}/mknodes\ncd ${BUILT_PRODUCTS_DIR} && ${DERIVED_FILE_DIR}/mknodes ${SRCROOT}/sh/nodetypes ${SRCROOT}/sh/nodes.c.pat";
|
||||
shellScript = "mkdir -p ${DERIVED_FILE_DIR}\nenv -i xcrun -sdk macosx cc ${SRCROOT}/sh/mknodes.c -o ${DERIVED_FILE_DIR}/mknodes\ncd ${BUILT_PRODUCTS_DIR} && ${DERIVED_FILE_DIR}/mknodes ${SRCROOT}/sh/nodetypes ${SRCROOT}/sh/nodes.c.pat\n";
|
||||
};
|
||||
FD6060F21B7C0744004BCA6A /* mksyntax */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@ -5296,6 +5322,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = su/su_entitlements.plist;
|
||||
INSTALL_MODE_FLAG = "u+s,u+w,go-w,a+rX";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
|
10
su/su_entitlements.plist
Normal file
10
su/su_entitlements.plist
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.keystore.console</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.clear-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -12,10 +12,8 @@
|
||||
<string>/bin/sh</string>
|
||||
<string>/AppleInternal/Tests/shell_cmds/printf/legacy_test.sh</string>
|
||||
</array>
|
||||
<key>IgnoreOutput</key>
|
||||
<true/>
|
||||
<key>TestName</key>
|
||||
<string>shell_cmds: printf</string>
|
||||
<key>IgnoreOutput</key><true/>
|
||||
<key>TestName</key><string>shell_cmds.printf</string>
|
||||
<key>WhenToRun</key>
|
||||
<array>
|
||||
<string>PRESUBMISSION</string>
|
||||
@ -28,8 +26,20 @@
|
||||
<string>/bin/sh</string>
|
||||
<string>/AppleInternal/Tests/shell_cmds/test/legacy_test.sh</string>
|
||||
</array>
|
||||
<key>TestName</key>
|
||||
<string>shell_cmds: test</string>
|
||||
<key>TestName</key><string>shell_cmds.test</string>
|
||||
<key>WhenToRun</key>
|
||||
<array>
|
||||
<string>PRESUBMISSION</string>
|
||||
<string>NIGHTLY</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Command</key>
|
||||
<array>
|
||||
<string>/bin/sh</string>
|
||||
<string>/AppleInternal/Tests/shell_cmds/time/test_time.sh</string>
|
||||
</array>
|
||||
<key>TestName</key><string>shell_cmds.time</string>
|
||||
<key>WhenToRun</key>
|
||||
<array>
|
||||
<string>PRESUBMISSION</string>
|
||||
|
60
time/tests/test_time.sh
Executable file
60
time/tests/test_time.sh
Executable file
@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -o nounset
|
||||
|
||||
TIME="${TIME-/usr/bin/time}"
|
||||
echo "SUITE: time(1)"
|
||||
what $TIME
|
||||
echo
|
||||
|
||||
EXIT=0
|
||||
|
||||
echo TEST: check real time
|
||||
|
||||
TIME_SLEEP=`$TIME 2>&1 sleep 1 | sed -n -E 's/[ ]+([0-9]+).*/\1/p'`
|
||||
TIME_STATUS=$?
|
||||
|
||||
if [ "$TIME_STATUS" -ne "0" ]; then
|
||||
echo FAIL: time failed with "$TIME_STATUS"
|
||||
EXIT=1
|
||||
fi
|
||||
|
||||
if [ "$TIME_SLEEP" -lt "0" ]; then
|
||||
echo FAIL: time mis-timed sleep
|
||||
EXIT=2
|
||||
fi
|
||||
|
||||
MONOTONIC=`sysctl -n kern.monotonic.task_thread_counting`
|
||||
if [ "$MONOTONIC" -ne "0" ]; then
|
||||
echo TEST: check instructions retired
|
||||
|
||||
TIME_INSTRS=`$TIME -l 2>&1 sleep 1 | sed -E -n '/instructions/p'`
|
||||
if [ -z "$TIME_INSTRS" ]; then
|
||||
echo FAIL: time is not showing instructions retired
|
||||
EXIT=3
|
||||
fi
|
||||
else
|
||||
echo SKIP: check instructions retired
|
||||
fi
|
||||
|
||||
# NB: SIGINT and SIGQUIT work locally, but the automated test harnesses tries to
|
||||
# handle those signals itself before the fork.
|
||||
|
||||
echo TEST: check child SIGUSR1
|
||||
|
||||
TIME_USR1=`$TIME 2>&1 sh -c 'kill -USR1 $$ && sleep 5 && true'`
|
||||
TIME_STATUS=$?
|
||||
if [ "$TIME_STATUS" -eq "0" ]; then
|
||||
echo FAIL: time should allow child to receive SIGUSR1
|
||||
EXIT=4
|
||||
fi
|
||||
|
||||
echo TEST: check non-existent binary
|
||||
TIME_NONEXIST=`$TIME 2>&1 ./this-wont-exist`
|
||||
TIME_STATUS=$?
|
||||
if [ "$TIME_STATUS" -ne "127" ]; then
|
||||
echo FAIL: time should error when measuring a non-existent command
|
||||
EXIT=5
|
||||
fi
|
||||
|
||||
exit $EXIT
|
@ -114,7 +114,3 @@ The
|
||||
.Nm
|
||||
utility conforms to
|
||||
.St -p1003.2-92 .
|
||||
.Sh BUGS
|
||||
The granularity of seconds on microprocessors is crude and
|
||||
can result in times being reported for CPU usage which are too large by
|
||||
a second.
|
||||
|
189
time/time.c
189
time/time.c
@ -33,52 +33,48 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <inttypes.h>
|
||||
#include <langinfo.h>
|
||||
#include <libproc.h>
|
||||
#include <locale.h>
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1987, 1988, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
__RCSID("$NetBSD: time.c,v 1.9 1997/10/20 03:28:21 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sysexits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
|
||||
int lflag;
|
||||
int portableflag;
|
||||
bool child_running = true;
|
||||
|
||||
int main __P((int, char **));
|
||||
void
|
||||
child_handler(int sig)
|
||||
{
|
||||
child_running = false;
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int pid;
|
||||
int ch, status;
|
||||
struct timeval before, after;
|
||||
int ch, status, rusage_ret = -1;
|
||||
uint64_t before_ns, after_ns, duration_ns, duration_secs, duration_frac_ns;
|
||||
struct rusage ru;
|
||||
char * radix = NULL;
|
||||
struct rusage_info_v4 ruinfo;
|
||||
sigset_t sigmask, suspmask, origmask;
|
||||
|
||||
#ifdef __GNUC__ /* XXX: borken gcc */
|
||||
(void)&argv;
|
||||
#endif
|
||||
lflag = 0;
|
||||
while ((ch = getopt(argc, argv, "lp")) != -1)
|
||||
while ((ch = getopt(argc, argv, "lp")) != -1) {
|
||||
switch((char)ch) {
|
||||
case 'p':
|
||||
portableflag = 1;
|
||||
@ -88,37 +84,88 @@ main(argc, argv)
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
fprintf(stderr, "usage: time [-lp] command.\n");
|
||||
fprintf(stderr, "usage: time [-lp] <command>\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(argc -= optind))
|
||||
if (!(argc -= optind)) {
|
||||
exit(0);
|
||||
}
|
||||
argv += optind;
|
||||
|
||||
gettimeofday(&before, (struct timezone *)NULL);
|
||||
switch(pid = vfork()) {
|
||||
case -1: /* error */
|
||||
perror("time");
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
case 0: /* child */
|
||||
sigemptyset(&sigmask);
|
||||
/*
|
||||
* Block SIGCHLD so that the check for `child_running` doesn't miss the
|
||||
* handler before calling `sigsuspend` and blocking forever.
|
||||
*/
|
||||
sigaddset(&sigmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &sigmask, &origmask);
|
||||
|
||||
/*
|
||||
* Ensure child signals are handled by the parent prior to fork; otherwise,
|
||||
* they could be missed between the child forking and calling `sigsuspend`.
|
||||
*/
|
||||
(void)signal(SIGCHLD, child_handler);
|
||||
|
||||
sigemptyset(&suspmask);
|
||||
|
||||
before_ns = clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
|
||||
/*
|
||||
* NB: Don't add anything between these two lines -- measurement is
|
||||
* happening now.
|
||||
*/
|
||||
switch (pid = vfork()) {
|
||||
case -1: /* error */
|
||||
err(EX_OSERR, "time");
|
||||
__builtin_unreachable();
|
||||
case 0: /* child */
|
||||
/*
|
||||
* Allow the child to respond to signals by resetting to the original
|
||||
* signal handling behavior.
|
||||
*/
|
||||
(void)sigprocmask(SIG_SETMASK, &origmask, NULL);
|
||||
execvp(*argv, argv);
|
||||
perror(*argv);
|
||||
_exit((errno == ENOENT) ? 127 : 126);
|
||||
/* NOTREACHED */
|
||||
__builtin_unreachable();
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
|
||||
/* parent */
|
||||
/*
|
||||
* Let the child handle signals that normally exit.
|
||||
*/
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
while (wait3(&status, 0, &ru) != pid);
|
||||
gettimeofday(&after, (struct timezone *)NULL);
|
||||
if (!WIFEXITED(status))
|
||||
|
||||
while (child_running) {
|
||||
/*
|
||||
* This would be racy, but SIGCHLD is blocked above (as part of
|
||||
* `sigmask`.
|
||||
*/
|
||||
sigsuspend(&suspmask);
|
||||
}
|
||||
/*
|
||||
* NB: Minimize what's added between these statements to preserve the
|
||||
* accuracy of the time measurement.
|
||||
*/
|
||||
after_ns = clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
|
||||
if (lflag) {
|
||||
rusage_ret = proc_pid_rusage(pid, RUSAGE_INFO_V4, (void **)&ruinfo);
|
||||
}
|
||||
while (wait3(&status, 0, &ru) != pid) {
|
||||
}
|
||||
if (!WIFEXITED(status)) {
|
||||
fprintf(stderr, "Command terminated abnormally.\n");
|
||||
timersub(&after, &before, &after);
|
||||
}
|
||||
duration_ns = after_ns - before_ns;
|
||||
duration_secs = duration_ns / (1000 * 1000 * 1000);
|
||||
duration_frac_ns = duration_ns - (duration_secs * 1000 * 1000 * 1000);
|
||||
|
||||
if (portableflag) {
|
||||
char *radix = NULL;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
radix = nl_langinfo(RADIXCHAR);
|
||||
@ -126,15 +173,15 @@ main(argc, argv)
|
||||
radix = ".";
|
||||
}
|
||||
|
||||
fprintf (stderr, "real %9ld%s%02ld\n",
|
||||
(long)after.tv_sec, radix, (long)after.tv_usec/10000);
|
||||
fprintf (stderr, "user %9ld%s%02ld\n",
|
||||
fprintf(stderr, "real %9" PRIu64 "%s%02" PRIu64 "\n",
|
||||
duration_secs, radix, duration_frac_ns / (10 * 1000 * 1000));
|
||||
fprintf(stderr, "user %9ld%s%02ld\n",
|
||||
(long)ru.ru_utime.tv_sec, radix, (long)ru.ru_utime.tv_usec/10000);
|
||||
fprintf (stderr, "sys %9ld%s%02ld\n",
|
||||
fprintf(stderr, "sys %9ld%s%02ld\n",
|
||||
(long)ru.ru_stime.tv_sec, radix, (long)ru.ru_stime.tv_usec/10000);
|
||||
} else {
|
||||
fprintf(stderr, "%9ld.%02ld real ",
|
||||
(long)after.tv_sec, (long)after.tv_usec/10000);
|
||||
fprintf(stderr, "%9" PRIu64 ".%02" PRIu64 " real ",
|
||||
duration_secs, duration_frac_ns / (10 * 1000 * 1000));
|
||||
fprintf(stderr, "%9ld.%02ld user ",
|
||||
(long)ru.ru_utime.tv_sec, (long)ru.ru_utime.tv_usec/10000);
|
||||
fprintf(stderr, "%9ld.%02ld sys\n",
|
||||
@ -142,41 +189,57 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
if (lflag) {
|
||||
int hz = 100; /* XXX */
|
||||
int hz = 100; /* XXX */
|
||||
long ticks;
|
||||
|
||||
ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) +
|
||||
hz * (ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000000;
|
||||
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_maxrss, "maximum resident set size");
|
||||
fprintf(stderr, "%10ld %s\n", ticks ? ru.ru_ixrss / ticks : 0,
|
||||
fprintf(stderr, "%20ld %s\n", ticks ? ru.ru_ixrss / ticks : 0,
|
||||
"average shared memory size");
|
||||
fprintf(stderr, "%10ld %s\n", ticks ? ru.ru_idrss / ticks : 0,
|
||||
fprintf(stderr, "%20ld %s\n", ticks ? ru.ru_idrss / ticks : 0,
|
||||
"average unshared data size");
|
||||
fprintf(stderr, "%10ld %s\n", ticks ? ru.ru_isrss / ticks : 0,
|
||||
fprintf(stderr, "%20ld %s\n", ticks ? ru.ru_isrss / ticks : 0,
|
||||
"average unshared stack size");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_minflt, "page reclaims");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_majflt, "page faults");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_nswap, "swaps");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_inblock, "block input operations");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_oublock, "block output operations");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_msgsnd, "messages sent");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_msgrcv, "messages received");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_nsignals, "signals received");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_nvcsw, "voluntary context switches");
|
||||
fprintf(stderr, "%10ld %s\n",
|
||||
fprintf(stderr, "%20ld %s\n",
|
||||
ru.ru_nivcsw, "involuntary context switches");
|
||||
|
||||
if (rusage_ret >= 0) {
|
||||
if (ruinfo.ri_instructions > 0) {
|
||||
fprintf(stderr, "%20" PRIu64 " %s\n", ruinfo.ri_instructions,
|
||||
"instructions retired");
|
||||
}
|
||||
if (ruinfo.ri_cycles > 0) {
|
||||
fprintf(stderr, "%20" PRIu64 " %s\n", ruinfo.ri_cycles,
|
||||
"cycles elapsed");
|
||||
}
|
||||
if (ruinfo.ri_lifetime_max_phys_footprint > 0) {
|
||||
fprintf(stderr, "%20" PRIu64 " %s\n",
|
||||
ruinfo.ri_lifetime_max_phys_footprint,
|
||||
"peak memory footprint");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit (WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE);
|
||||
exit(WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -10,11 +12,7 @@
|
||||
* 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
|
||||
* 3. 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.
|
||||
*
|
||||
@ -30,6 +28,8 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
|
@ -36,7 +36,19 @@ strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
|
||||
s1 = *str;
|
||||
if (s1 == NULL)
|
||||
return;
|
||||
s2 = calloc(maxsize, 1);
|
||||
/*
|
||||
* If maxsize is 0 then set it to the length of s1, because we have
|
||||
* to duplicate s1. XXX we maybe should double-check whether the match
|
||||
* appears in s1. If it doesn't, then we also have to set the length
|
||||
* to the length of s1, to avoid modifying the argument. It may make
|
||||
* sense to check if maxsize is <= strlen(s1), because in that case we
|
||||
* want to return the unmodified string, too.
|
||||
*/
|
||||
if (maxsize == 0) {
|
||||
match = NULL;
|
||||
maxsize = strlen(s1) + 1;
|
||||
}
|
||||
s2 = calloc(1, maxsize);
|
||||
if (s2 == NULL)
|
||||
err(1, "calloc");
|
||||
|
||||
|
@ -13,11 +13,7 @@
|
||||
.\" 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
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
@ -37,7 +33,7 @@
|
||||
.\" $FreeBSD: src/usr.bin/xargs/xargs.1,v 1.34 2005/05/21 09:55:09 ru Exp $
|
||||
.\" $xMach: xargs.1,v 1.2 2002/02/23 05:23:37 tim Exp $
|
||||
.\"
|
||||
.Dd August 2, 2004
|
||||
.Dd August 4, 2015
|
||||
.Dt XARGS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -45,11 +41,12 @@
|
||||
.Nd "construct argument list(s) and execute utility"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 0opt
|
||||
.Op Fl 0oprt
|
||||
.Op Fl E Ar eofstr
|
||||
.Oo
|
||||
.Fl I Ar replstr
|
||||
.Op Fl R Ar replacements
|
||||
.Op Fl S Ar replsize
|
||||
.Oc
|
||||
.Op Fl J Ar replstr
|
||||
.Op Fl L Ar number
|
||||
@ -74,8 +71,7 @@ Any arguments specified on the command line are given to
|
||||
upon each invocation, followed by some number of the arguments read
|
||||
from the standard input of
|
||||
.Nm .
|
||||
The utility
|
||||
is repeatedly executed until standard input is exhausted.
|
||||
This is repeated until standard input is exhausted.
|
||||
.Pp
|
||||
Spaces, tabs and newlines may be embedded in arguments using single
|
||||
(``\ '\ '')
|
||||
@ -115,13 +111,20 @@ flag is specified) arguments to
|
||||
.Ar utility
|
||||
with the entire line of input.
|
||||
The resulting arguments, after replacement is done, will not be allowed to grow
|
||||
beyond 255 bytes; this is implemented by concatenating as much of the argument
|
||||
beyond
|
||||
.Ar replsize
|
||||
(or 255 if no
|
||||
.Fl S
|
||||
flag is specified)
|
||||
bytes; this is implemented by concatenating as much of the argument
|
||||
containing
|
||||
.Ar replstr
|
||||
as possible, to the constructed arguments to
|
||||
.Ar utility ,
|
||||
up to 255 bytes.
|
||||
The 255 byte limit does not apply to arguments to
|
||||
up to
|
||||
.Ar replsize
|
||||
bytes.
|
||||
The size limit does not apply to arguments to
|
||||
.Ar utility
|
||||
which do not contain
|
||||
.Ar replstr ,
|
||||
@ -160,8 +163,7 @@ directories which start with an uppercase letter in the current
|
||||
directory to
|
||||
.Pa destdir :
|
||||
.Pp
|
||||
.Dl /bin/ls -1d [A-Z]* | xargs -J % cp -rp % destdir
|
||||
.Pp
|
||||
.Dl /bin/ls -1d [A-Z]* | xargs -J % cp -Rp % destdir
|
||||
.It Fl L Ar number
|
||||
Call
|
||||
.Ar utility
|
||||
@ -211,6 +213,11 @@ Parallel mode: run at most
|
||||
invocations of
|
||||
.Ar utility
|
||||
at once.
|
||||
If
|
||||
.Ar maxprocs
|
||||
is set to 0,
|
||||
.Nm
|
||||
will run as many processes as possible.
|
||||
.It Fl p
|
||||
Echo each command to be executed and ask the user whether it should be
|
||||
executed.
|
||||
@ -220,6 +227,34 @@ in the POSIX locale,
|
||||
causes the command to be executed, any other response causes it to be
|
||||
skipped.
|
||||
No commands are executed if the process is not attached to a terminal.
|
||||
.It Fl r
|
||||
Compatibility with GNU
|
||||
.Nm .
|
||||
The GNU version of
|
||||
.Nm
|
||||
runs the
|
||||
.Ar utility
|
||||
argument at least once, even if
|
||||
.Nm
|
||||
input is empty, and it supports a
|
||||
.Fl r
|
||||
option to inhibit this behavior.
|
||||
The
|
||||
.Fx
|
||||
version of
|
||||
.Nm
|
||||
does not run the
|
||||
.Ar utility
|
||||
argument on empty input, but it supports the
|
||||
.Fl r
|
||||
option for command-line compatibility with GNU
|
||||
.Nm ,
|
||||
but the
|
||||
.Fl r
|
||||
option does nothing in the
|
||||
.Fx
|
||||
version of
|
||||
.Nm .
|
||||
.It Fl R Ar replacements
|
||||
Specify the maximum number of arguments that
|
||||
.Fl I
|
||||
@ -227,6 +262,13 @@ will do replacement in.
|
||||
If
|
||||
.Ar replacements
|
||||
is negative, the number of arguments in which to replace is unbounded.
|
||||
.It Fl S Ar replsize
|
||||
Specify the amount of space (in bytes) that
|
||||
.Fl I
|
||||
can use for replacements.
|
||||
The default for
|
||||
.Ar replsize
|
||||
is 255.
|
||||
.It Fl s Ar size
|
||||
Set the maximum number of bytes for the command line length provided to
|
||||
.Ar utility .
|
||||
@ -272,7 +314,11 @@ cannot be invoked, an invocation of
|
||||
is terminated by a signal,
|
||||
or an invocation of
|
||||
.Ar utility
|
||||
exits with a value of 255.
|
||||
exits with a value of 255, the
|
||||
.Nm
|
||||
utility stops processing input and exits after all invocations of
|
||||
.Ar utility
|
||||
finish processing.
|
||||
.Sh LEGACY DESCRIPTION
|
||||
In legacy mode, the
|
||||
.Fl L
|
||||
@ -314,16 +360,16 @@ utility is expected to be
|
||||
.St -p1003.2
|
||||
compliant.
|
||||
The
|
||||
.Fl J , o , P
|
||||
.Fl J , o , P, R
|
||||
and
|
||||
.Fl R
|
||||
.Fl S
|
||||
options are non-standard
|
||||
.Fx
|
||||
extensions which may not be available on other operating systems.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in PWB UNIX.
|
||||
utility appeared in PWB UNIX.
|
||||
.Sh BUGS
|
||||
If
|
||||
.Ar utility
|
||||
|
308
xargs/xargs.c
308
xargs/xargs.c
@ -1,4 +1,6 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -13,11 +15,7 @@
|
||||
* 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
|
||||
* 3. 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.
|
||||
*
|
||||
@ -48,11 +46,13 @@ static char sccsid[] = "@(#)xargs.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/usr.bin/xargs/xargs.c,v 1.57 2005/02/27 02:01:31 gad Exp $");
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/resource.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -79,7 +79,17 @@ static int prompt(void);
|
||||
static void run(char **);
|
||||
static void usage(void);
|
||||
void strnsubst(char **, const char *, const char *, size_t);
|
||||
static pid_t xwait(int block, int *status);
|
||||
static void xexit(const char *, const int);
|
||||
static void waitchildren(const char *, int);
|
||||
static void pids_init(void);
|
||||
static int pids_empty(void);
|
||||
static int pids_full(void);
|
||||
static void pids_add(pid_t pid);
|
||||
static int pids_remove(pid_t pid);
|
||||
static int findslot(pid_t pid);
|
||||
static int findfreeslot(void);
|
||||
static void clearslot(int slot);
|
||||
|
||||
static int last_was_newline = 1;
|
||||
static int last_was_blank = 0;
|
||||
@ -89,9 +99,10 @@ static char **av, **bxp, **ep, **endxp, **xp;
|
||||
static char *argp, *bbp, *ebp, *inpline, *p, *replstr;
|
||||
static const char *eofstr;
|
||||
static int count, insingle, indouble, oflag, pflag, tflag, Rflag, rval, zflag;
|
||||
static int cnt, Iflag, jfound, Lflag, wasquoted, xflag;
|
||||
static int cnt, Iflag, jfound, Lflag, Sflag, wasquoted, xflag;
|
||||
static int curprocs, maxprocs;
|
||||
static size_t pad9314053;
|
||||
static pid_t *childpids;
|
||||
|
||||
static volatile int childerr;
|
||||
|
||||
@ -104,7 +115,9 @@ main(int argc, char *argv[])
|
||||
int ch, Jflag, nflag, nline;
|
||||
size_t nargs;
|
||||
size_t linelen;
|
||||
struct rlimit rl;
|
||||
char *endptr;
|
||||
const char *errstr;
|
||||
|
||||
inpline = replstr = NULL;
|
||||
ep = environ;
|
||||
@ -137,8 +150,8 @@ main(int argc, char *argv[])
|
||||
}
|
||||
nline -= pad9314053;
|
||||
maxprocs = 1;
|
||||
while ((ch = getopt(argc, argv, "0E:I:J:L:n:oP:pR:s:tx")) != -1)
|
||||
switch(ch) {
|
||||
while ((ch = getopt(argc, argv, "0E:I:J:L:n:oP:pR:S:s:rtx")) != -1)
|
||||
switch (ch) {
|
||||
case 'E':
|
||||
eofstr = optarg;
|
||||
break;
|
||||
@ -154,7 +167,9 @@ main(int argc, char *argv[])
|
||||
replstr = optarg;
|
||||
break;
|
||||
case 'L':
|
||||
Lflag = atoi(optarg);
|
||||
Lflag = strtonum(optarg, 0, INT_MAX, &errstr);
|
||||
if (errstr)
|
||||
errx(1, "-L %s: %s", optarg, errstr);
|
||||
if (COMPAT_MODE("bin/xargs", "Unix2003")) {
|
||||
nflag = 0; /* Override */
|
||||
nargs = 5000;
|
||||
@ -172,8 +187,13 @@ main(int argc, char *argv[])
|
||||
oflag = 1;
|
||||
break;
|
||||
case 'P':
|
||||
if ((maxprocs = atoi(optarg)) <= 0)
|
||||
errx(1, "max. processes must be >0");
|
||||
maxprocs = strtonum(optarg, 0, INT_MAX, &errstr);
|
||||
if (errstr)
|
||||
errx(1, "-P %s: %s", optarg, errstr);
|
||||
if (getrlimit(RLIMIT_NPROC, &rl) != 0)
|
||||
errx(1, "getrlimit failed");
|
||||
if (maxprocs == 0 || maxprocs > rl.rlim_cur)
|
||||
maxprocs = rl.rlim_cur;
|
||||
break;
|
||||
case 'p':
|
||||
pflag = 1;
|
||||
@ -183,8 +203,18 @@ main(int argc, char *argv[])
|
||||
if (*endptr != '\0')
|
||||
errx(1, "replacements must be a number");
|
||||
break;
|
||||
case 'r':
|
||||
/* GNU compatibility */
|
||||
break;
|
||||
case 'S':
|
||||
Sflag = strtoul(optarg, &endptr, 10);
|
||||
if (*endptr != '\0')
|
||||
errx(1, "replsize must be a number");
|
||||
break;
|
||||
case 's':
|
||||
nline = atoi(optarg);
|
||||
nline = strtonum(optarg, 0, INT_MAX, &errstr);
|
||||
if (errstr)
|
||||
errx(1, "-s %s: %s", optarg, errstr);
|
||||
pad9314053 = 0; /* assume the -s value is valid */
|
||||
break;
|
||||
case 't':
|
||||
@ -205,8 +235,12 @@ main(int argc, char *argv[])
|
||||
|
||||
if (!Iflag && Rflag)
|
||||
usage();
|
||||
if (!Iflag && Sflag)
|
||||
usage();
|
||||
if (Iflag && !Rflag)
|
||||
Rflag = 5;
|
||||
if (Iflag && !Sflag)
|
||||
Sflag = 255;
|
||||
if (xflag && !nflag)
|
||||
usage();
|
||||
if (Iflag || Lflag)
|
||||
@ -214,13 +248,15 @@ main(int argc, char *argv[])
|
||||
if (replstr != NULL && *replstr == '\0')
|
||||
errx(1, "replstr may not be empty");
|
||||
|
||||
pids_init();
|
||||
|
||||
/*
|
||||
* Allocate pointers for the utility name, the utility arguments,
|
||||
* the maximum arguments to be read from stdin and the trailing
|
||||
* NULL.
|
||||
*/
|
||||
linelen = 1 + argc + nargs + 1;
|
||||
if ((av = bxp = malloc(linelen * sizeof(char **))) == NULL)
|
||||
if ((av = bxp = malloc(linelen * sizeof(char *))) == NULL)
|
||||
errx(1, "malloc failed");
|
||||
|
||||
/*
|
||||
@ -279,13 +315,11 @@ parse_input(int argc, char *argv[])
|
||||
|
||||
foundeof = 0;
|
||||
|
||||
switch(ch = getchar()) {
|
||||
switch (ch = getchar()) {
|
||||
case EOF:
|
||||
/* No arguments since last exec. */
|
||||
if (p == bbp) {
|
||||
waitchildren(*argv, 1);
|
||||
exit(rval);
|
||||
}
|
||||
if (p == bbp)
|
||||
xexit(*av, rval);
|
||||
goto arg1;
|
||||
case ' ':
|
||||
last_was_blank = 1;
|
||||
@ -323,11 +357,13 @@ parse_input(int argc, char *argv[])
|
||||
last_was_newline = 1;
|
||||
|
||||
/* Quotes do not escape newlines. */
|
||||
arg1: if (insingle || indouble)
|
||||
errx(1, "unterminated quote");
|
||||
arg1: if (insingle || indouble) {
|
||||
warnx("unterminated quote");
|
||||
xexit(*av, 1);
|
||||
}
|
||||
arg2:
|
||||
foundeof = *eofstr != '\0' &&
|
||||
strcmp(argp, eofstr) == 0;
|
||||
strncmp(argp, eofstr, p - argp) == 0;
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* 6591323: -I specifies that it processes the entire line,
|
||||
@ -370,8 +406,10 @@ arg2:
|
||||
*/
|
||||
inpline = realloc(inpline, curlen + 2 +
|
||||
strlen(argp));
|
||||
if (inpline == NULL)
|
||||
errx(1, "realloc failed");
|
||||
if (inpline == NULL) {
|
||||
warnx("realloc failed");
|
||||
xexit(*av, 1);
|
||||
}
|
||||
if (curlen == 1)
|
||||
strcpy(inpline, argp);
|
||||
else
|
||||
@ -388,17 +426,17 @@ arg2:
|
||||
*/
|
||||
if (xp == endxp || p + (count * pad9314053) > ebp || ch == EOF ||
|
||||
(Lflag <= count && xflag) || foundeof) {
|
||||
if (xflag && xp != endxp && p + (count * pad9314053) > ebp)
|
||||
errx(1, "insufficient space for arguments");
|
||||
if (xflag && xp != endxp && p + (count * pad9314053) > ebp) {
|
||||
warnx("insufficient space for arguments");
|
||||
xexit(*av, 1);
|
||||
}
|
||||
if (jfound) {
|
||||
for (avj = argv; *avj; avj++)
|
||||
*xp++ = *avj;
|
||||
}
|
||||
prerun(argc, av);
|
||||
if (ch == EOF || foundeof) {
|
||||
waitchildren(*argv, 1);
|
||||
exit(rval);
|
||||
}
|
||||
if (ch == EOF || foundeof)
|
||||
xexit(*av, rval);
|
||||
p = bbp;
|
||||
xp = bxp;
|
||||
count = 0;
|
||||
@ -423,8 +461,10 @@ arg2:
|
||||
if (zflag)
|
||||
goto addch;
|
||||
/* Backslash escapes anything, is escaped by quotes. */
|
||||
if (!insingle && !indouble && (ch = getchar()) == EOF)
|
||||
errx(1, "backslash at EOF");
|
||||
if (!insingle && !indouble && (ch = getchar()) == EOF) {
|
||||
warnx("backslash at EOF");
|
||||
xexit(*av, 1);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
addch: if (p < ebp) {
|
||||
@ -433,11 +473,15 @@ addch: if (p < ebp) {
|
||||
}
|
||||
|
||||
/* If only one argument, not enough buffer space. */
|
||||
if (bxp == xp)
|
||||
errx(1, "insufficient space for argument");
|
||||
if (bxp == xp) {
|
||||
warnx("insufficient space for argument");
|
||||
xexit(*av, 1);
|
||||
}
|
||||
/* Didn't hit argument limit, so if xflag object. */
|
||||
if (xflag)
|
||||
errx(1, "insufficient space for arguments");
|
||||
if (xflag) {
|
||||
warnx("insufficient space for arguments");
|
||||
xexit(*av, 1);
|
||||
}
|
||||
|
||||
if (jfound) {
|
||||
for (avj = argv; *avj; avj++)
|
||||
@ -481,17 +525,21 @@ prerun(int argc, char *argv[])
|
||||
* Allocate memory to hold the argument list, and
|
||||
* a NULL at the tail.
|
||||
*/
|
||||
tmp = malloc((argc + 1) * sizeof(char**));
|
||||
if (tmp == NULL)
|
||||
errx(1, "malloc failed");
|
||||
tmp = malloc((argc + 1) * sizeof(char *));
|
||||
if (tmp == NULL) {
|
||||
warnx("malloc failed");
|
||||
xexit(*argv, 1);
|
||||
}
|
||||
tmp2 = tmp;
|
||||
|
||||
/*
|
||||
* Save the first argument and iterate over it, we
|
||||
* cannot do strnsubst() to it.
|
||||
*/
|
||||
if ((*tmp++ = strdup(*avj++)) == NULL)
|
||||
errx(1, "strdup failed");
|
||||
if ((*tmp++ = strdup(*avj++)) == NULL) {
|
||||
warnx("strdup failed");
|
||||
xexit(*argv, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* For each argument to utility, if we have not used up
|
||||
@ -504,12 +552,14 @@ prerun(int argc, char *argv[])
|
||||
while (--argc) {
|
||||
*tmp = *avj++;
|
||||
if (repls && strstr(*tmp, replstr) != NULL) {
|
||||
strnsubst(tmp++, replstr, inpline, (size_t)255);
|
||||
strnsubst(tmp++, replstr, inpline, (size_t)Sflag);
|
||||
if (repls > 0)
|
||||
repls--;
|
||||
} else {
|
||||
if ((*tmp = strdup(*tmp)) == NULL)
|
||||
errx(1, "strdup failed");
|
||||
if ((*tmp = strdup(*tmp)) == NULL) {
|
||||
warnx("strdup failed");
|
||||
xexit(*argv, 1);
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
@ -578,9 +628,10 @@ run(char **argv)
|
||||
}
|
||||
exec:
|
||||
childerr = 0;
|
||||
switch(pid = vfork()) {
|
||||
switch (pid = vfork()) {
|
||||
case -1:
|
||||
err(1, "vfork");
|
||||
warn("vfork");
|
||||
xexit(*argv, 1);
|
||||
case 0:
|
||||
if (oflag) {
|
||||
if ((fd = open(_PATH_TTY, O_RDONLY)) == -1)
|
||||
@ -597,35 +648,156 @@ exec:
|
||||
childerr = errno;
|
||||
_exit(1);
|
||||
}
|
||||
curprocs++;
|
||||
pids_add(pid);
|
||||
waitchildren(*argv, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for a tracked child to exit and return its pid and exit status.
|
||||
*
|
||||
* Ignores (discards) all untracked child processes.
|
||||
* Returns -1 and sets errno to ECHILD if no tracked children exist.
|
||||
* If block is set, waits indefinitely for a child process to exit.
|
||||
* If block is not set and no children have exited, returns 0 immediately.
|
||||
*/
|
||||
static pid_t
|
||||
xwait(int block, int *status) {
|
||||
pid_t pid;
|
||||
|
||||
if (pids_empty()) {
|
||||
errno = ECHILD;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
while ((pid = waitpid(-1, status, block ? 0 : WNOHANG)) > 0)
|
||||
if (pids_remove(pid))
|
||||
break;
|
||||
|
||||
return (pid);
|
||||
}
|
||||
|
||||
static void
|
||||
xexit(const char *name, const int exit_code) {
|
||||
waitchildren(name, 1);
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
static void
|
||||
waitchildren(const char *name, int waitall)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
int cause_exit = 0;
|
||||
|
||||
while ((pid = waitpid(-1, &status, !waitall && curprocs < maxprocs ?
|
||||
WNOHANG : 0)) > 0) {
|
||||
curprocs--;
|
||||
/* If we couldn't invoke the utility, exit. */
|
||||
if (childerr != 0) {
|
||||
errno = childerr;
|
||||
err(errno == ENOENT ? 127 : 126, "%s", name);
|
||||
}
|
||||
while ((pid = xwait(waitall || pids_full(), &status)) > 0) {
|
||||
/*
|
||||
* If utility signaled or exited with a value of 255,
|
||||
* exit 1-125.
|
||||
* If we couldn't invoke the utility or if utility exited
|
||||
* because of a signal or with a value of 255, warn (per
|
||||
* POSIX), and then wait until all other children have
|
||||
* exited before exiting 1-125. POSIX requires us to stop
|
||||
* reading if child exits because of a signal or with 255,
|
||||
* but it does not require us to exit immediately; waiting
|
||||
* is preferable to orphaning.
|
||||
*/
|
||||
if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
|
||||
exit(1);
|
||||
if (WEXITSTATUS(status))
|
||||
rval = 1;
|
||||
if (childerr != 0 && cause_exit == 0) {
|
||||
errno = childerr;
|
||||
waitall = 1;
|
||||
cause_exit = errno == ENOENT ? 127 : 126;
|
||||
warn("%s", name);
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
waitall = cause_exit = 1;
|
||||
warnx("%s: terminated with signal %d; aborting",
|
||||
name, WTERMSIG(status));
|
||||
} else if (WEXITSTATUS(status) == 255) {
|
||||
waitall = cause_exit = 1;
|
||||
warnx("%s: exited with status 255; aborting", name);
|
||||
} else if (WEXITSTATUS(status))
|
||||
rval = 1;
|
||||
}
|
||||
|
||||
if (cause_exit)
|
||||
exit(cause_exit);
|
||||
if (pid == -1 && errno != ECHILD)
|
||||
err(1, "wait3");
|
||||
err(1, "waitpid");
|
||||
}
|
||||
|
||||
#define NOPID (0)
|
||||
|
||||
static void
|
||||
pids_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((childpids = malloc(maxprocs * sizeof(*childpids))) == NULL)
|
||||
errx(1, "malloc failed");
|
||||
|
||||
for (i = 0; i < maxprocs; i++)
|
||||
clearslot(i);
|
||||
}
|
||||
|
||||
static int
|
||||
pids_empty(void)
|
||||
{
|
||||
|
||||
return (curprocs == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
pids_full(void)
|
||||
{
|
||||
|
||||
return (curprocs >= maxprocs);
|
||||
}
|
||||
|
||||
static void
|
||||
pids_add(pid_t pid)
|
||||
{
|
||||
int slot;
|
||||
|
||||
slot = findfreeslot();
|
||||
childpids[slot] = pid;
|
||||
curprocs++;
|
||||
}
|
||||
|
||||
static int
|
||||
pids_remove(pid_t pid)
|
||||
{
|
||||
int slot;
|
||||
|
||||
if ((slot = findslot(pid)) < 0)
|
||||
return (0);
|
||||
|
||||
clearslot(slot);
|
||||
curprocs--;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
findfreeslot(void)
|
||||
{
|
||||
int slot;
|
||||
|
||||
if ((slot = findslot(NOPID)) < 0)
|
||||
errx(1, "internal error: no free pid slot");
|
||||
return (slot);
|
||||
}
|
||||
|
||||
static int
|
||||
findslot(pid_t pid)
|
||||
{
|
||||
int slot;
|
||||
|
||||
for (slot = 0; slot < maxprocs; slot++)
|
||||
if (childpids[slot] == pid)
|
||||
return (slot);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
clearslot(int slot)
|
||||
{
|
||||
|
||||
childpids[slot] = NOPID;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -649,6 +821,7 @@ prompt(void)
|
||||
(void)fclose(ttyfp);
|
||||
return (0);
|
||||
}
|
||||
response[rsize - 1] = '\0';
|
||||
match = regexec(&cre, response, 0, NULL, 0);
|
||||
(void)fclose(ttyfp);
|
||||
regfree(&cre);
|
||||
@ -658,9 +831,10 @@ prompt(void)
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n"
|
||||
" [-L number] [-n number [-x]] [-P maxprocs] [-s size]\n"
|
||||
" [utility [argument ...]]\n");
|
||||
"usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements] [-S replsize]]\n"
|
||||
" [-J replstr] [-L number] [-n number [-x]] [-P maxprocs]\n"
|
||||
" [-s size] [utility [argument ...]]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -31,6 +31,20 @@ for manpage in `cat "$SRCROOT/xcodescripts/builtins-manpages.txt"`; do
|
||||
done
|
||||
set -x
|
||||
|
||||
install -d -o root -g wheel -m 0755 "$DSTROOT"/AppleInternal/Tests/shell_cmds
|
||||
install -o root -g wheel -m 0644 "$SRCROOT"/tests/regress.m4 \
|
||||
"$DSTROOT"/AppleInternal/Tests/shell_cmds
|
||||
|
||||
install -d -o root -g wheel -m 0755 \
|
||||
"$DSTROOT"/AppleInternal/Tests/shell_cmds/time
|
||||
install -o root -g wheel -m 0644 "$SRCROOT"/time/tests/test_time.sh \
|
||||
"$DSTROOT"/AppleInternal/Tests/shell_cmds/time
|
||||
|
||||
install -d -o root -g wheel -m 0755 \
|
||||
"$DSTROOT"/AppleInternal/CoreOS/BATS/unit_tests
|
||||
install -o root -g wheel -m 0644 "$SRCROOT"/tests/shell_cmds.plist \
|
||||
"$DSTROOT"/AppleInternal/CoreOS/BATS/unit_tests
|
||||
|
||||
# Skip locate and su targets for iOS
|
||||
if [ "$TARGET_NAME" = "All_iOS" ]; then
|
||||
exit 0
|
||||
@ -50,9 +64,3 @@ echo ".so man8/locate.updatedb.8" > "$MANDIR"/man8/locate.mklocatedb.8
|
||||
|
||||
install -d -o root -g wheel -m 0755 "$PAMDIR"
|
||||
install -c -o root -g wheel -m 0644 "$SRCROOT"/su/su.pam "$PAMDIR"/su
|
||||
|
||||
install -d -o root -g wheel -m 0755 "$DSTROOT"/AppleInternal/Tests/shell_cmds
|
||||
install -o root -g wheel -m 0644 "$SRCROOT"/tests/regress.m4 "$DSTROOT"/AppleInternal/Tests/shell_cmds
|
||||
|
||||
install -d -o root -g wheel -m 0755 "$DSTROOT"/AppleInternal/CoreOS/BATS/unit_tests
|
||||
install -o root -g wheel -m 0644 "$SRCROOT"/tests/shell_cmds.plist "$DSTROOT"/AppleInternal/CoreOS/BATS/unit_tests
|
||||
|
Loading…
Reference in New Issue
Block a user