NetBSD re-synchronization of the source tree

This brings our tree to NetBSD 7.0, as found on -current on the
10-10-2015.

This updates:
 - LLVM to 3.6.1
 - GCC to GCC 5.1
 - Replace minix/commands/zdump with usr.bin/zdump
 - external/bsd/libelf has moved to /external/bsd/elftoolchain/
 - Import ctwm
 - Drop sprintf from libminc

Change-Id: I149836ac18e9326be9353958bab9b266efb056f0
This commit is contained in:
2016-01-13 20:32:14 +01:00
parent 8933525b85
commit 0a6a1f1d05
32425 changed files with 2998492 additions and 1342217 deletions
+6 -3
View File
@@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.99 2012/12/02 12:55:27 apb Exp $
# $NetBSD: Makefile,v 1.101 2015/05/10 20:30:54 joerg Exp $
# @(#)Makefile 8.4 (Berkeley) 5/5/95
.include <bsd.own.mk>
@@ -42,6 +42,9 @@ CPPFLAGS+=-DSHELL -I. -I${.CURDIR}
.ifdef SMALLPROG
CPPFLAGS+=-DSMALL
.endif
.ifdef TINYPROG
CPPFLAGS+=-DTINY
.else
SRCS+=printf.c
.endif
@@ -77,9 +80,9 @@ nodes.c nodes.h: mknodes.sh nodetypes nodes.c.pat
NBCOMPATLIB= -L${TOOLDIR}/lib -lnbcompat
.endif
.if make(install)
.if !defined(__MINIX)
SUBDIR+=USD.doc
.endif
.endif # !defined(__MINIX)
COPTS.printf.c = -Wno-format-nonliteral
COPTS.jobs.c = -Wno-format-nonliteral
+8 -8
View File
@@ -1,12 +1,12 @@
# $NetBSD: Makefile,v 1.1 2010/08/22 01:58:16 perry Exp $
# $NetBSD: Makefile,v 1.4 2014/07/05 19:23:00 dholland Exp $
# @(#)Makefile 8.1 (Berkeley) 8/14/93
DIR= usd/03.shell
SRCS= Rv7man t.mac t1 t2 t3 t4
MACROS= -ms
paper.ps: ${SRCS}
${TOOL_REFER} -e -p ${SRCS} | \
${TOOL_ROFF_PS} ${MACROS} > ${.TARGET}
SECTION=reference/ref1
ARTICLE=sh
SRCS= referargs t.mac t1 t2 t3 t4
MACROS=-ms
ROFF_REFER=yes
#REFER_ARGS=-e -p Rv7man
EXTRAHTMLFILES=sh1.png sh2.png sh3.png sh4.png sh5.png
.include <bsd.doc.mk>
+8
View File
@@ -0,0 +1,8 @@
.\" $NetBSD: referargs,v 1.1 2014/07/05 19:22:02 dholland Exp $
.\"
.\" Arguments for refer; these were previously passed on the refer(1)
.\" command line: -e -p Rv7man
.R1
accumulate
database Rv7man
.R2
+7 -7
View File
@@ -1,4 +1,4 @@
/* $NetBSD: alias.c,v 1.14 2011/06/18 21:18:46 christos Exp $ */
/* $NetBSD: alias.c,v 1.15 2014/06/18 18:17:30 christos Exp $ */
/*-
* Copyright (c) 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: alias.c,v 1.14 2011/06/18 21:18:46 christos Exp $");
__RCSID("$NetBSD: alias.c,v 1.15 2014/06/18 18:17:30 christos Exp $");
#endif
#endif /* not lint */
@@ -59,7 +59,7 @@ struct alias *atab[ATABSIZE];
STATIC void setalias(char *, char *);
STATIC int unalias(char *);
STATIC struct alias **hashalias(char *);
STATIC struct alias **hashalias(const char *);
STATIC
void
@@ -178,7 +178,7 @@ rmaliases(void)
}
struct alias *
lookupalias(char *name, int check)
lookupalias(const char *name, int check)
{
struct alias *ap = *hashalias(name);
@@ -193,8 +193,8 @@ lookupalias(char *name, int check)
return (NULL);
}
char *
get_alias_text(char *name)
const char *
alias_text(void *dummy __unused, const char *name)
{
struct alias *ap;
@@ -264,7 +264,7 @@ unaliascmd(int argc, char **argv)
}
STATIC struct alias **
hashalias(char *p)
hashalias(const char *p)
{
unsigned int hashval;
+3 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: alias.h,v 1.7 2011/06/18 21:18:46 christos Exp $ */
/* $NetBSD: alias.h,v 1.8 2014/06/18 18:17:30 christos Exp $ */
/*-
* Copyright (c) 1993
@@ -43,6 +43,6 @@ struct alias {
int flag;
};
struct alias *lookupalias(char *, int);
char *get_alias_text(char *);
struct alias *lookupalias(const char *, int);
const char *alias_text(void *, const char *);
void rmaliases(void);
+2 -2
View File
@@ -1,5 +1,5 @@
#!/bin/sh -
# $NetBSD: builtins.def,v 1.22 2012/12/31 14:10:15 dsl Exp $
# $NetBSD: builtins.def,v 1.23 2015/05/10 20:30:54 joerg Exp $
#
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
@@ -66,7 +66,7 @@ hashcmd hash
jobidcmd jobid
jobscmd -u jobs
localcmd local
#ifndef SMALL
#ifndef TINY
printfcmd printf
#endif
pwdcmd -u pwd
+135 -22
View File
@@ -1,4 +1,4 @@
/* $NetBSD: eval.c,v 1.107 2013/06/27 23:22:04 yamt Exp $ */
/* $NetBSD: eval.c,v 1.110 2015/01/02 19:56:20 christos Exp $ */
/*-
* Copyright (c) 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
#else
__RCSID("$NetBSD: eval.c,v 1.107 2013/06/27 23:22:04 yamt Exp $");
__RCSID("$NetBSD: eval.c,v 1.110 2015/01/02 19:56:20 christos Exp $");
#endif
#endif /* not lint */
@@ -89,11 +89,20 @@ __RCSID("$NetBSD: eval.c,v 1.107 2013/06/27 23:22:04 yamt Exp $");
#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
#define EV_BACKCMD 04 /* command executing within back quotes */
int evalskip; /* set if we are skipping commands */
STATIC enum skipstate evalskip; /* != SKIPNONE if we are skipping commands */
STATIC int skipcount; /* number of levels to skip */
MKINIT int loopnest; /* current loop nesting level */
int funcnest; /* depth of function calls */
STATIC int loopnest; /* current loop nesting level */
STATIC int funcnest; /* depth of function calls */
STATIC int builtin_flags; /* evalcommand flags for builtins */
/*
* Base function nesting level inside a dot command. Set to 0 initially
* and to (funcnest + 1) before every dot command to enable
* 1) detection of being in a file sourced by a dot command and
* 2) counting of function nesting in that file for the implementation
* of the return command.
* The value is reset to its previous value after the dot command.
*/
STATIC int dot_funcnest;
const char *commandname;
@@ -111,6 +120,7 @@ STATIC void evalpipe(union node *);
STATIC void evalcommand(union node *, int, struct backcmd *);
STATIC void prehash(union node *);
STATIC char *find_dot_file(char *);
/*
* Called to reset things after an exception.
@@ -120,9 +130,7 @@ STATIC void prehash(union node *);
INCLUDE "eval.h"
RESET {
evalskip = 0;
loopnest = 0;
funcnest = 0;
reset_eval();
}
SHELLPROC {
@@ -130,6 +138,15 @@ SHELLPROC {
}
#endif
void
reset_eval(void)
{
evalskip = SKIPNONE;
dot_funcnest = 0;
loopnest = 0;
funcnest = 0;
}
static int
sh_pipe(int fds[2])
{
@@ -327,11 +344,11 @@ evalloop(union node *n, int flags)
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip) {
skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
evalskip = 0;
evalskip = SKIPNONE;
continue;
}
if (evalskip == SKIPBREAK && --skipcount <= 0)
evalskip = 0;
evalskip = SKIPNONE;
break;
}
if (n->type == NWHILE) {
@@ -377,11 +394,11 @@ evalfor(union node *n, int flags)
status = exitstatus;
if (evalskip) {
if (evalskip == SKIPCONT && --skipcount <= 0) {
evalskip = 0;
evalskip = SKIPNONE;
continue;
}
if (evalskip == SKIPBREAK && --skipcount <= 0)
evalskip = 0;
evalskip = SKIPNONE;
break;
}
}
@@ -850,17 +867,19 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
* child's address space is actually shared with the parent as
* we rely on this.
*/
if (cmdentry.cmdtype == CMDNORMAL) {
if (usefork == 0 && cmdentry.cmdtype == CMDNORMAL) {
pid_t pid;
int serrno;
savelocalvars = localvars;
localvars = NULL;
vforked = 1;
switch (pid = vfork()) {
case -1:
TRACE(("Vfork failed, errno=%d\n", errno));
serrno = errno;
TRACE(("Vfork failed, errno=%d\n", serrno));
INTON;
error("Cannot vfork");
error("Cannot vfork (%s)", strerror(serrno));
break;
case 0:
/* Make sure that exceptions only unwind to
@@ -969,7 +988,7 @@ normal_fork:
popredir();
INTON;
if (evalskip == SKIPFUNC) {
evalskip = 0;
evalskip = SKIPNONE;
skipcount = 0;
}
if (flags & EV_EXIT)
@@ -1109,7 +1128,24 @@ prehash(union node *n)
pathval());
}
STATIC int
in_function(void)
{
return funcnest;
}
STATIC enum skipstate
current_skipstate(void)
{
return evalskip;
}
STATIC void
stop_skipping(void)
{
evalskip = SKIPNONE;
skipcount = 0;
}
/*
* Builtin commands. Builtin commands whose functions are closely
@@ -1156,9 +1192,84 @@ breakcmd(int argc, char **argv)
return 0;
}
int
dotcmd(int argc, char **argv)
{
exitstatus = 0;
if (argc >= 2) { /* That's what SVR2 does */
char *fullname;
/*
* dot_funcnest needs to be 0 when not in a dotcmd, so it
* cannot be restored with (funcnest + 1).
*/
int dot_funcnest_old;
struct stackmark smark;
setstackmark(&smark);
fullname = find_dot_file(argv[1]);
setinputfile(fullname, 1);
commandname = fullname;
dot_funcnest_old = dot_funcnest;
dot_funcnest = funcnest + 1;
cmdloop(0);
dot_funcnest = dot_funcnest_old;
popfile();
popstackmark(&smark);
}
return exitstatus;
}
/*
* Take commands from a file. To be compatible we should do a path
* search for the file, which is necessary to find sub-commands.
*/
STATIC char *
find_dot_file(char *basename)
{
char *fullname;
const char *path = pathval();
struct stat statb;
/* don't try this for absolute or relative paths */
if (strchr(basename, '/'))
return basename;
while ((fullname = padvance(&path, basename)) != NULL) {
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
/*
* Don't bother freeing here, since it will
* be freed by the caller.
*/
return fullname;
}
stunalloc(fullname);
}
/* not found in the PATH */
error("%s: not found", basename);
/* NOTREACHED */
}
/*
* The return command.
*
* Quoth the POSIX standard:
* The return utility shall cause the shell to stop executing the current
* function or dot script. If the shell is not currently executing
* a function or dot script, the results are unspecified.
*
* As for the unspecified part, there seems to be no de-facto standard: bash
* ignores the return with a warning, zsh ignores the return in interactive
* mode but seems to liken it to exit in a script. (checked May 2014)
*
* We choose to silently ignore the return. Older versions of this shell
* set evalskip to SKIPFILE causing the shell to (indirectly) exit. This
* had at least the problem of circumventing the check for stopped jobs,
* which would occur for exit or ^D.
*/
int
@@ -1166,17 +1277,19 @@ returncmd(int argc, char **argv)
{
int ret = argc > 1 ? number(argv[1]) : exitstatus;
if (funcnest) {
if ((dot_funcnest == 0 && funcnest)
|| (dot_funcnest > 0 && funcnest - (dot_funcnest - 1) > 0)) {
evalskip = SKIPFUNC;
skipcount = 1;
return ret;
}
else {
/* Do what ksh does; skip the rest of the file */
} else if (dot_funcnest > 0) {
evalskip = SKIPFILE;
skipcount = 1;
return ret;
} else {
/* XXX: should a warning be issued? */
ret = 0;
}
return ret;
}
+17 -8
View File
@@ -1,4 +1,4 @@
/* $NetBSD: eval.h,v 1.15 2008/02/15 17:26:06 matt Exp $ */
/* $NetBSD: eval.h,v 1.16 2014/05/31 14:42:18 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -53,12 +53,21 @@ void evaltree(union node *, int);
void evalbackcmd(union node *, struct backcmd *);
/* in_function returns nonzero if we are currently evaluating a function */
#define in_function() funcnest
extern int funcnest;
extern int evalskip;
int in_function(void); /* return non-zero, if evaluating a function */
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
#define SKIPFUNC 3
#define SKIPFILE 4
enum skipstate {
SKIPNONE = 0, /* not skipping */
SKIPBREAK, /* break */
SKIPCONT, /* continue */
SKIPFUNC, /* return in a function */
SKIPFILE /* return in a dot command */
};
enum skipstate current_skipstate(void);
void stop_skipping(void); /* reset internal skipping state to SKIPNONE */
/*
* Only for use by reset() in init.c!
*/
void reset_eval(void);
+54 -16
View File
@@ -1,4 +1,4 @@
/* $NetBSD: expand.c,v 1.90 2013/10/06 21:05:50 ast Exp $ */
/* $NetBSD: expand.c,v 1.93 2015/08/27 07:46:47 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95";
#else
__RCSID("$NetBSD: expand.c,v 1.90 2013/10/06 21:05:50 ast Exp $");
__RCSID("$NetBSD: expand.c,v 1.93 2015/08/27 07:46:47 christos Exp $");
#endif
#endif /* not lint */
@@ -51,6 +51,7 @@ __RCSID("$NetBSD: expand.c,v 1.90 2013/10/06 21:05:50 ast Exp $");
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <wctype.h>
/*
* Routines to expand arguments to commands. We have to deal with
@@ -97,7 +98,7 @@ struct arglist exparg; /* holds expanded arg list */
STATIC void argstr(char *, int);
STATIC char *exptilde(char *, int);
STATIC void expbackq(union node *, int, int);
STATIC int subevalvar(char *, char *, int, int, int, int);
STATIC int subevalvar(char *, char *, int, int, int, int, int);
STATIC char *evalvar(char *, int);
STATIC int varisset(char *, int);
STATIC void varvalue(char *, int, int, int);
@@ -450,7 +451,8 @@ expbackq(union node *cmd, int quoted, int flag)
if (--in.nleft < 0) {
if (in.fd < 0)
break;
while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR);
while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR)
continue;
TRACE(("expbackq: read returns %d\n", i));
if (i <= 0)
break;
@@ -493,7 +495,7 @@ expbackq(union node *cmd, int quoted, int flag)
STATIC int
subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varflags)
subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varflags, int quotes)
{
char *startp;
char *loc = NULL;
@@ -546,10 +548,10 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla
for (loc = startp; loc < str; loc++) {
c = *loc;
*loc = '\0';
if (patmatch(str, startp, varflags & VSQUOTE))
if (patmatch(str, startp, quotes))
goto recordleft;
*loc = c;
if ((varflags & VSQUOTE) && *loc == CTLESC)
if (quotes && *loc == CTLESC)
loc++;
}
return 0;
@@ -558,11 +560,11 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla
for (loc = str - 1; loc >= startp;) {
c = *loc;
*loc = '\0';
if (patmatch(str, startp, varflags & VSQUOTE))
if (patmatch(str, startp, quotes))
goto recordleft;
*loc = c;
loc--;
if ((varflags & VSQUOTE) && loc > startp &&
if (quotes && loc > startp &&
*(loc - 1) == CTLESC) {
for (q = startp; q < loc; q++)
if (*q == CTLESC)
@@ -575,10 +577,10 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla
case VSTRIMRIGHT:
for (loc = str - 1; loc >= startp;) {
if (patmatch(str, loc, varflags & VSQUOTE))
if (patmatch(str, loc, quotes))
goto recordright;
loc--;
if ((varflags & VSQUOTE) && loc > startp &&
if (quotes && loc > startp &&
*(loc - 1) == CTLESC) {
for (q = startp; q < loc; q++)
if (*q == CTLESC)
@@ -591,9 +593,9 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla
case VSTRIMRIGHTMAX:
for (loc = startp; loc < str - 1; loc++) {
if (patmatch(str, loc, varflags & VSQUOTE))
if (patmatch(str, loc, quotes))
goto recordright;
if ((varflags & VSQUOTE) && *loc == CTLESC)
if (quotes && *loc == CTLESC)
loc++;
}
return 0;
@@ -761,7 +763,7 @@ again: /* jump here after setting a variable with ${var=text} */
STPUTC('\0', expdest);
patloc = expdest - stackblock();
if (subevalvar(p, NULL, patloc, subtype,
startloc, varflags) == 0) {
startloc, varflags, quotes) == 0) {
int amount = (expdest - stackblock() - patloc) + 1;
STADJUST(-amount, expdest);
}
@@ -774,7 +776,7 @@ again: /* jump here after setting a variable with ${var=text} */
case VSQUESTION:
if (set)
break;
if (subevalvar(p, var, 0, subtype, startloc, varflags)) {
if (subevalvar(p, var, 0, subtype, startloc, varflags, quotes)) {
varflags &= ~VSNUL;
/*
* Remove any recorded regions beyond
@@ -1365,6 +1367,37 @@ msort(struct strlist *list, int len)
}
/*
* See if a character matches a character class, starting at the first colon
* of "[:class:]".
* If a valid character class is recognized, a pointer to the next character
* after the final closing bracket is stored into *end, otherwise a null
* pointer is stored into *end.
*/
static int
match_charclass(char *p, wchar_t chr, char **end)
{
char name[20];
char *nameend;
wctype_t cclass;
*end = NULL;
p++;
nameend = strstr(p, ":]");
if (nameend == NULL || (size_t)(nameend - p) >= sizeof(name) ||
nameend == p)
return 0;
memcpy(name, p, nameend - p);
name[nameend - p] = '\0';
*end = nameend + 2;
cclass = wctype(name);
/* An unknown class matches nothing but is valid nevertheless. */
if (cclass == 0)
return 0;
return iswctype(chr, cclass);
}
/*
* Returns true if the pattern matches the string.
@@ -1385,7 +1418,7 @@ patmatch(char *pattern, char *string, int squoted)
STATIC int
pmatch(char *pattern, char *string, int squoted)
{
char *p, *q;
char *p, *q, *end;
char c;
p = pattern;
@@ -1465,6 +1498,11 @@ pmatch(char *pattern, char *string, int squoted)
do {
if (c == CTLQUOTEMARK)
continue;
if (c == '[' && *p == ':') {
found |= match_charclass(p, chr, &end);
if (end != NULL)
p = end;
}
if (c == CTLESC)
c = *p++;
if (*p == '-' && p[1] != ']') {
+8 -4
View File
@@ -1,4 +1,4 @@
/* $NetBSD: histedit.c,v 1.45 2012/03/20 18:42:29 matt Exp $ */
/* $NetBSD: histedit.c,v 1.47 2014/06/18 18:17:30 christos Exp $ */
/*-
* Copyright (c) 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: histedit.c,v 1.45 2012/03/20 18:42:29 matt Exp $");
__RCSID("$NetBSD: histedit.c,v 1.47 2014/06/18 18:17:30 christos Exp $");
#endif
#endif /* not lint */
@@ -59,6 +59,7 @@ __RCSID("$NetBSD: histedit.c,v 1.45 2012/03/20 18:42:29 matt Exp $");
#include "mystring.h"
#include "myhistedit.h"
#include "error.h"
#include "alias.h"
#ifndef SMALL
#include "eval.h"
#include "memalloc.h"
@@ -135,6 +136,7 @@ histedit(void)
el_set(el, EL_HIST, history, hist);
el_set(el, EL_PROMPT, getprompt);
el_set(el, EL_SIGNAL, 1);
el_set(el, EL_ALIAS_TEXT, alias_text, NULL);
el_set(el, EL_ADDFN, "rl-complete",
"ReadLine compatible completion function",
_el_fn_complete);
@@ -432,10 +434,12 @@ histcmd(int argc, char **argv)
}
if (editor) {
char *editcmd;
size_t cmdlen;
fclose(efp);
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
sprintf(editcmd, "%s %s", editor, editfile);
cmdlen = strlen(editor) + strlen(editfile) + 2;
editcmd = stalloc(cmdlen);
snprintf(editcmd, cmdlen, "%s %s", editor, editfile);
evalstring(editcmd, 0); /* XXX - should use no JC command */
INTON;
readcmdfile(editfile); /* XXX - should read back - quick tst */
+17 -12
View File
@@ -1,4 +1,4 @@
/* $NetBSD: jobs.c,v 1.71 2012/12/31 14:10:15 dsl Exp $ */
/* $NetBSD: jobs.c,v 1.75 2015/08/22 12:12:47 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: jobs.c,v 1.71 2012/12/31 14:10:15 dsl Exp $");
__RCSID("$NetBSD: jobs.c,v 1.75 2015/08/22 12:12:47 christos Exp $");
#endif
#endif /* not lint */
@@ -572,12 +572,18 @@ showjobs(struct output *out, int mode)
{
int jobno;
struct job *jp;
#if JOBS /* MINIX: gotpid. */
int silent = 0, gotpid;
#else
int silent = 0;
#endif
TRACE(("showjobs(%x) called\n", mode));
/* If not even one one job changed, there is nothing to do */
#if JOBS /* MINIX: gotpid. */
gotpid = dowait(0, NULL);
#endif
while (dowait(0, NULL) > 0)
continue;
#if JOBS /* MINIX: #ifdef fails when JOBS = 0 */
@@ -659,7 +665,7 @@ waitcmd(int argc, char **argv)
continue;
}
if (dowait(WBLOCK, NULL) == -1)
return 128 + SIGINT;
return 128 + lastsig();
jp = jobtab;
}
}
@@ -674,9 +680,9 @@ waitcmd(int argc, char **argv)
/* loop until process terminated or stopped */
while (job->state == JOBRUNNING) {
if (dowait(WBLOCK|WNOFREE, job) == -1)
return 128 + SIGINT;
return 128 + lastsig();
}
status = job->ps[job->nprocs - 1].status;
status = job->ps[job->nprocs ? job->nprocs - 1 : 0].status;
if (WIFEXITED(status))
retval = WEXITSTATUS(status);
#if JOBS
@@ -885,14 +891,16 @@ makejob(union node *node, int nprocs)
int
forkshell(struct job *jp, union node *n, int mode)
{
int pid;
pid_t pid;
int serrno;
TRACE(("forkshell(%%%d, %p, %d) called\n", jp - jobtab, n, mode));
switch ((pid = fork())) {
case -1:
TRACE(("Fork failed, errno=%d\n", errno));
serrno = errno;
TRACE(("Fork failed, errno=%d\n", serrno));
INTON;
error("Cannot fork");
error("Cannot fork (%s)", strerror(serrno));
break;
case 0:
forkchild(jp, n, mode, 0);
@@ -912,10 +920,8 @@ forkparent(struct job *jp, union node *n, int mode, pid_t pid)
pgrp = pid;
else
pgrp = jp->ps[0].pid;
#if JOBS /* LSC: not available under MINIX. */
/* This can fail because we are doing it in the child also */
(void)setpgid(pid, pgrp);
#endif
}
if (mode == FORK_BG)
backgndpid = pid; /* set $! */
@@ -1087,13 +1093,12 @@ dowait(int flags, struct job *job)
struct job *thisjob;
int done;
int stopped;
extern volatile char gotsig[];
TRACE(("dowait(%x) called\n", flags));
do {
pid = waitproc(flags & WBLOCK, job, &status);
TRACE(("wait returns pid %d, status %d\n", pid, status));
} while (pid == -1 && errno == EINTR && gotsig[SIGINT - 1] == 0);
} while (pid == -1 && errno == EINTR && pendingsigs == 0);
if (pid <= 0)
return pid;
INTOFF;
+32 -59
View File
@@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.57 2011/06/18 21:18:46 christos Exp $ */
/* $NetBSD: main.c,v 1.59 2015/05/26 21:35:15 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95";
#else
__RCSID("$NetBSD: main.c,v 1.57 2011/06/18 21:18:46 christos Exp $");
__RCSID("$NetBSD: main.c,v 1.59 2015/05/26 21:35:15 christos Exp $");
#endif
#endif /* not lint */
@@ -89,7 +89,6 @@ extern int etext();
#endif
STATIC void read_profile(const char *);
STATIC char *find_dot_file(char *);
int main(int, char **);
/*
@@ -107,6 +106,11 @@ main(int argc, char **argv)
struct stackmark smark;
volatile int state;
char *shinit;
uid_t uid;
gid_t gid;
uid = getuid();
gid = getgid();
setlocale(LC_ALL, "");
@@ -179,6 +183,18 @@ main(int argc, char **argv)
initpwd();
setstackmark(&smark);
procargs(argc, argv);
/*
* Limit bogus system(3) or popen(3) calls in setuid binaries,
* by requiring the -p flag
*/
if (!pflag && (uid != geteuid() || gid != getegid())) {
setuid(uid);
setgid(gid);
/* PS1 might need to be changed accordingly. */
choose_ps1();
}
if (argv[0] && argv[0][0] == '-') {
state = 1;
read_profile("/etc/profile");
@@ -239,6 +255,7 @@ cmdloop(int top)
struct stackmark smark;
int inter;
int numeof = 0;
enum skipstate skip;
TRACE(("cmdloop(%d) called\n", top));
setstackmark(&smark);
@@ -270,8 +287,18 @@ cmdloop(int top)
}
popstackmark(&smark);
setstackmark(&smark);
if (evalskip == SKIPFILE) {
evalskip = 0;
/*
* Any SKIP* can occur here! SKIP(FUNC|BREAK|CONT) occur when
* a dotcmd is in a loop or a function body and appropriate
* built-ins occurs in file scope in the sourced file. Values
* other than SKIPFILE are reset by the appropriate eval*()
* that contained the dotcmd() call.
*/
skip = current_skipstate();
if (skip != SKIPNONE) {
if (skip == SKIPFILE)
stop_skipping();
break;
}
}
@@ -337,60 +364,6 @@ readcmdfile(char *name)
/*
* Take commands from a file. To be compatible we should do a path
* search for the file, which is necessary to find sub-commands.
*/
STATIC char *
find_dot_file(char *basename)
{
char *fullname;
const char *path = pathval();
struct stat statb;
/* don't try this for absolute or relative paths */
if (strchr(basename, '/'))
return basename;
while ((fullname = padvance(&path, basename)) != NULL) {
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
/*
* Don't bother freeing here, since it will
* be freed by the caller.
*/
return fullname;
}
stunalloc(fullname);
}
/* not found in the PATH */
error("%s: not found", basename);
/* NOTREACHED */
}
int
dotcmd(int argc, char **argv)
{
exitstatus = 0;
if (argc >= 2) { /* That's what SVR2 does */
char *fullname;
struct stackmark smark;
setstackmark(&smark);
fullname = find_dot_file(argv[1]);
setinputfile(fullname, 1);
commandname = fullname;
cmdloop(0);
popfile();
popstackmark(&smark);
}
return exitstatus;
}
int
exitcmd(int argc, char **argv)
{
+4 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: miscbltin.c,v 1.42 2012/06/11 18:28:10 njoly Exp $ */
/* $NetBSD: miscbltin.c,v 1.43 2015/05/09 13:28:55 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: miscbltin.c,v 1.42 2012/06/11 18:28:10 njoly Exp $");
__RCSID("$NetBSD: miscbltin.c,v 1.43 2015/05/09 13:28:55 christos Exp $");
#endif
#endif /* not lint */
@@ -427,7 +427,8 @@ ulimitcmd(int argc, char **argv)
return 0;
}
getrlimit(l->cmd, &limit);
if (getrlimit(l->cmd, &limit) == -1)
error("error getting limit (%s)", strerror(errno));
if (set) {
if (how & HARD)
limit.rlim_max = val;
+6 -2
View File
@@ -1,4 +1,4 @@
/* $NetBSD: options.h,v 1.20 2011/06/18 21:18:46 christos Exp $ */
/* $NetBSD: options.h,v 1.22 2015/05/26 21:35:15 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -99,9 +99,13 @@ DEF_OPT( "cdprint", 0 ) /* always print result of cd */
#define cdprint optlist[17].val
DEF_OPT( "tabcomplete", 0 ) /* <tab> causes filename expansion */
#define tabcomplete optlist[18].val
DEF_OPT( "fork", 'F' ) /* use fork(2) instead of vfork(2) */
#define usefork optlist[19].val
DEF_OPT( "nopriv", 'p' ) /* preserve privs even if set{u,g}id */
#define pflag optlist[20].val
#ifdef DEBUG
DEF_OPT( "debug", 0 ) /* enable debug prints */
#define debug optlist[19].val
#define debug optlist[21].val
#endif
#ifdef DEFINE_OPTIONS
+37 -18
View File
@@ -1,4 +1,4 @@
/* $NetBSD: parser.c,v 1.85 2013/10/02 21:48:55 christos Exp $ */
/* $NetBSD: parser.c,v 1.93 2014/08/29 09:35:19 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
#else
__RCSID("$NetBSD: parser.c,v 1.85 2013/10/02 21:48:55 christos Exp $");
__RCSID("$NetBSD: parser.c,v 1.93 2014/08/29 09:35:19 christos Exp $");
#endif
#endif /* not lint */
@@ -432,7 +432,17 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
cpp = &n1->ncase.cases;
noalias = 1;
checkkwd = 2, readtoken();
do {
/*
* Both ksh and bash accept 'case x in esac'
* so configure scripts started taking advantage of this.
* The page: http://pubs.opengroup.org/onlinepubs/\
* 009695399/utilities/xcu_chap02.html contradicts itself,
* as to if this is legal; the "Case Conditional Format"
* paragraph shows one case is required, but the "Grammar"
* section shows a grammar that explicitly allows the no
* case option.
*/
while (lasttoken != TESAC) {
*cpp = cp = (union node *)stalloc(sizeof (struct nclist));
if (lasttoken == TLP)
readtoken();
@@ -467,7 +477,7 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
}
}
cpp = &cp->nclist.next;
} while(lasttoken != TESAC);
}
noalias = 0;
*cpp = NULL;
checkkwd = 1;
@@ -637,8 +647,8 @@ void fixredir(union node *n, const char *text, int err)
if (!err)
n->ndup.vname = NULL;
if (is_digit(text[0]) && text[1] == '\0')
n->ndup.dupfd = digit_val(text[0]);
if (is_number(text))
n->ndup.dupfd = number(text);
else if (text[0] == '-' && text[1] == '\0')
n->ndup.dupfd = -1;
else {
@@ -678,7 +688,8 @@ parsefname(void)
if (heredoclist == NULL)
heredoclist = here;
else {
for (p = heredoclist ; p->next ; p = p->next);
for (p = heredoclist ; p->next ; p = p->next)
continue;
p->next = here;
}
} else if (n->type == NTOFD || n->type == NFROMFD) {
@@ -762,13 +773,13 @@ readtoken(void)
for (pp = parsekwd; *pp; pp++) {
if (**pp == *wordtext && equal(*pp, wordtext))
{
lasttoken = t = pp -
lasttoken = t = pp -
parsekwd + KWDOFFSET;
TRACE(("keyword %s recognized\n", tokname[t]));
goto out;
}
}
if(!noalias &&
if (!noalias &&
(ap = lookupalias(wordtext, 1)) != NULL) {
pushstring(ap->val, strlen(ap->val), ap);
checkkwd = savecheckkwd;
@@ -823,19 +834,25 @@ xxreadtoken(void)
case ' ': case '\t':
continue;
case '#':
while ((c = pgetc()) != '\n' && c != PEOF);
while ((c = pgetc()) != '\n' && c != PEOF)
continue;
pungetc();
continue;
case '\\':
if (pgetc() == '\n') {
switch (pgetc()) {
case '\n':
startlinno = ++plinno;
if (doprompt)
setprompt(2);
else
setprompt(0);
continue;
case PEOF:
RETURN(TEOF);
default:
pungetc();
break;
}
pungetc();
goto breakloop;
case '\n':
plinno++;
@@ -990,6 +1007,7 @@ readtoken1(int firstc, char const *syn, char *eofmark, int striptabs)
break;
}
if (c == '\n') {
plinno++;
if (doprompt)
setprompt(2);
else
@@ -1136,8 +1154,7 @@ endword:
if (eofmark == NULL) {
if ((c == '>' || c == '<')
&& quotef == 0
&& len <= 2
&& (*out == '\0' || is_digit(*out))) {
&& (*out == '\0' || is_number(out))) {
PARSEREDIR();
return lasttoken = TREDIR;
} else {
@@ -1172,7 +1189,8 @@ checkend: {
char *p, *q;
p = line;
for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
for (q = eofmark + 1 ; *q && *p == *q ; p++, q++)
continue;
if ((*p == '\0' || *p == '\n') && *q == '\0') {
c = PEOF;
plinno++;
@@ -1194,8 +1212,9 @@ checkend: {
*/
parseredir: {
char fd = *out;
char fd[64];
union node *np;
strlcpy(fd, out, sizeof(fd));
np = (union node *)stalloc(sizeof (struct nfile));
if (c == '>') {
@@ -1244,8 +1263,8 @@ parseredir: {
break;
}
}
if (fd != '\0')
np->nfile.fd = digit_val(fd);
if (*fd != '\0')
np->nfile.fd = number(fd);
redirnode = np;
goto parseredir_return;
}
+23 -6
View File
@@ -1,4 +1,4 @@
/* $NetBSD: redir.c,v 1.35 2013/06/27 23:22:04 yamt Exp $ */
/* $NetBSD: redir.c,v 1.37 2014/10/23 21:03:25 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: redir.c,v 1.35 2013/06/27 23:22:04 yamt Exp $");
__RCSID("$NetBSD: redir.c,v 1.37 2014/10/23 21:03:25 christos Exp $");
#endif
#endif /* not lint */
@@ -164,10 +164,11 @@ redirect(union node *redir, int flags)
STATIC void
openredirect(union node *redir, char memory[10], int flags)
{
struct stat sb;
int fd = redir->nfile.fd;
char *fname;
int f;
int oflags = O_WRONLY|O_CREAT|O_TRUNC, eflags;
int eflags;
/*
* We suppress interrupts so that we won't leave open file
@@ -194,12 +195,28 @@ openredirect(union node *redir, char memory[10], int flags)
goto ecreate;
break;
case NTO:
if (Cflag)
oflags |= O_EXCL;
if (Cflag) {
fname = redir->nfile.expfname;
if ((f = open(fname, O_WRONLY)) == -1) {
if ((f = open(fname, O_WRONLY|O_CREAT|O_EXCL,
0666)) < 0)
goto ecreate;
} else if (fstat(f, &sb) == -1) {
int serrno = errno;
close(f);
errno = serrno;
goto ecreate;
} else if (S_ISREG(sb.st_mode)) {
close(f);
errno = EEXIST;
goto ecreate;
}
break;
}
/* FALLTHROUGH */
case NCLOBBER:
fname = redir->nfile.expfname;
if ((f = open(fname, oflags, 0666)) < 0)
if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
goto ecreate;
break;
case NAPPEND:
+53 -8
View File
@@ -1,4 +1,4 @@
.\" $NetBSD: sh.1,v 1.111 2013/10/02 20:42:56 christos Exp $
.\" $NetBSD: sh.1,v 1.115 2015/05/26 21:35:15 christos Exp $
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -31,7 +31,7 @@
.\"
.\" @(#)sh.1 8.6 (Berkeley) 5/4/95
.\"
.Dd October 2, 2013
.Dd May 26, 2015
.Dt SH 1
.Os
.Sh NAME
@@ -53,8 +53,8 @@
.Nm
.Fl c
.Bk -words
.Op Fl aCefnuvxIimqVEb
.Op Cm +aCefnuvxIimqVEb
.Op Fl abCEefnuvxIimpqV
.Op Cm +abCEefnuvxIimpqV
.Ek
.Bk -words
.Op Fl o Ar option_name
@@ -67,8 +67,8 @@
.Nm
.Fl s
.Bk -words
.Op Fl aCefnuvxIimqVEb
.Op Cm +aCefnuvxIimqVEb
.Op Fl abCEefnuvxIimpqV
.Op Cm +abCEefnuvxIimpqV
.Ek
.Bk -words
.Op Fl o Ar option_name
@@ -299,6 +299,13 @@ section below.)
.It Fl b Em notify
Enable asynchronous notification of background job completion.
(Not implemented.)
.It Fl p Em nopriv
Do not attempt to reset effective uid if it does not match uid.
This is not set by default to help avoid incorrect usage by setuid
root programs via
.Xr system 3
or
.Xr popen 3 .
.It "\ \ " Em cdprint
Make an interactive shell always print the new directory name when
changed by the
@@ -1157,6 +1164,15 @@ matches a
.Dq \&[
rather than introducing a character class.
A character class matches any of the characters between the square brackets.
A named class of characters (see
.Xr wctype 3 )
may be specified by surrounding the name with
.Pq Dq [:
and
.Pq Dq :] .
For example,
.Pq Dq [[:alpha:]]
is a shell pattern that matches a single letter.
A range of characters may be specified using a minus sign
.Pq Dq - .
The character class may be complemented
@@ -1183,10 +1199,24 @@ be built in for efficiency (e.g.
.Xr test 1 ,
etc).
.Bl -tag -width 5n
.It :
.It : [ Ar arg ... ]
A null command that returns a 0 (true) exit value.
Any arguments are ignored.
.It \&. file
The commands in the specified file are read and executed by the shell.
The dot command reads and executes the commands from the specified
.Ar file
in the current shell environment.
The file does not need to be executable and is looked up from the directories
listed in the
.Ev PATH
variable if it does not contain a directory separator
.Pq Sq / .
The return command can be used for a premature return from the sourced file.
.Pp
The POSIX standard is unclear on how loop control keywords (break
and continue) behave across a dot command boundary.
This implementation allows them to control loops surrounding the dot command,
but obviously such behavior should not be relied on.
.It alias Op Ar name Ns Op Ar "=string ..."
If
.Ar name=string
@@ -1623,6 +1653,21 @@ With the
.Fl p
option specified the output will be formatted suitably for non-interactive use.
.Pp
.It return [ Ar n ]
Stop executing the current function or a dot command with return value of
.Ar n
or the value of the last executed command, if not specified.
For portability,
.Ar n
should be in the range from 0 to 255.
.Pp
The POSIX standard says that the results of
.Sq return
outside a function or a dot command are unspecified.
This implementation treats such a return as a no-op with a return value of 0
(success, true).
Use the exit command instead, if you want to return from a script or exit
your shell.
.It set Oo { Fl options | Cm +options | Cm \-- } Oc Ar arg ...
The
.Ic set
+13 -4
View File
@@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.35 2011/06/18 21:18:46 christos Exp $ */
/* $NetBSD: trap.c,v 1.37 2015/08/22 12:12:47 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
#else
__RCSID("$NetBSD: trap.c,v 1.35 2011/06/18 21:18:46 christos Exp $");
__RCSID("$NetBSD: trap.c,v 1.37 2015/08/22 12:12:47 christos Exp $");
#endif
#endif /* not lint */
@@ -77,8 +77,8 @@ __RCSID("$NetBSD: trap.c,v 1.35 2011/06/18 21:18:46 christos Exp $");
char *trap[NSIG+1]; /* trap handler commands */
MKINIT char sigmode[NSIG]; /* current value of signal */
volatile char gotsig[NSIG]; /* indicates specified signal received */
int pendingsigs; /* indicates some signal received */
static volatile char gotsig[NSIG];/* indicates specified signal received */
volatile int pendingsigs; /* indicates some signal received */
static int getsigaction(int, sig_t *);
@@ -421,7 +421,16 @@ done:
pendingsigs = 0;
}
int
lastsig(void)
{
int i;
for (i = NSIG; i > 0; i--)
if (gotsig[i - 1])
return i;
return SIGINT; /* XXX */
}
/*
* Controls whether the shell is interactive or not.
+3 -2
View File
@@ -1,4 +1,4 @@
/* $NetBSD: trap.h,v 1.20 2012/03/15 02:02:20 joerg Exp $ */
/* $NetBSD: trap.h,v 1.22 2015/08/22 12:12:47 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -34,7 +34,7 @@
* @(#)trap.h 8.3 (Berkeley) 6/5/95
*/
extern int pendingsigs;
extern volatile int pendingsigs;
void clear_traps(int);
sig_t setsignal(int, int);
@@ -43,3 +43,4 @@ void onsig(int);
void dotrap(void);
void setinteractive(int);
void exitshell(int) __dead;
int lastsig(void);
+15 -7
View File
@@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.43 2013/11/01 16:49:02 christos Exp $ */
/* $NetBSD: var.c,v 1.44 2015/05/26 21:35:15 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: var.c,v 1.43 2013/11/01 16:49:02 christos Exp $");
__RCSID("$NetBSD: var.c,v 1.44 2015/05/26 21:35:15 christos Exp $");
#endif
#endif /* not lint */
@@ -190,11 +190,19 @@ initvar(void)
if (find_var("PS1", &vpp, &vps1.name_len) == NULL) {
vps1.next = *vpp;
*vpp = &vps1;
vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
vps1.flags = VSTRFIXED|VTEXTFIXED;
vps1.text = NULL;
choose_ps1();
}
}
void
choose_ps1(void)
{
free(vps1.text);
vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
}
/*
* Safe version of setvar, returns 1 on success 0 on failure.
*/
@@ -575,11 +583,11 @@ exportcmd(int argc, char **argv)
char *name;
const char *p;
int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
int pflag;
int pflg;
pflag = nextopt("p") == 'p' ? 3 : 0;
if (argc <= 1 || pflag) {
showvars( pflag ? argv[0] : 0, flag, pflag );
pflg = nextopt("p") == 'p' ? 3 : 0;
if (argc <= 1 || pflg) {
showvars( pflg ? argv[0] : 0, flag, pflg );
return 0;
}
+2 -1
View File
@@ -1,4 +1,4 @@
/* $NetBSD: var.h,v 1.25 2011/06/18 21:18:46 christos Exp $ */
/* $NetBSD: var.h,v 1.26 2015/05/26 21:35:15 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -125,5 +125,6 @@ void mklocal(const char *, int);
void listmklocal(struct strlist *, int);
void poplocalvars(void);
int unsetvar(const char *, int);
void choose_ps1(void);
int setvarsafe(const char *, const char *, int);
void print_quoted(const char *);