diff options
author | peter <peter@FreeBSD.org> | 1996-05-27 01:41:12 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-05-27 01:41:12 +0000 |
commit | 60815f4c2969de69a3e09bfca9268c576198cbcb (patch) | |
tree | 9bfa90469c6e32a06ff7eff2333085ea8fe73123 | |
parent | 0291e848bc787305335af649ac14bc8fe5a19a49 (diff) | |
download | FreeBSD-src-60815f4c2969de69a3e09bfca9268c576198cbcb.zip FreeBSD-src-60815f4c2969de69a3e09bfca9268c576198cbcb.tar.gz |
Import the 4.4BSD-Lite2 /bin/sh sources
Requested by: joerg
(Note, this is mostly going to be conflicts, which is expected. Our entire
sh source has a mainline, so this should not change anything except for
a few new files appearing. I dont think they are a problem)
66 files changed, 2226 insertions, 1222 deletions
diff --git a/bin/sh/Makefile b/bin/sh/Makefile index 3114da6..efa2fe7 100644 --- a/bin/sh/Makefile +++ b/bin/sh/Makefile @@ -1,29 +1,28 @@ -# @(#)Makefile 8.1 (Berkeley) 6/8/93 +# @(#)Makefile 8.4 (Berkeley) 5/5/95 PROG= sh SRCS= alias.c builtins.c cd.c echo.c error.c eval.c exec.c expand.c \ histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \ - mystring.c nodes.c options.c parser.c printf.c redir.c show.c \ - signames.c syntax.c trap.c output.c var.c + mystring.c nodes.c options.c parser.c redir.c show.c syntax.c \ + trap.c output.c var.c OBJS+= init.o arith.o arith_lex.o -LDADD= -ll -ledit -ltermcap -lcompat +LDADD+= -ll -ledit -ltermcap LFLAGS= -8 # 8-bit lex scanner for arithmetic CFLAGS+=-DSHELL -I. -I${.CURDIR} .PATH: ${.CURDIR}/bltin ${.CURDIR}/../../usr.bin/printf CLEANFILES+=\ - builtins.c builtins.h init.c mkinit mknodes mksignames mksyntax \ - nodes.c nodes.h signames.c signames.h syntax.c syntax.h token.def \ - y.tab.h + builtins.c builtins.h init.c mkinit mknodes mksyntax \ + nodes.c nodes.h printf.o syntax.c syntax.h token.def y.tab.h .depend parser.o: token.def token.def: mktokens sh ${.CURDIR}/mktokens -builtins.h builtins.c: ${.CURDIR}/mkbuiltins ${.CURDIR}/builtins - cd ${.CURDIR}; sh mkbuiltins +builtins.h builtins.c: ${.CURDIR}/mkbuiltins ${.CURDIR}/builtins.def + cd ${.CURDIR}; sh mkbuiltins ${.OBJDIR} init.c: mkinit ${SRCS} - ./mkinit '${CC} -c ${CFLAGS} init.c' ${.ALLSRC} + ./mkinit '${CC} -c ${CFLAGS} init.c' ${.ALLSRC:S/^mkinit$//} mkinit: ${.CURDIR}/mkinit.c ${CC} ${CFLAGS} ${.CURDIR}/mkinit.c -o $@ @@ -34,12 +33,6 @@ nodes.c nodes.h: mknodes ${.CURDIR}/nodetypes ${.CURDIR}/nodes.c.pat mknodes: ${.CURDIR}/mknodes.c ${CC} ${CFLAGS} ${.CURDIR}/mknodes.c -o $@ -signames.c signames.h: mksignames - ./mksignames - -mksignames: ${.CURDIR}/mksignames.c - ${CC} ${CFLAGS} ${.CURDIR}/mksignames.c -o $@ - syntax.c syntax.h: mksyntax ./mksyntax diff --git a/bin/sh/alias.c b/bin/sh/alias.c index 3cf38a9..e235ddb 100644 --- a/bin/sh/alias.c +++ b/bin/sh/alias.c @@ -35,9 +35,10 @@ */ #ifndef lint -static char sccsid[] = "@(#)alias.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95"; #endif /* not lint */ +#include <stdlib.h> #include "shell.h" #include "input.h" #include "output.h" @@ -51,12 +52,15 @@ static char sccsid[] = "@(#)alias.c 8.1 (Berkeley) 5/31/93"; struct alias *atab[ATABSIZE]; +STATIC void setalias __P((char *, char *)); +STATIC int unalias __P((char *)); STATIC struct alias **hashalias __P((char *)); STATIC +void setalias(name, val) char *name, *val; - { +{ struct alias *ap, **app; app = hashalias(name); @@ -96,7 +100,7 @@ setalias(name, val) { int len = strlen(val); ap->val = ckmalloc(len + 2); - bcopy(val, ap->val, len); + memcpy(ap->val, val, len); ap->val[len] = ' '; /* fluff */ ap->val[len+1] = '\0'; } @@ -171,7 +175,8 @@ rmaliases() { struct alias * lookupalias(name, check) char *name; - { + int check; +{ struct alias *ap = *hashalias(name); for (; ap; ap = ap->next) { @@ -188,9 +193,11 @@ lookupalias(name, check) /* * TODO - sort output */ +int aliascmd(argc, argv) + int argc; char **argv; - { +{ char *n, *v; int ret = 0; struct alias *ap; @@ -205,7 +212,7 @@ aliascmd(argc, argv) } return (0); } - while (n = *++argv) { + while ((n = *++argv) != NULL) { if ((v = strchr(n+1, '=')) == NULL) /* n+1: funny ksh stuff */ if ((ap = lookupalias(n, 0)) == NULL) { outfmt(out2, "alias: %s not found\n", n); @@ -221,9 +228,11 @@ aliascmd(argc, argv) return (ret); } +int unaliascmd(argc, argv) + int argc; char **argv; - { +{ int i; while ((i = nextopt("a")) != '\0') { diff --git a/bin/sh/alias.h b/bin/sh/alias.h index adc56a9..279cff2 100644 --- a/bin/sh/alias.h +++ b/bin/sh/alias.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)alias.h 8.1 (Berkeley) 5/31/93 + * @(#)alias.h 8.2 (Berkeley) 5/4/95 */ #define ALIASINUSE 1 @@ -45,4 +45,7 @@ struct alias { int flag; }; -struct alias *lookupalias(); +struct alias *lookupalias __P((char *, int)); +int aliascmd __P((int, char **)); +int unaliascmd __P((int, char **)); +void rmaliases __P((void)); diff --git a/bin/sh/arith.h b/bin/sh/arith.h new file mode 100644 index 0000000..d6d7303 --- /dev/null +++ b/bin/sh/arith.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)arith.h 1.1 (Berkeley) 5/4/95 + */ + +int arith __P((char *)); +int expcmd __P((int , char **)); diff --git a/bin/sh/arith.y b/bin/sh/arith.y index 4b2e78f..e673788 100644 --- a/bin/sh/arith.y +++ b/bin/sh/arith.y @@ -1,13 +1,16 @@ -%token ARITH_OR ARITH_AND ARITH_ADD ARITH_SUBT ARITH_MULT ARITH_DIV ARITH_REM ARITH_EQ ARITH_GT ARITH_GEQ ARITH_LT ARITH_LEQ ARITH_NEQ -%token ARITH_NUM ARITH_LPAREN ARITH_RPAREN ARITH_NOT ARITH_UNARYMINUS +%token ARITH_NUM ARITH_LPAREN ARITH_RPAREN %left ARITH_OR %left ARITH_AND -%left ARITH_EQ ARITH_NEQ -%left ARITH_LT ARITH_GT ARITH_GEQ ARITH_LEQ -%left ARITH_ADD ARITH_SUBT -%left ARITH_MULT ARITH_DIV ARITH_REM -%left ARITH_UNARYMINUS ARITH_NOT +%left ARITH_BOR +%left ARITH_BXOR +%left ARITH_BAND +%left ARITH_EQ ARITH_NE +%left ARITH_LT ARITH_GT ARITH_GE ARITH_LE +%left ARITH_LSHIFT ARITH_RSHIFT +%left ARITH_ADD ARITH_SUB +%left ARITH_MUL ARITH_DIV ARITH_REM +%left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT %% exp: expr = { @@ -17,25 +20,36 @@ exp: expr = { expr: ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; } - | expr ARITH_OR expr = { $$ = $1 ? $1 : $3 ? $3 : 0; } - | expr ARITH_AND expr = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } - | expr ARITH_EQ expr = { $$ = $1 == $3; } - | expr ARITH_GT expr = { $$ = $1 > $3; } - | expr ARITH_GEQ expr = { $$ = $1 >= $3; } - | expr ARITH_LT expr = { $$ = $1 < $3; } - | expr ARITH_LEQ expr = { $$ = $1 <= $3; } - | expr ARITH_NEQ expr = { $$ = $1 != $3; } - | expr ARITH_ADD expr = { $$ = $1 + $3; } - | expr ARITH_SUBT expr = { $$ = $1 - $3; } - | expr ARITH_MULT expr = { $$ = $1 * $3; } - | expr ARITH_DIV expr = { + | expr ARITH_OR expr = { $$ = $1 ? $1 : $3 ? $3 : 0; } + | expr ARITH_AND expr = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } + | expr ARITH_BOR expr = { $$ = $1 | $3; } + | expr ARITH_BXOR expr = { $$ = $1 ^ $3; } + | expr ARITH_BAND expr = { $$ = $1 & $3; } + | expr ARITH_EQ expr = { $$ = $1 == $3; } + | expr ARITH_GT expr = { $$ = $1 > $3; } + | expr ARITH_GE expr = { $$ = $1 >= $3; } + | expr ARITH_LT expr = { $$ = $1 < $3; } + | expr ARITH_LE expr = { $$ = $1 <= $3; } + | expr ARITH_NE expr = { $$ = $1 != $3; } + | expr ARITH_LSHIFT expr = { $$ = $1 << $3; } + | expr ARITH_RSHIFT expr = { $$ = $1 >> $3; } + | expr ARITH_ADD expr = { $$ = $1 + $3; } + | expr ARITH_SUB expr = { $$ = $1 - $3; } + | expr ARITH_MUL expr = { $$ = $1 * $3; } + | expr ARITH_DIV expr = { if ($3 == 0) yyerror("division by zero"); $$ = $1 / $3; } - | expr ARITH_REM expr = { $$ = $1 % $3; } + | expr ARITH_REM expr = { + if ($3 == 0) + yyerror("division by zero"); + $$ = $1 % $3; + } | ARITH_NOT expr = { $$ = !($2); } - | ARITH_UNARYMINUS expr = { $$ = -($2); } + | ARITH_BNOT expr = { $$ = ~($2); } + | ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); } + | ARITH_ADD expr %prec ARITH_UNARYPLUS = { $$ = $2; } | ARITH_NUM ; %% @@ -76,7 +90,7 @@ expr: ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; } */ #ifndef lint -static char sccsid[] = "@(#)arith.y 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; #endif /* not lint */ #include "shell.h" @@ -86,13 +100,12 @@ static char sccsid[] = "@(#)arith.y 8.1 (Berkeley) 5/31/93"; char *arith_buf, *arith_startbuf; +int arith(s) char *s; { - extern arith_wasoper; long result; - arith_wasoper = 1; arith_buf = arith_startbuf = s; INTOFF; @@ -103,10 +116,10 @@ arith(s) return (result); } +void yyerror(s) char *s; { - extern yytext, yylval; yyerrok; yyclearin; @@ -117,7 +130,9 @@ yyerror(s) /* * The exp(1) builtin. */ +int expcmd(argc, argv) + int argc; char **argv; { char *p; diff --git a/bin/sh/arith_lex.l b/bin/sh/arith_lex.l index 0fb1c7b..6c0e279 100644 --- a/bin/sh/arith_lex.l +++ b/bin/sh/arith_lex.l @@ -36,14 +36,15 @@ */ #ifndef lint -static char sccsid[] = "@(#)arith_lex.l 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; #endif /* not lint */ +#include <unistd.h> #include "y.tab.h" +#include "error.h" extern yylval; extern char *arith_buf, *arith_startbuf; -int arith_wasoper; #undef YY_INPUT #define YY_INPUT(buf,result,max) \ result = (*buf = *arith_buf++) ? 1 : YY_NULL; @@ -51,36 +52,33 @@ int arith_wasoper; %% [ \t\n] { ; } -[0-9]+ { arith_wasoper = 0; yylval = atol(yytext); return(ARITH_NUM); } -"(" { arith_wasoper = 1; return(ARITH_LPAREN); } -")" { arith_wasoper = 0; return(ARITH_RPAREN); } -"||" { arith_wasoper = 1; return(ARITH_OR); } -"&&" { arith_wasoper = 1; return(ARITH_AND); } -"==" { arith_wasoper = 1; return(ARITH_EQ); } -">" { arith_wasoper = 1; return(ARITH_GT); } -">=" { arith_wasoper = 1; return(ARITH_GEQ); } -"<" { arith_wasoper = 1; return(ARITH_LT); } -"<=" { arith_wasoper = 1; return(ARITH_LEQ); } -"!=" { arith_wasoper = 1; return(ARITH_NEQ); } -"*" { arith_wasoper = 1; return(ARITH_MULT); } -"/" { arith_wasoper = 1; return(ARITH_DIV); } -"%" { arith_wasoper = 1; return(ARITH_REM); } -"+" { if (!arith_wasoper) { /* ignore unary plus */ - arith_wasoper = 1; - return(ARITH_ADD); - } - } -"-" { if (arith_wasoper) { - return(ARITH_UNARYMINUS); - } else { - arith_wasoper = 1; - return(ARITH_SUBT); - } - } -"!" { arith_wasoper = 1; return(ARITH_NOT); } +[0-9]+ { yylval = atol(yytext); return(ARITH_NUM); } +"(" { return(ARITH_LPAREN); } +")" { return(ARITH_RPAREN); } +"||" { return(ARITH_OR); } +"&&" { return(ARITH_AND); } +"|" { return(ARITH_BOR); } +"^" { return(ARITH_BXOR); } +"&" { return(ARITH_BAND); } +"==" { return(ARITH_EQ); } +"!=" { return(ARITH_NE); } +">" { return(ARITH_GT); } +">=" { return(ARITH_GE); } +"<" { return(ARITH_LT); } +"<=" { return(ARITH_LE); } +"<<" { return(ARITH_LSHIFT); } +">>" { return(ARITH_RSHIFT); } +"*" { return(ARITH_MUL); } +"/" { return(ARITH_DIV); } +"%" { return(ARITH_REM); } +"+" { return(ARITH_ADD); } +"-" { return(ARITH_SUB); } +"~" { return(ARITH_BNOT); } +"!" { return(ARITH_NOT); } . { error("arith: syntax error: \"%s\"\n", arith_startbuf); } %% +void arith_lex_reset() { YY_NEW_FILE; } diff --git a/bin/sh/bltin/bltin.h b/bin/sh/bltin/bltin.h index c8bf8d5..efaa926 100644 --- a/bin/sh/bltin/bltin.h +++ b/bin/sh/bltin/bltin.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)bltin.h 8.1 (Berkeley) 5/31/93 + * @(#)bltin.h 8.2 (Berkeley) 5/4/95 */ /* diff --git a/bin/sh/bltin/echo.1 b/bin/sh/bltin/echo.1 index d2cb8d1..bf5f891 100644 --- a/bin/sh/bltin/echo.1 +++ b/bin/sh/bltin/echo.1 @@ -33,9 +33,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)echo.1 8.1 (Berkeley) 5/31/93 +.\" @(#)echo.1 8.2 (Berkeley) 5/4/95 .\" -.Dd May 31, 1993 +.Dd May 4, 1995 .Dt ECHO 1 .Os BSD 4.4 .Sh NAME diff --git a/bin/sh/bltin/echo.c b/bin/sh/bltin/echo.c index c1d8970..97ab6c2 100644 --- a/bin/sh/bltin/echo.c +++ b/bin/sh/bltin/echo.c @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)echo.c 8.1 (Berkeley) 5/31/93 + * @(#)echo.c 8.2 (Berkeley) 5/4/95 */ /* @@ -46,7 +46,11 @@ /* #define eflag 1 */ -main(argc, argv) char **argv; { +int +main(argc, argv) + int argc; + char **argv; +{ register char **ap; register char *p; register char c; diff --git a/bin/sh/builtins.def b/bin/sh/builtins.def new file mode 100644 index 0000000..aa5b2c9 --- /dev/null +++ b/bin/sh/builtins.def @@ -0,0 +1,90 @@ +#!/bin/sh - +# +# 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. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# @(#)builtins.def 8.4 (Berkeley) 5/4/95 + +# +# This file lists all the builtin commands. The first column is the name +# of a C routine. The -j flag, if present, specifies that this command +# is to be excluded from systems without job control, and the -h flag, +# if present specifies that this command is to be excluded from systems +# based on the NO_HISTORY compile-time symbol. The rest of the line +# specifies the command name or names used to run the command. The entry +# for bltincmd, which is run when the user does not specify a command, must +# come first. +# +# NOTE: bltincmd must come first! + +bltincmd command +#alloccmd alloc +bgcmd -j bg +breakcmd break continue +#catfcmd catf +cdcmd cd chdir +dotcmd . +echocmd echo +evalcmd eval +execcmd exec +exitcmd exit +expcmd exp let +exportcmd export readonly +#exprcmd expr test [ +falsecmd false +histcmd -h fc +fgcmd -j fg +getoptscmd getopts +hashcmd hash +jobidcmd jobid +jobscmd jobs +#linecmd line +localcmd local +#nlechocmd nlecho +#printfcmd printf +pwdcmd pwd +readcmd read +returncmd return +setcmd set +setvarcmd setvar +shiftcmd shift +trapcmd trap +truecmd : true +umaskcmd umask +unaliascmd unalias +unsetcmd unset +waitcmd wait +#foocmd foo +aliascmd alias +ulimitcmd ulimit diff --git a/bin/sh/cd.c b/bin/sh/cd.c index d1984d9..4f363a3 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -35,9 +35,15 @@ */ #ifndef lint -static char sccsid[] = "@(#)cd.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + /* * The cd and pwd commands. */ @@ -50,31 +56,24 @@ static char sccsid[] = "@(#)cd.c 8.1 (Berkeley) 5/31/93"; #include "output.h" #include "memalloc.h" #include "error.h" +#include "redir.h" #include "mystring.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> - - -#ifdef __STDC__ -STATIC int docd(char *, int); -STATIC void updatepwd(char *); -STATIC void getpwd(void); -STATIC char *getcomponent(void); -#else -STATIC int docd(); -STATIC void updatepwd(); -STATIC void getpwd(); -STATIC char *getcomponent(); -#endif +#include "show.h" +STATIC int docd __P((char *, int)); +STATIC char *getcomponent __P((void)); +STATIC void updatepwd __P((char *)); +STATIC void getpwd __P((void)); char *curdir; /* current working directory */ char *prevdir; /* previous working directory */ STATIC char *cdcomppath; int -cdcmd(argc, argv) char **argv; { +cdcmd(argc, argv) + int argc; + char **argv; +{ char *dest; char *path; char *p; @@ -92,8 +91,7 @@ cdcmd(argc, argv) char **argv; { if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL) path = nullstr; while ((p = padvance(&path, dest)) != NULL) { - if (stat(p, &statb) >= 0 - && (statb.st_mode & S_IFMT) == S_IFDIR) { + if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { if (!print) { /* * XXX - rethink @@ -108,6 +106,8 @@ cdcmd(argc, argv) char **argv; { } } error("can't cd to %s", dest); + /*NOTREACHED*/ + return 0; } @@ -145,7 +145,8 @@ docd(dest, print) STATIC int docd(dest, print) char *dest; - { + int print; +{ register char *p; register char *q; char *symlink; @@ -165,7 +166,7 @@ top: } first = 1; while ((q = getcomponent()) != NULL) { - if (q[0] == '\0' || q[0] == '.' && q[1] == '\0') + if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0')) continue; if (! first) STPUTC('/', p); @@ -178,7 +179,7 @@ top: STACKSTRNUL(p); if (lstat(stackblock(), &statb) < 0) error("lstat %s failed", stackblock()); - if ((statb.st_mode & S_IFMT) != S_IFLNK) + if (!S_ISLNK(statb.st_mode)) continue; /* Hit a symbolic link. We have to start all over again. */ @@ -308,7 +309,10 @@ updatepwd(dir) int -pwdcmd(argc, argv) char **argv; { +pwdcmd(argc, argv) + int argc; + char **argv; +{ getpwd(); out1str(curdir); out1c('\n'); @@ -355,7 +359,7 @@ getpwd() { pip[1] = -1; p = buf; while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0 - || i == -1 && errno == EINTR) { + || (i == -1 && errno == EINTR)) { if (i > 0) p += i; } diff --git a/bin/sh/error.c b/bin/sh/error.c index b6853b6..d175451 100644 --- a/bin/sh/error.c +++ b/bin/sh/error.c @@ -35,7 +35,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)error.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ /* @@ -47,12 +47,9 @@ static char sccsid[] = "@(#)error.c 8.1 (Berkeley) 5/31/93"; #include "options.h" #include "output.h" #include "error.h" +#include "show.h" #include <signal.h> -#ifdef __STDC__ -#include "stdarg.h" -#else -#include <varargs.h> -#endif +#include <unistd.h> #include <errno.h> @@ -74,7 +71,9 @@ char *commandname; */ void -exraise(e) { +exraise(e) + int e; +{ if (handler == NULL) abort(); exception = e; @@ -94,14 +93,15 @@ exraise(e) { void onint() { + sigset_t sigset; + if (suppressint) { intpending++; return; } intpending = 0; -#ifdef BSD - sigsetmask(0); -#endif + sigemptyset(&sigset); + sigprocmask(SIG_SETMASK, &sigset, NULL); if (rootshell && iflag) exraise(EXINT); else @@ -124,21 +124,23 @@ error2(a, b) * formatting. It then raises the error exception. */ -#ifdef __STDC__ +#if __STDC__ void -error(char *msg, ...) { +error(char *msg, ...) #else void error(va_alist) va_dcl - { +#endif +{ +#if !__STDC__ char *msg; #endif va_list ap; - CLEAR_PENDING_INT; INTOFF; -#ifdef __STDC__ + +#if __STDC__ va_start(ap, msg); #else va_start(ap); @@ -177,55 +179,57 @@ struct errname { #define ALL (E_OPEN|E_CREAT|E_EXEC) STATIC const struct errname errormsg[] = { - EINTR, ALL, "interrupted", - EACCES, ALL, "permission denied", - EIO, ALL, "I/O error", - ENOENT, E_OPEN, "no such file", - ENOENT, E_CREAT, "directory nonexistent", - ENOENT, E_EXEC, "not found", - ENOTDIR, E_OPEN, "no such file", - ENOTDIR, E_CREAT, "directory nonexistent", - ENOTDIR, E_EXEC, "not found", - EISDIR, ALL, "is a directory", -/* EMFILE, ALL, "too many open files", */ - ENFILE, ALL, "file table overflow", - ENOSPC, ALL, "file system full", + { EINTR, ALL, "interrupted" }, + { EACCES, ALL, "permission denied" }, + { EIO, ALL, "I/O error" }, + { ENOENT, E_OPEN, "no such file" }, + { ENOENT, E_CREAT,"directory nonexistent" }, + { ENOENT, E_EXEC, "not found" }, + { ENOTDIR, E_OPEN, "no such file" }, + { ENOTDIR, E_CREAT,"directory nonexistent" }, + { ENOTDIR, E_EXEC, "not found" }, + { EISDIR, ALL, "is a directory" }, +#ifdef notdef + { EMFILE, ALL, "too many open files" }, +#endif + { ENFILE, ALL, "file table overflow" }, + { ENOSPC, ALL, "file system full" }, #ifdef EDQUOT - EDQUOT, ALL, "disk quota exceeded", + { EDQUOT, ALL, "disk quota exceeded" }, #endif #ifdef ENOSR - ENOSR, ALL, "no streams resources", + { ENOSR, ALL, "no streams resources" }, #endif - ENXIO, ALL, "no such device or address", - EROFS, ALL, "read-only file system", - ETXTBSY, ALL, "text busy", + { ENXIO, ALL, "no such device or address" }, + { EROFS, ALL, "read-only file system" }, + { ETXTBSY, ALL, "text busy" }, #ifdef SYSV - EAGAIN, E_EXEC, "not enough memory", + { EAGAIN, E_EXEC, "not enough memory" }, #endif - ENOMEM, ALL, "not enough memory", + { ENOMEM, ALL, "not enough memory" }, #ifdef ENOLINK - ENOLINK, ALL, "remote access failed", + { ENOLINK, ALL, "remote access failed" }, #endif #ifdef EMULTIHOP - EMULTIHOP, ALL, "remote access failed", + { EMULTIHOP, ALL, "remote access failed" }, #endif #ifdef ECOMM - ECOMM, ALL, "remote access failed", + { ECOMM, ALL, "remote access failed" }, #endif #ifdef ESTALE - ESTALE, ALL, "remote access failed", + { ESTALE, ALL, "remote access failed" }, #endif #ifdef ETIMEDOUT - ETIMEDOUT, ALL, "remote access failed", + { ETIMEDOUT, ALL, "remote access failed" }, #endif #ifdef ELOOP - ELOOP, ALL, "symbolic link loop", + { ELOOP, ALL, "symbolic link loop" }, #endif - E2BIG, E_EXEC, "argument list too long", + { E2BIG, E_EXEC, "argument list too long" }, #ifdef ELIBACC - ELIBACC, E_EXEC, "shared library missing", + { ELIBACC, E_EXEC, "shared library missing" }, #endif - 0, 0, NULL + { 0, 0, NULL }, }; @@ -236,7 +240,10 @@ STATIC const struct errname errormsg[] = { */ char * -errmsg(e, action) { +errmsg(e, action) + int e; + int action; +{ struct errname const *ep; static char buf[12]; diff --git a/bin/sh/error.h b/bin/sh/error.h index 8f87caf..a38ab7c 100644 --- a/bin/sh/error.h +++ b/bin/sh/error.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)error.h 8.1 (Berkeley) 5/31/93 + * @(#)error.h 8.2 (Berkeley) 5/4/95 */ /* @@ -82,24 +82,16 @@ extern volatile int intpending; extern char *commandname; /* name of command--printed on error */ #define INTOFF suppressint++ -#define INTON if (--suppressint == 0 && intpending) onint(); else +#define INTON { if (--suppressint == 0 && intpending) onint(); } #define FORCEINTON {suppressint = 0; if (intpending) onint();} #define CLEAR_PENDING_INT intpending = 0 #define int_pending() intpending -#ifdef __STDC__ -void exraise(int); -void onint(void); -void error2(char *, char *); -void error(char *, ...); -char *errmsg(int, int); -#else -void exraise(); -void onint(); -void error2(); -void error(); -char *errmsg(); -#endif +void exraise __P((int)); +void onint __P((void)); +void error2 __P((char *, char *)); +void error __P((char *, ...)); +char *errmsg __P((int, int)); /* diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 48a9f99..d02b943 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -35,9 +35,12 @@ */ #ifndef lint -static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; #endif /* not lint */ +#include <signal.h> +#include <unistd.h> + /* * Evaluate a command. */ @@ -59,9 +62,11 @@ static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 5/31/93"; #include "var.h" #include "memalloc.h" #include "error.h" +#include "show.h" #include "mystring.h" +#ifndef NO_HISTORY #include "myhistedit.h" -#include <signal.h> +#endif /* flags in argument to evaltree */ @@ -84,28 +89,17 @@ int funcnest; /* depth of function calls */ char *commandname; struct strlist *cmdenviron; int exitstatus; /* exit status of last command */ +int oexitstatus; /* saved exit status */ -#ifdef __STDC__ -STATIC void evalloop(union node *); -STATIC void evalfor(union node *); -STATIC void evalcase(union node *, int); -STATIC void evalsubshell(union node *, int); -STATIC void expredir(union node *); -STATIC void evalpipe(union node *); -STATIC void evalcommand(union node *, int, struct backcmd *); -STATIC void prehash(union node *); -#else -STATIC void evalloop(); -STATIC void evalfor(); -STATIC void evalcase(); -STATIC void evalsubshell(); -STATIC void expredir(); -STATIC void evalpipe(); -STATIC void evalcommand(); -STATIC void prehash(); -#endif - +STATIC void evalloop __P((union node *)); +STATIC void evalfor __P((union node *)); +STATIC void evalcase __P((union node *, int)); +STATIC void evalsubshell __P((union node *, int)); +STATIC void expredir __P((union node *)); +STATIC void evalpipe __P((union node *)); +STATIC void evalcommand __P((union node *, int, struct backcmd *)); +STATIC void prehash __P((union node *)); /* @@ -132,7 +126,9 @@ SHELLPROC { * The eval commmand. */ +int evalcmd(argc, argv) + int argc; char **argv; { char *p; @@ -191,14 +187,17 @@ evalstring(s) void evaltree(n, flags) union node *n; - { + int flags; +{ if (n == NULL) { TRACE(("evaltree(NULL) called\n")); exitstatus = 0; goto out; } +#ifndef NO_HISTORY displayhist = 1; /* show history substitutions done with fc */ - TRACE(("evaltree(0x%x: %d) called\n", (int)n, n->type)); +#endif + TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type)); switch (n->type) { case NSEMI: evaltree(n->nbinary.ch1, 0); @@ -231,19 +230,17 @@ evaltree(n, flags) evalsubshell(n, flags); break; case NIF: { - int status = 0; + int status; evaltree(n->nif.test, EV_TESTED); + status = exitstatus; + exitstatus = 0; if (evalskip) goto out; - if (exitstatus == 0) { + if (status == 0) evaltree(n->nif.ifpart, flags); - status = exitstatus; - } else if (n->nif.elsepart) { + else if (n->nif.elsepart) evaltree(n->nif.elsepart, flags); - status = exitstatus; - } - exitstatus = status; break; } case NWHILE: @@ -287,7 +284,7 @@ out: STATIC void evalloop(n) union node *n; - { +{ int status; loopnest++; @@ -323,8 +320,8 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { STATIC void evalfor(n) - union node *n; - { + union node *n; +{ struct arglist arglist; union node *argp; struct strlist *sp; @@ -333,6 +330,7 @@ evalfor(n) setstackmark(&smark); arglist.lastp = &arglist.list; for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { + oexitstatus = exitstatus; expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); if (evalskip) goto out; @@ -364,7 +362,8 @@ out: STATIC void evalcase(n, flags) union node *n; - { + int flags; +{ union node *cp; union node *patp; struct arglist arglist; @@ -372,6 +371,7 @@ evalcase(n, flags) setstackmark(&smark); arglist.lastp = &arglist.list; + oexitstatus = exitstatus; expandarg(n->ncase.expr, &arglist, EXP_TILDE); for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) { for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { @@ -396,7 +396,8 @@ out: STATIC void evalsubshell(n, flags) union node *n; - { + int flags; +{ struct job *jp; int backgnd = (n->type == NBACKGND); @@ -424,17 +425,27 @@ evalsubshell(n, flags) STATIC void expredir(n) union node *n; - { +{ register union node *redir; for (redir = n ; redir ; redir = redir->nfile.next) { - if (redir->type == NFROM - || redir->type == NTO - || redir->type == NAPPEND) { - struct arglist fn; - fn.lastp = &fn.list; + struct arglist fn; + fn.lastp = &fn.list; + oexitstatus = exitstatus; + switch (redir->type) { + case NFROM: + case NTO: + case NAPPEND: expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); redir->nfile.expfname = fn.list->text; + break; + case NFROMFD: + case NTOFD: + if (redir->ndup.vname) { + expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE); + fixredir(redir, fn.list->text, 1); + } + break; } } } @@ -451,14 +462,14 @@ expredir(n) STATIC void evalpipe(n) union node *n; - { +{ struct job *jp; struct nodelist *lp; int pipelen; int prevfd; int pip[2]; - TRACE(("evalpipe(0x%x) called\n", (int)n)); + TRACE(("evalpipe(0x%lx) called\n", (long)n)); pipelen = 0; for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) pipelen++; @@ -518,7 +529,7 @@ void evalbackcmd(n, result) union node *n; struct backcmd *result; - { +{ int pip[2]; struct job *jp; struct stackmark smark; /* unnecessary */ @@ -528,12 +539,15 @@ evalbackcmd(n, result) result->buf = NULL; result->nleft = 0; result->jp = NULL; - exitstatus = 0; - if (n == NULL) + if (n == NULL) { + exitstatus = 0; goto out; + } if (n->type == NCMD) { + exitstatus = oexitstatus; evalcommand(n, EV_BACKCMD, result); } else { + exitstatus = 0; if (pipe(pip) < 0) error("Pipe call failed"); jp = makejob(n, 1); @@ -566,8 +580,9 @@ out: STATIC void evalcommand(cmd, flags, backcmd) union node *cmd; + int flags; struct backcmd *backcmd; - { +{ struct stackmark smark; union node *argp; struct arglist arglist; @@ -577,7 +592,6 @@ evalcommand(cmd, flags, backcmd) char **envp; int varflag; struct strlist *sp; - register char *p; int mode; int pip[2]; struct cmdentry cmdentry; @@ -589,15 +603,24 @@ evalcommand(cmd, flags, backcmd) struct localvar *volatile savelocalvars; volatile int e; char *lastarg; +#if __GNUC__ + /* Avoid longjmp clobbering */ + (void) &argv; + (void) &argc; + (void) &lastarg; + (void) &flags; +#endif /* First expand the arguments. */ - TRACE(("evalcommand(0x%x, %d) called\n", (int)cmd, flags)); + TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); setstackmark(&smark); arglist.lastp = &arglist.list; varlist.lastp = &varlist.list; varflag = 1; + oexitstatus = exitstatus; + exitstatus = 0; for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { - p = argp->narg.text; + char *p = argp->narg.text; if (varflag && is_name(*p)) { do { p++; @@ -648,9 +671,20 @@ evalcommand(cmd, flags, backcmd) cmdentry.cmdtype = CMDBUILTIN; cmdentry.u.index = BLTINCMD; } else { - find_command(argv[0], &cmdentry, 1); + static const char PATH[] = "PATH="; + char *path = pathval(); + + /* + * Modify the command lookup path, if a PATH= assignment + * is present + */ + for (sp = varlist.list ; sp ; sp = sp->next) + if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) + path = sp->text + sizeof(PATH) - 1; + + find_command(argv[0], &cmdentry, 1, path); if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ - exitstatus = 2; + exitstatus = 1; flushout(&errout); return; } @@ -662,7 +696,7 @@ evalcommand(cmd, flags, backcmd) break; if ((cmdentry.u.index = find_builtin(*argv)) < 0) { outfmt(&errout, "%s: not found\n", *argv); - exitstatus = 2; + exitstatus = 1; flushout(&errout); return; } @@ -674,11 +708,11 @@ evalcommand(cmd, flags, backcmd) /* Fork off a child process if necessary. */ if (cmd->ncmd.backgnd - || cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0 - || (flags & EV_BACKCMD) != 0 + || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) + || ((flags & EV_BACKCMD) != 0 && (cmdentry.cmdtype != CMDBUILTIN || cmdentry.u.index == DOTCMD - || cmdentry.u.index == EVALCMD)) { + || cmdentry.u.index == EVALCMD))) { jp = makejob(cmd, 1); mode = cmd->ncmd.backgnd; if (flags & EV_BACKCMD) { @@ -787,7 +821,9 @@ cmddone: if (e != EXERROR || cmdentry.u.index == BLTINCMD || cmdentry.u.index == DOTCMD || cmdentry.u.index == EVALCMD +#ifndef NO_HISTORY || cmdentry.u.index == HISTCMD +#endif || cmdentry.u.index == EXECCMD) exraise(e); FORCEINTON; @@ -803,16 +839,10 @@ cmddone: trputs("normal command: "); trargs(argv); clearredir(); redirect(cmd->ncmd.redirect, 0); - if (varlist.list) { - p = stalloc(strlen(pathval()) + 1); - scopy(pathval(), p); - } else { - p = pathval(); - } for (sp = varlist.list ; sp ; sp = sp->next) setvareq(sp->text, VEXPORT|VSTACK); envp = environment(); - shellexec(argv, envp, p, cmdentry.u.index); + shellexec(argv, envp, pathval(), cmdentry.u.index); /*NOTREACHED*/ } goto out; @@ -846,11 +876,13 @@ out: STATIC void prehash(n) union node *n; - { +{ struct cmdentry entry; - if (n->type == NCMD && goodname(n->ncmd.args->narg.text)) - find_command(n->ncmd.args->narg.text, &entry, 0); + if (n->type == NCMD && n->ncmd.args) + if (goodname(n->ncmd.args->narg.text)) + find_command(n->ncmd.args->narg.text, &entry, 0, + pathval()); } @@ -865,8 +897,16 @@ prehash(n) * specified variables. */ -bltincmd(argc, argv) char **argv; { +int +bltincmd(argc, argv) + int argc; + char **argv; +{ listsetvar(cmdenviron); + /* + * Preserve exitstatus of a previous possible redirection + * as POSIX mandates + */ return exitstatus; } @@ -882,7 +922,11 @@ bltincmd(argc, argv) char **argv; { * in the standard shell so we don't make it one here. */ -breakcmd(argc, argv) char **argv; { +int +breakcmd(argc, argv) + int argc; + char **argv; +{ int n; n = 1; @@ -902,7 +946,11 @@ breakcmd(argc, argv) char **argv; { * The return command. */ -returncmd(argc, argv) char **argv; { +int +returncmd(argc, argv) + int argc; + char **argv; +{ int ret; ret = exitstatus; @@ -916,16 +964,37 @@ returncmd(argc, argv) char **argv; { } -truecmd(argc, argv) char **argv; { +int +falsecmd(argc, argv) + int argc; + char **argv; +{ + return 1; +} + + +int +truecmd(argc, argv) + int argc; + char **argv; +{ return 0; } -execcmd(argc, argv) char **argv; { +int +execcmd(argc, argv) + int argc; + char **argv; +{ if (argc > 1) { + struct strlist *sp; + iflag = 0; /* exit on error */ mflag = 0; optschanged(); + for (sp = cmdenviron; sp ; sp = sp->next) + setvareq(sp->text, VEXPORT|VSTACK); shellexec(argv + 1, environment(), pathval(), 0); } diff --git a/bin/sh/eval.h b/bin/sh/eval.h index 5789bcb..ab852fc 100644 --- a/bin/sh/eval.h +++ b/bin/sh/eval.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)eval.h 8.1 (Berkeley) 5/31/93 + * @(#)eval.h 8.2 (Berkeley) 5/4/95 */ extern char *commandname; /* currently executing command */ @@ -48,17 +48,17 @@ struct backcmd { /* result of evalbackcmd */ struct job *jp; /* job structure for command */ }; - -#ifdef __STDC__ -void evalstring(char *); +int evalcmd __P((int, char **)); +void evalstring __P((char *)); union node; /* BLETCH for ansi C */ -void evaltree(union node *, int); -void evalbackcmd(union node *, struct backcmd *); -#else -void evalstring(); -void evaltree(); -void evalbackcmd(); -#endif +void evaltree __P((union node *, int)); +void evalbackcmd __P((union node *, struct backcmd *)); +int bltincmd __P((int, char **)); +int breakcmd __P((int, char **)); +int returncmd __P((int, char **)); +int falsecmd __P((int, char **)); +int truecmd __P((int, char **)); +int execcmd __P((int, char **)); /* in_function returns nonzero if we are currently evaluating a function */ #define in_function() funcnest diff --git a/bin/sh/exec.c b/bin/sh/exec.c index 30c7f73..525bf0e 100644 --- a/bin/sh/exec.c +++ b/bin/sh/exec.c @@ -35,9 +35,16 @@ */ #ifndef lint -static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdlib.h> + /* * When commands are first encountered, they are entered in a hash table. * This ensures that a full path search will not have to be done for them @@ -64,11 +71,8 @@ static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 5/31/93"; #include "error.h" #include "init.h" #include "mystring.h" +#include "show.h" #include "jobs.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> #define CMDTABLESIZE 31 /* should be prime */ @@ -89,21 +93,12 @@ STATIC struct tblentry *cmdtable[CMDTABLESIZE]; STATIC int builtinloc = -1; /* index in path of %builtin, or -1 */ -#ifdef __STDC__ -STATIC void tryexec(char *, char **, char **); -STATIC void execinterp(char **, char **); -STATIC void printentry(struct tblentry *, int); -STATIC void clearcmdentry(int); -STATIC struct tblentry *cmdlookup(char *, int); -STATIC void delete_cmd_entry(void); -#else -STATIC void tryexec(); -STATIC void execinterp(); -STATIC void printentry(); -STATIC void clearcmdentry(); -STATIC struct tblentry *cmdlookup(); -STATIC void delete_cmd_entry(); -#endif +STATIC void tryexec __P((char *, char **, char **)); +STATIC void execinterp __P((char **, char **)); +STATIC void printentry __P((struct tblentry *, int)); +STATIC void clearcmdentry __P((int)); +STATIC struct tblentry *cmdlookup __P((char *, int)); +STATIC void delete_cmd_entry __P((void)); @@ -116,7 +111,8 @@ void shellexec(argv, envp, path, index) char **argv, **envp; char *path; - { + int index; +{ char *cmdname; int e; @@ -145,7 +141,9 @@ tryexec(cmd, argv, envp) char **envp; { int e; +#ifndef BSD char *p; +#endif #ifdef SYSV do { @@ -284,7 +282,7 @@ padvance(path, name) growstackblock(); q = stackblock(); if (p != start) { - bcopy(start, q, p - start); + memcpy(q, start, p - start); q += p - start; *q++ = '/'; } @@ -306,7 +304,11 @@ padvance(path, name) /*** Command hashing code ***/ -hashcmd(argc, argv) char **argv; { +int +hashcmd(argc, argv) + int argc; + char **argv; +{ struct tblentry **pp; struct tblentry *cmdp; int c; @@ -333,9 +335,9 @@ hashcmd(argc, argv) char **argv; { while ((name = *argptr) != NULL) { if ((cmdp = cmdlookup(name, 0)) != NULL && (cmdp->cmdtype == CMDNORMAL - || cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) + || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) delete_cmd_entry(); - find_command(name, &entry, 1); + find_command(name, &entry, 1, pathval()); if (verbose) { if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */ cmdp = cmdlookup(name, 0); @@ -396,14 +398,15 @@ printentry(cmdp, verbose) */ void -find_command(name, entry, printerr) +find_command(name, entry, printerr, path) char *name; struct cmdentry *entry; - { + int printerr; + char *path; +{ struct tblentry *cmdp; int index; int prev; - char *path; char *fullname; struct stat statb; int e; @@ -439,7 +442,6 @@ find_command(name, entry, printerr) prev = cmdp->param.index; } - path = pathval(); e = ENOENT; index = -1; loop: @@ -479,7 +481,7 @@ loop: goto loop; } e = EACCES; /* if we fail, this will be the error */ - if ((statb.st_mode & S_IFMT) != S_IFREG) + if (!S_ISREG(statb.st_mode)) goto loop; if (pathopt) { /* this is a %func directory */ stalloc(strlen(fullname) + 1); @@ -533,8 +535,8 @@ success: int find_builtin(name) char *name; - { - const register struct builtincmd *bp; +{ + register const struct builtincmd *bp; for (bp = builtincmd ; bp->name ; bp++) { if (*bp->name == *name && equal(bp->name, name)) @@ -558,7 +560,7 @@ hashcd() { for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { if (cmdp->cmdtype == CMDNORMAL - || cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0) + || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) cmdp->rehash = 1; } } @@ -575,25 +577,22 @@ hashcd() { void changepath(newval) char *newval; - { +{ char *old, *new; int index; int firstchange; int bltin; - int hasdot; old = pathval(); new = newval; firstchange = 9999; /* assume no change */ - index = hasdot = 0; + index = 0; bltin = -1; - if (*new == ':') - hasdot++; for (;;) { if (*old != *new) { firstchange = index; - if (*old == '\0' && *new == ':' - || *old == ':' && *new == '\0') + if ((*old == '\0' && *new == ':') + || (*old == ':' && *new == '\0')) firstchange++; old = new; /* ignore subsequent differences */ } @@ -602,17 +601,10 @@ changepath(newval) if (*new == '%' && bltin < 0 && prefix("builtin", new + 1)) bltin = index; if (*new == ':') { - char c = *(new+1); - index++; - if (c == ':' || c == '\0' || (c == '.' && - ((c = *(new+2)) == ':' || c == '\0'))) - hasdot++; } new++, old++; } - if (hasdot && geteuid() == 0) - out2str("sh: warning: running as root with dot in PATH\n"); if (builtinloc < 0 && bltin >= 0) builtinloc = bltin; /* zap builtins */ if (builtinloc >= 0 && bltin < 0) @@ -628,7 +620,9 @@ changepath(newval) */ STATIC void -clearcmdentry(firstchange) { +clearcmdentry(firstchange) + int firstchange; +{ struct tblentry **tblp; struct tblentry **pp; struct tblentry *cmdp; @@ -637,8 +631,10 @@ clearcmdentry(firstchange) { for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { pp = tblp; while ((cmdp = *pp) != NULL) { - if (cmdp->cmdtype == CMDNORMAL && cmdp->param.index >= firstchange - || cmdp->cmdtype == CMDBUILTIN && builtinloc >= firstchange) { + if ((cmdp->cmdtype == CMDNORMAL && + cmdp->param.index >= firstchange) + || (cmdp->cmdtype == CMDBUILTIN && + builtinloc >= firstchange)) { *pp = cmdp->next; ckfree(cmdp); } else { @@ -700,7 +696,8 @@ struct tblentry **lastcmdentry; STATIC struct tblentry * cmdlookup(name, add) char *name; - { + int add; +{ int hashval; register char *p; struct tblentry *cmdp; diff --git a/bin/sh/exec.h b/bin/sh/exec.h index a82b0d1..a278315 100644 --- a/bin/sh/exec.h +++ b/bin/sh/exec.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)exec.h 8.1 (Berkeley) 5/31/93 + * @(#)exec.h 8.3 (Berkeley) 6/8/95 */ /* values of cmdtype */ @@ -54,22 +54,15 @@ struct cmdentry { extern char *pathopt; /* set by padvance */ -#ifdef __STDC__ -void shellexec(char **, char **, char *, int); -char *padvance(char **, char *); -void find_command(char *, struct cmdentry *, int); -int find_builtin(char *); -void hashcd(void); -void changepath(char *); -void defun(char *, union node *); -int unsetfunc(char *); -#else -void shellexec(); -char *padvance(); -void find_command(); -int find_builtin(); -void hashcd(); -void changepath(); -void defun(); -int unsetfunc(); -#endif +void shellexec __P((char **, char **, char *, int)); +char *padvance __P((char **, char *)); +int hashcmd __P((int, char **)); +void find_command __P((char *, struct cmdentry *, int, char *)); +int find_builtin __P((char *)); +void hashcd __P((void)); +void changepath __P((char *)); +void deletefuncs __P((void)); +void getcmdentry __P((char *, struct cmdentry *)); +void addcmdentry __P((char *, struct cmdentry *)); +void defun __P((char *, union node *)); +int unsetfunc __P((char *)); diff --git a/bin/sh/expand.c b/bin/sh/expand.c index edee495..186da7a 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -35,9 +35,18 @@ */ #ifndef lint -static char sccsid[] = "@(#)expand.c 8.2 (Berkeley) 10/22/93"; +static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <errno.h> +#include <dirent.h> +#include <unistd.h> +#include <pwd.h> +#include <stdlib.h> + /* * Routines to expand arguments to commands. We have to deal with * backquotes, shell variables, and file metacharacters. @@ -58,12 +67,8 @@ static char sccsid[] = "@(#)expand.c 8.2 (Berkeley) 10/22/93"; #include "memalloc.h" #include "error.h" #include "mystring.h" -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <errno.h> -#include <dirent.h> -#include <pwd.h> +#include "arith.h" +#include "show.h" /* * Structure specifying which parts of the string should be searched @@ -84,39 +89,22 @@ struct ifsregion ifsfirst; /* first struct in list of ifs regions */ struct ifsregion *ifslastp; /* last struct in list */ struct arglist exparg; /* holds expanded arg list */ -#ifdef __STDC__ -STATIC void argstr(char *, int); -STATIC void expbackq(union node *, int, int); -STATIC char *evalvar(char *, int); -STATIC int varisset(int); -STATIC void varvalue(int, int, int); -STATIC void recordregion(int, int, int); -STATIC void ifsbreakup(char *, struct arglist *); -STATIC void expandmeta(struct strlist *, int); -STATIC void expmeta(char *, char *); -STATIC void expari(int); -STATIC void addfname(char *); -STATIC struct strlist *expsort(struct strlist *); -STATIC struct strlist *msort(struct strlist *, int); -STATIC int pmatch(char *, char *); -STATIC char *exptilde(char *, int); -#else -STATIC void argstr(); -STATIC void expbackq(); -STATIC char *evalvar(); -STATIC int varisset(); -STATIC void varvalue(); -STATIC void recordregion(); -STATIC void ifsbreakup(); -STATIC void expandmeta(); -STATIC void expmeta(); -STATIC void expari(); -STATIC void addfname(); -STATIC struct strlist *expsort(); -STATIC struct strlist *msort(); -STATIC int pmatch(); -STATIC char *exptilde(); -#endif +STATIC void argstr __P((char *, int)); +STATIC char *exptilde __P((char *, int)); +STATIC void expbackq __P((union node *, int, int)); +STATIC int subevalvar __P((char *, char *, int, int, int)); +STATIC char *evalvar __P((char *, int)); +STATIC int varisset __P((int)); +STATIC void varvalue __P((int, int, int)); +STATIC void recordregion __P((int, int, int)); +STATIC void ifsbreakup __P((char *, struct arglist *)); +STATIC void expandmeta __P((struct strlist *, int)); +STATIC void expmeta __P((char *, char *)); +STATIC void addfname __P((char *)); +STATIC struct strlist *expsort __P((struct strlist *)); +STATIC struct strlist *msort __P((struct strlist *, int)); +STATIC int pmatch __P((char *, char *)); +STATIC char *cvtnum __P((int, char *)); /* * Expand shell variables and backquotes inside a here document. @@ -144,7 +132,8 @@ void expandarg(arg, arglist, flag) union node *arg; struct arglist *arglist; - { + int flag; +{ struct strlist *sp; char *p; @@ -201,7 +190,8 @@ expandarg(arg, arglist, flag) STATIC void argstr(p, flag) register char *p; - { + int flag; +{ register char c; int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */ int firsteq = 1; @@ -257,13 +247,14 @@ breakloop:; STATIC char * exptilde(p, flag) char *p; - { + int flag; +{ char c, *startp = p; struct passwd *pw; char *home; int quotes = flag & (EXP_FULL | EXP_CASE); - while (c = *p) { + while ((c = *p) != '\0') { switch(c) { case CTLESC: return (startp); @@ -289,7 +280,7 @@ done: if (*home == '\0') goto lose; *p = c; - while (c = *home++) { + while ((c = *home++) != '\0') { if (quotes && SQSYNTAX[c] == CCTL) STPUTC(CTLESC, expdest); STPUTC(c, expdest); @@ -307,7 +298,8 @@ lose: */ void expari(flag) - { + int flag; +{ char *p, *start; int result; int quotes = flag & (EXP_FULL | EXP_CASE); @@ -352,7 +344,9 @@ expari(flag) STATIC void expbackq(cmd, quoted, flag) union node *cmd; - { + int quoted; + int flag; +{ struct backcmd in; int i; char buf[128]; @@ -400,9 +394,11 @@ expbackq(cmd, quoted, flag) STPUTC(lastc, dest); } } - if (lastc == '\n') { + + /* Eat all trailing newlines */ + for (p--; lastc == '\n'; lastc = *--p) STUNPUTC(dest); - } + if (in.fd >= 0) close(in.fd); if (in.buf) @@ -421,6 +417,101 @@ expbackq(cmd, quoted, flag) +STATIC int +subevalvar(p, str, subtype, startloc, varflags) + char *p; + char *str; + int subtype; + int startloc; + int varflags; +{ + + char *startp; + char *loc; + int c = 0; + int saveherefd = herefd; + struct nodelist *saveargbackq = argbackq; + herefd = -1; + argstr(p, 0); + STACKSTRNUL(expdest); + herefd = saveherefd; + argbackq = saveargbackq; + startp = stackblock() + startloc; + + switch (subtype) { + case VSASSIGN: + setvar(str, startp, 0); + STADJUST(startp - expdest, expdest); + varflags &= ~VSNUL; + if (c != 0) + *loc = c; + return 1; + + case VSQUESTION: + if (*p != CTLENDVAR) { + outfmt(&errout, "%s\n", startp); + error((char *)NULL); + } + error("%.*s: parameter %snot set", p - str - 1, + str, (varflags & VSNUL) ? "null or " + : nullstr); + return 0; + + case VSTRIMLEFT: + for (loc = startp; loc < str - 1; loc++) { + c = *loc; + *loc = '\0'; + if (patmatch(str, startp)) { + *loc = c; + goto recordleft; + } + *loc = c; + } + return 0; + + case VSTRIMLEFTMAX: + for (loc = str - 1; loc >= startp; loc--) { + c = *loc; + *loc = '\0'; + if (patmatch(str, startp)) { + *loc = c; + goto recordleft; + } + *loc = c; + } + return 0; + + case VSTRIMRIGHT: + for (loc = str - 1; loc >= startp; loc--) { + if (patmatch(str, loc)) { + expdest = loc; + return 1; + } + } + return 0; + + case VSTRIMRIGHTMAX: + for (loc = startp; loc < str - 1; loc++) { + if (patmatch(str, loc)) { + expdest = loc; + return 1; + } + } + return 0; + + + default: + abort(); + } + +recordleft: + expdest = (str - 1) - (loc - startp); + while (loc != str - 1) + *startp++ = *loc++; + return 1; +} + + /* * Expand a variable, and return a pointer to the next character in the * input string. @@ -429,15 +520,19 @@ expbackq(cmd, quoted, flag) STATIC char * evalvar(p, flag) char *p; - { + int flag; +{ int subtype; int varflags; char *var; char *val; + char *pat; int c; int set; int special; int startloc; + int varlen; + int easy; int quotes = flag & (EXP_FULL | EXP_CASE); varflags = *p++; @@ -453,60 +548,104 @@ again: /* jump here after setting a variable with ${var=text} */ val = NULL; } else { val = lookupvar(var); - if (val == NULL || (varflags & VSNUL) && val[0] == '\0') { + if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) { val = NULL; set = 0; } else set = 1; } + varlen = 0; startloc = expdest - stackblock(); if (set && subtype != VSPLUS) { /* insert the value of the variable */ if (special) { + char *exp, *oexpdest = expdest; varvalue(*var, varflags & VSQUOTE, flag & EXP_FULL); + if (subtype == VSLENGTH) { + for (exp = oexpdest;exp != expdest; exp++) + varlen++; + expdest = oexpdest; + } } else { - char const *syntax = (varflags & VSQUOTE)? DQSYNTAX : BASESYNTAX; + char const *syntax = (varflags & VSQUOTE) ? DQSYNTAX + : BASESYNTAX; + + if (subtype == VSLENGTH) { + for (;*val; val++) + varlen++; + } + else { + while (*val) { + if (quotes && syntax[*val] == CCTL) + STPUTC(CTLESC, expdest); + STPUTC(*val++, expdest); + } - while (*val) { - if (quotes && syntax[*val] == CCTL) - STPUTC(CTLESC, expdest); - STPUTC(*val++, expdest); } } } + if (subtype == VSPLUS) set = ! set; - if (((varflags & VSQUOTE) == 0 || (*var == '@' && shellparam.nparam != 1)) - && (set || subtype == VSNORMAL)) - recordregion(startloc, expdest - stackblock(), varflags & VSQUOTE); - if (! set && subtype != VSNORMAL) { - if (subtype == VSPLUS || subtype == VSMINUS) { + + easy = ((varflags & VSQUOTE) == 0 || + (*var == '@' && shellparam.nparam != 1)); + + + switch (subtype) { + case VSLENGTH: + expdest = cvtnum(varlen, expdest); + goto record; + + case VSNORMAL: + if (!easy) + break; +record: + recordregion(startloc, expdest - stackblock(), + varflags & VSQUOTE); + break; + + case VSPLUS: + case VSMINUS: + if (!set) { argstr(p, flag); - } else { - char *startp; - int saveherefd = herefd; - struct nodelist *saveargbackq = argbackq; - herefd = -1; - argstr(p, 0); - STACKSTRNUL(expdest); - herefd = saveherefd; - argbackq = saveargbackq; - startp = stackblock() + startloc; - if (subtype == VSASSIGN) { - setvar(var, startp, 0); - STADJUST(startp - expdest, expdest); - varflags &=~ VSNUL; + break; + } + if (easy) + goto record; + break; + + case VSTRIMLEFT: + case VSTRIMLEFTMAX: + case VSTRIMRIGHT: + case VSTRIMRIGHTMAX: + if (!set) + break; + /* + * Terminate the string and start recording the pattern + * right after it + */ + STPUTC('\0', expdest); + pat = expdest; + if (subevalvar(p, pat, subtype, startloc, varflags)) + goto record; + break; + + case VSASSIGN: + case VSQUESTION: + if (!set) { + if (subevalvar(p, var, subtype, startloc, varflags)) goto again; - } - /* subtype == VSQUESTION */ - if (*p != CTLENDVAR) { - outfmt(&errout, "%s\n", startp); - error((char *)NULL); - } - error("%.*s: parameter %snot set", p - var - 1, - var, (varflags & VSNUL)? "null or " : nullstr); + break; } + if (easy) + goto record; + break; + + default: + abort(); } + if (subtype != VSNORMAL) { /* skip to end of alternative */ int nesting = 1; for (;;) { @@ -564,12 +703,13 @@ varisset(name) STATIC void varvalue(name, quoted, allow_split) char name; - { + int quoted; + int allow_split; +{ int num; - char temp[32]; char *p; int i; - extern int exitstatus; + extern int oexitstatus; char sep; char **ap; char const *syntax; @@ -594,7 +734,7 @@ varvalue(name, quoted, allow_split) num = rootpid; goto numvar; case '?': - num = exitstatus; + num = oexitstatus; goto numvar; case '#': num = shellparam.nparam; @@ -602,13 +742,7 @@ varvalue(name, quoted, allow_split) case '!': num = backgndpid; numvar: - p = temp + 31; - temp[31] = '\0'; - do { - *--p = num % 10 + '0'; - } while ((num /= 10) != 0); - while (*p) - STPUTC(*p++, expdest); + expdest = cvtnum(num, expdest); break; case '-': for (i = 0 ; i < NOPTS ; i++) { @@ -652,7 +786,11 @@ allargs: */ STATIC void -recordregion(start, end, nulonly) { +recordregion(start, end, nulonly) + int start; + int end; + int nulonly; +{ register struct ifsregion *ifsp; if (ifslastp == NULL) { @@ -675,7 +813,6 @@ recordregion(start, end, nulonly) { * strings to the argument list. The regions of the string to be * searched for IFS characters have been stored by recordregion. */ - STATIC void ifsbreakup(string, arglist) char *string; @@ -687,6 +824,8 @@ ifsbreakup(string, arglist) register char *p; char *q; char *ifs; + int ifsspc; + start = string; if (ifslastp != NULL) { @@ -694,19 +833,20 @@ ifsbreakup(string, arglist) do { p = string + ifsp->begoff; ifs = ifsp->nulonly? nullstr : ifsval(); + ifsspc = strchr(ifs, ' ') != NULL; while (p < string + ifsp->endoff) { q = p; if (*p == CTLESC) p++; if (strchr(ifs, *p++)) { - if (q > start || *ifs != ' ') { + if (q > start || !ifsspc) { *q = '\0'; sp = (struct strlist *)stalloc(sizeof *sp); sp->text = start; *arglist->lastp = sp; arglist->lastp = &sp->next; } - if (*ifs == ' ') { + if (ifsspc) { for (;;) { if (p >= string + ifsp->endoff) break; @@ -723,7 +863,7 @@ ifsbreakup(string, arglist) } } } while ((ifsp = ifsp->next) != NULL); - if (*start || (*ifs != ' ' && start > string)) { + if (*start || (!ifsspc && start > string)) { sp = (struct strlist *)stalloc(sizeof *sp); sp->text = start; *arglist->lastp = sp; @@ -750,7 +890,8 @@ char *expdir; STATIC void expandmeta(str, flag) struct strlist *str; - { + int flag; +{ char *p; struct strlist **savelastp; struct strlist *sp; @@ -891,7 +1032,7 @@ expmeta(enddir, name) *endname++ = '\0'; } matchdot = 0; - if (start[0] == '.' || start[0] == CTLESC && start[1] == '.') + if (start[0] == '.' || (start[0] == CTLESC && start[1] == '.')) matchdot++; while (! int_pending() && (dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.' && ! matchdot) @@ -902,7 +1043,9 @@ expmeta(enddir, name) addfname(expdir); } else { char *q; - for (p = enddir, q = dp->d_name ; *p++ = *q++ ;); + for (p = enddir, q = dp->d_name; + (*p++ = *q++) != '\0';) + continue; p[-1] = '/'; expmeta(p, endname); } @@ -957,7 +1100,8 @@ expsort(str) STATIC struct strlist * msort(list, len) struct strlist *list; - { + int len; +{ struct strlist *p, *q; struct strlist **lpp; int half; @@ -1074,6 +1218,8 @@ pmatch(pattern, string) } found = 0; chr = *q++; + if (chr == '\0') + return 0; c = *p++; do { if (c == CTLESC) @@ -1158,3 +1304,30 @@ casematch(pattern, val) popstackmark(&smark); return result; } + +/* + * Our own itoa(). + */ + +STATIC char * +cvtnum(num, buf) + int num; + char *buf; + { + char temp[32]; + int neg = num < 0; + char *p = temp + 31; + + temp[31] = '\0'; + + do { + *--p = num % 10 + '0'; + } while ((num /= 10) != 0); + + if (neg) + *--p = '-'; + + while (*p) + STPUTC(*p++, buf); + return buf; +} diff --git a/bin/sh/expand.h b/bin/sh/expand.h index 5c6758f..ee318d9 100644 --- a/bin/sh/expand.h +++ b/bin/sh/expand.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)expand.h 8.1 (Berkeley) 5/31/93 + * @(#)expand.h 8.2 (Berkeley) 5/4/95 */ struct strlist { @@ -57,17 +57,10 @@ struct arglist { #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */ -#ifdef __STDC__ union node; -void expandarg(union node *, struct arglist *, int); -void expandhere(union node *, int); -int patmatch(char *, char *); -void rmescapes(char *); -int casematch(union node *, char *); -#else -void expandarg(); -void expandhere(); -int patmatch(); -void rmescapes(); -int casematch(); -#endif +void expandhere __P((union node *, int)); +void expandarg __P((union node *, struct arglist *, int)); +void expari __P((int)); +int patmatch __P((char *, char *)); +void rmescapes __P((char *)); +int casematch __P((union node *, char *)); diff --git a/bin/sh/funcs/cmv b/bin/sh/funcs/cmv index a0921ef..d511e47 100644 --- a/bin/sh/funcs/cmv +++ b/bin/sh/funcs/cmv @@ -32,7 +32,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)cmv 8.1 (Berkeley) 5/31/93 +# @(#)cmv 8.2 (Berkeley) 5/4/95 # Conditional move--don't replace an existing file. diff --git a/bin/sh/funcs/dirs b/bin/sh/funcs/dirs index 04b7fe1..32b475b 100644 --- a/bin/sh/funcs/dirs +++ b/bin/sh/funcs/dirs @@ -32,7 +32,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)dirs 8.1 (Berkeley) 5/31/93 +# @(#)dirs 8.2 (Berkeley) 5/4/95 # pushd, popd, and dirs --- written by Chris Bertin # Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris diff --git a/bin/sh/funcs/kill b/bin/sh/funcs/kill index da670e9..cf90c68 100644 --- a/bin/sh/funcs/kill +++ b/bin/sh/funcs/kill @@ -32,7 +32,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)kill 8.1 (Berkeley) 5/31/93 +# @(#)kill 8.2 (Berkeley) 5/4/95 # Convert job names to process ids and then run /bin/kill. diff --git a/bin/sh/funcs/login b/bin/sh/funcs/login index d8e9d6f..a21e9f6 100644 --- a/bin/sh/funcs/login +++ b/bin/sh/funcs/login @@ -32,7 +32,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)login 8.1 (Berkeley) 5/31/93 +# @(#)login 8.2 (Berkeley) 5/4/95 # replaces the login builtin in the BSD shell login () exec login "$@" diff --git a/bin/sh/funcs/newgrp b/bin/sh/funcs/newgrp index d5aa63e..dad3cd5 100644 --- a/bin/sh/funcs/newgrp +++ b/bin/sh/funcs/newgrp @@ -32,6 +32,6 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)newgrp 8.1 (Berkeley) 5/31/93 +# @(#)newgrp 8.2 (Berkeley) 5/4/95 newgrp() exec newgrp "$@" diff --git a/bin/sh/funcs/popd b/bin/sh/funcs/popd index 2f4de3a..10193f8 100644 --- a/bin/sh/funcs/popd +++ b/bin/sh/funcs/popd @@ -32,7 +32,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)popd 8.1 (Berkeley) 5/31/93 +# @(#)popd 8.2 (Berkeley) 5/4/95 # pushd, popd, and dirs --- written by Chris Bertin # Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris diff --git a/bin/sh/funcs/pushd b/bin/sh/funcs/pushd index 0c50353..59b0040 100644 --- a/bin/sh/funcs/pushd +++ b/bin/sh/funcs/pushd @@ -32,7 +32,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)pushd 8.1 (Berkeley) 5/31/93 +# @(#)pushd 8.2 (Berkeley) 5/4/95 # pushd, popd, and dirs --- written by Chris Bertin # Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris diff --git a/bin/sh/funcs/suspend b/bin/sh/funcs/suspend index 4483965..85723b0 100644 --- a/bin/sh/funcs/suspend +++ b/bin/sh/funcs/suspend @@ -32,7 +32,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)suspend 8.1 (Berkeley) 5/31/93 +# @(#)suspend 8.2 (Berkeley) 5/4/95 suspend() { local - diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c index 0093c17..5601852 100644 --- a/bin/sh/histedit.c +++ b/bin/sh/histedit.c @@ -35,22 +35,29 @@ */ #ifndef lint -static char sccsid[] = "@(#)histedit.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ -/* - * Editline and history functions (and glue). - */ #include <sys/param.h> #include <paths.h> #include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +/* + * Editline and history functions (and glue). + */ #include "shell.h" #include "parser.h" #include "var.h" #include "options.h" +#include "main.h" +#include "output.h" #include "mystring.h" +#ifndef NO_HISTORY +#include "myhistedit.h" +#endif #include "error.h" -#include "histedit.h" +#include "eval.h" #include "memalloc.h" #define MAXHISTLOOPS 4 /* max recursions through fc */ @@ -67,7 +74,9 @@ STATIC char *fc_replace __P((const char *, char *, char *)); * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ -histedit() { +void +histedit() +{ #define editing (Eflag || Vflag) @@ -132,7 +141,10 @@ bad: } } -sethistsize() { + +void +sethistsize() +{ char *cp; int histsize; @@ -149,8 +161,10 @@ sethistsize() { * This command is provided since POSIX decided to standardize * the Korn shell fc command. Oh well... */ +int histcmd(argc, argv) - char *argv[]; + int argc; + char **argv; { extern char *optarg; extern int optind, optopt, optreset; @@ -167,6 +181,21 @@ histcmd(argc, argv) struct jmploc *volatile savehandler; char editfile[MAXPATHLEN + 1]; FILE *efp; +#ifdef __GNUC__ + /* Avoid longjmp clobbering */ + (void) &editor; + (void) &lflg; + (void) &nflg; + (void) &rflg; + (void) &sflg; + (void) &firststr; + (void) &laststr; + (void) &pat; + (void) &repl; + (void) &efp; + (void) &argc; + (void) &argv; +#endif if (hist == NULL) error("history not active"); @@ -358,6 +387,7 @@ histcmd(argc, argv) --active; if (displayhist) displayhist = 0; + return 0; } STATIC char * @@ -384,14 +414,18 @@ fc_replace(s, p, r) return (dest); } +int not_fcnumber(s) char *s; { + if (s == NULL) + return 0; if (*s == '-') s++; return (!is_number(s)); } +int str_to_event(str, last) char *str; int last; @@ -399,7 +433,7 @@ str_to_event(str, last) const HistEvent *he; char *s = str; int relative = 0; - int i, j; + int i; he = history(hist, H_FIRST); switch (*s) { diff --git a/bin/sh/init.h b/bin/sh/init.h index b184361..9a9b24c 100644 --- a/bin/sh/init.h +++ b/bin/sh/init.h @@ -33,15 +33,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)init.h 8.1 (Berkeley) 5/31/93 + * @(#)init.h 8.2 (Berkeley) 5/4/95 */ -#ifdef __STDC__ -void init(void); -void reset(void); -void initshellproc(void); -#else -void init(); -void reset(); -void initshellproc(); -#endif +void init __P((void)); +void reset __P((void)); +void initshellproc __P((void)); diff --git a/bin/sh/input.c b/bin/sh/input.c index d1d84e1..b1b0f83 100644 --- a/bin/sh/input.c +++ b/bin/sh/input.c @@ -35,17 +35,22 @@ */ #ifndef lint -static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95"; #endif /* not lint */ +#include <stdio.h> /* defines BUFSIZ */ +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + /* * This file implements the input routines used by the parser. */ -#include <stdio.h> /* defines BUFSIZ */ #include "shell.h" -#include <fcntl.h> -#include <errno.h> +#include "redir.h" #include "syntax.h" #include "input.h" #include "output.h" @@ -97,13 +102,7 @@ int whichprompt; /* 1 == PS1, 2 == PS2 */ EditLine *el; /* cookie for editline package */ -#ifdef __STDC__ -STATIC void pushfile(void); -#else -STATIC void pushfile(); -#endif - - +STATIC void pushfile __P((void)); #ifdef mkinit INCLUDE "input.h" @@ -134,7 +133,8 @@ SHELLPROC { char * pfgets(line, len) char *line; - { + int len; +{ register char *p = line; int nleft = len; int c; @@ -208,7 +208,6 @@ retry: i = len; } else { -regular_read: i = read(parsefile->fd, p, BUFSIZ - 1); } eof: @@ -322,6 +321,7 @@ pushstring(s, len, ap) INTON; } +void popstring() { struct strpush *sp = parsefile->strpush; @@ -346,7 +346,8 @@ popstring() void setinputfile(fname, push) char *fname; - { + int push; +{ int fd; int fd2; @@ -371,7 +372,9 @@ setinputfile(fname, push) */ void -setinputfd(fd, push) { +setinputfd(fd, push) + int fd, push; +{ if (push) { pushfile(); parsefile->buf = ckmalloc(BUFSIZ); @@ -393,6 +396,7 @@ setinputfd(fd, push) { void setinputstring(string, push) char *string; + int push; { INTOFF; if (push) diff --git a/bin/sh/input.h b/bin/sh/input.h index 754eda0..becbc25 100644 --- a/bin/sh/input.h +++ b/bin/sh/input.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)input.h 8.1 (Berkeley) 5/31/93 + * @(#)input.h 8.2 (Berkeley) 5/4/95 */ /* PEOF (the end of file marker) is defined in syntax.h */ @@ -48,31 +48,17 @@ extern int parsenleft; /* number of characters left in input buffer */ extern char *parsenextc; /* next character in input buffer */ extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */ - -#ifdef __STDC__ -char *pfgets(char *, int); -int pgetc(void); -int preadbuffer(void); -void pungetc(void); -void pushstring(char *, int, void *); -void setinputfile(char *, int); -void setinputfd(int, int); -void setinputstring(char *, int); -void popfile(void); -void popallfiles(void); -void closescript(void); -#else -char *pfgets(); -int pgetc(); -int preadbuffer(); -void pungetc(); -void setinputfile(); -void setinputfd(); -void setinputstring(); -void popfile(); -void popallfiles(); -void pushstring(); -void closescript(); -#endif +char *pfgets __P((char *, int)); +int pgetc __P((void)); +int preadbuffer __P((void)); +void pungetc __P((void)); +void pushstring __P((char *, int, void *)); +void popstring __P((void)); +void setinputfile __P((char *, int)); +void setinputfd __P((int, int)); +void setinputstring __P((char *, int)); +void popfile __P((void)); +void popallfiles __P((void)); +void closescript __P((void)); #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index 60f66ed..a414013 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -35,37 +35,41 @@ */ #ifndef lint -static char sccsid[] = "@(#)jobs.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; #endif /* not lint */ +#include <fcntl.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/param.h> +#ifdef BSD +#include <sys/wait.h> +#include <sys/time.h> +#include <sys/resource.h> +#endif + #include "shell.h" #if JOBS #include "sgtty.h" #undef CEOF /* syntax.h redefines this */ #endif +#include "redir.h" +#include "show.h" #include "main.h" #include "parser.h" #include "nodes.h" #include "jobs.h" #include "options.h" #include "trap.h" -#include "signames.h" #include "syntax.h" #include "input.h" #include "output.h" #include "memalloc.h" #include "error.h" #include "mystring.h" -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#ifdef BSD -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> -#endif - struct job *jobtab; /* array of jobs */ @@ -76,22 +80,14 @@ int initialpgrp; /* pgrp of shell on invocation */ short curjob; /* current job */ #endif -#ifdef __STDC__ -STATIC void restartjob(struct job *); -STATIC struct job *getjob(char *); -STATIC void freejob(struct job *); -STATIC int procrunning(int); -STATIC int dowait(int, struct job *); -STATIC int waitproc(int, int *); -#else -STATIC void restartjob(); -STATIC struct job *getjob(); -STATIC void freejob(); -STATIC int procrunning(); -STATIC int dowait(); -STATIC int waitproc(); -#endif - +STATIC void restartjob __P((struct job *)); +STATIC void freejob __P((struct job *)); +STATIC struct job *getjob __P((char *)); +STATIC int dowait __P((int, struct job *)); +STATIC int onsigchild __P((void)); +STATIC int waitproc __P((int, int *)); +STATIC void cmdtxt __P((union node *)); +STATIC void cmdputs __P((char *)); /* @@ -105,7 +101,9 @@ STATIC int waitproc(); MKINIT int jobctl; void -setjobctl(on) { +setjobctl(on) + int on; +{ #ifdef OLD_TTY_DRIVER int ldisc; #endif @@ -120,8 +118,8 @@ setjobctl(on) { return; } if (initialpgrp == -1) - initialpgrp = getpgrp(0); - else if (initialpgrp != getpgrp(0)) { + initialpgrp = getpgrp(); + else if (initialpgrp != getpgrp()) { killpg(initialpgrp, SIGTTIN); continue; } @@ -136,10 +134,10 @@ setjobctl(on) { setsignal(SIGTSTP); setsignal(SIGTTOU); setsignal(SIGTTIN); - setpgrp(0, rootpid); + setpgid(0, rootpid); ioctl(2, TIOCSPGRP, (char *)&rootpid); } else { /* turning job control off */ - setpgrp(0, initialpgrp); + setpgid(0, initialpgrp); ioctl(2, TIOCSPGRP, (char *)&initialpgrp); setsignal(SIGTSTP); setsignal(SIGTTOU); @@ -150,6 +148,7 @@ setjobctl(on) { #ifdef mkinit +INCLUDE <stdlib.h> SHELLPROC { backgndpid = -1; @@ -163,7 +162,11 @@ SHELLPROC { #if JOBS -fgcmd(argc, argv) char **argv; { +int +fgcmd(argc, argv) + int argc; + char **argv; +{ struct job *jp; int pgrp; int status; @@ -181,7 +184,11 @@ fgcmd(argc, argv) char **argv; { } -bgcmd(argc, argv) char **argv; { +int +bgcmd(argc, argv) + int argc; + char **argv; +{ struct job *jp; do { @@ -197,7 +204,7 @@ bgcmd(argc, argv) char **argv; { STATIC void restartjob(jp) struct job *jp; - { +{ struct procstat *ps; int i; @@ -217,7 +224,10 @@ restartjob(jp) int -jobscmd(argc, argv) char **argv; { +jobscmd(argc, argv) + int argc; + char **argv; +{ showjobs(0); return 0; } @@ -233,7 +243,9 @@ jobscmd(argc, argv) char **argv; { */ void -showjobs(change) { +showjobs(change) + int change; +{ int jobno; int procno; int i; @@ -272,8 +284,8 @@ showjobs(change) { if ((i & 0xFF) == 0177) i >>= 8; #endif - if ((i & 0x7F) <= MAXSIG && sigmesg[i & 0x7F]) - scopy(sigmesg[i & 0x7F], s); + if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) + scopy(sys_siglist[i & 0x7F], s); else fmtstr(s, 64, "Signal %d", i & 0x7F); if (i & 0x80) @@ -327,7 +339,10 @@ freejob(jp) int -waitcmd(argc, argv) char **argv; { +waitcmd(argc, argv) + int argc; + char **argv; +{ struct job *job; int status; struct job *jp; @@ -368,7 +383,11 @@ waitcmd(argc, argv) char **argv; { -jobidcmd(argc, argv) char **argv; { +int +jobidcmd(argc, argv) + int argc; + char **argv; +{ struct job *jp; int i; @@ -436,6 +455,8 @@ currentjob: } } error("No such job: %s", name); + /*NOTREACHED*/ + return NULL; } @@ -447,7 +468,8 @@ currentjob: struct job * makejob(node, nprocs) union node *node; - { + int nprocs; +{ int i; struct job *jp; @@ -458,7 +480,7 @@ makejob(node, nprocs) jobtab = ckmalloc(4 * sizeof jobtab[0]); } else { jp = ckmalloc((njobs + 4) * sizeof jobtab[0]); - bcopy(jobtab, jp, njobs * sizeof jp[0]); + memcpy(jp, jobtab, njobs * sizeof jp[0]); ckfree(jobtab); jobtab = jp; } @@ -484,7 +506,8 @@ makejob(node, nprocs) jp->ps = &jp->ps0; } INTON; - TRACE(("makejob(0x%x, %d) returns %%%d\n", (int)node, nprocs, jp - jobtab + 1)); + TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs, + jp - jobtab + 1)); return jp; } @@ -508,11 +531,13 @@ int forkshell(jp, n, mode) union node *n; struct job *jp; - { + int mode; +{ int pid; int pgrp; - TRACE(("forkshell(%%%d, 0x%x, %d) called\n", jp - jobtab, (int)n, mode)); + TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n, + mode)); INTOFF; pid = fork(); if (pid == -1) { @@ -541,7 +566,7 @@ forkshell(jp, n, mode) pgrp = getpid(); else pgrp = jp->ps[0].pid; - setpgrp(0, pgrp); + setpgid(0, pgrp); if (mode == FORK_FG) { /*** this causes superfluous TIOCSPGRPS ***/ if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0) @@ -583,7 +608,7 @@ forkshell(jp, n, mode) pgrp = pid; else pgrp = jp->ps[0].pid; - setpgrp(pid, pgrp); + setpgid(pid, pgrp); } if (mode == FORK_BG) backgndpid = pid; /* set $! */ @@ -626,7 +651,7 @@ waitforjob(jp) register struct job *jp; { #if JOBS - int mypgrp = getpgrp(0); + int mypgrp = getpgrp(); #endif int status; int st; @@ -671,8 +696,9 @@ waitforjob(jp) STATIC int dowait(block, job) + int block; struct job *job; - { +{ int pid; int status; struct procstat *sp; @@ -736,8 +762,8 @@ dowait(block, job) if (status == SIGTSTP && rootshell && iflag) outfmt(out2, "%%%d ", job - jobtab + 1); #endif - if (status <= MAXSIG && sigmesg[status]) - out2str(sigmesg[status]); + if (status < NSIG && sys_siglist[status]) + out2str(sys_siglist[status]); else outfmt(out2, "Signal %d", status); if (core) @@ -797,8 +823,9 @@ STATIC int onsigchild() { STATIC int waitproc(block, status) + int block; int *status; - { +{ #ifdef BSD int flags; diff --git a/bin/sh/jobs.h b/bin/sh/jobs.h index 2464850..1d1dce9 100644 --- a/bin/sh/jobs.h +++ b/bin/sh/jobs.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)jobs.h 8.1 (Berkeley) 5/31/93 + * @(#)jobs.h 8.2 (Berkeley) 5/4/95 */ /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ @@ -77,22 +77,18 @@ struct job { extern short backgndpid; /* pid of last background process */ extern int job_warning; /* user was warned about stopped jobs */ - -#ifdef __STDC__ -void setjobctl(int); -void showjobs(int); -struct job *makejob(union node *, int); -int forkshell(struct job *, union node *, int); -int waitforjob(struct job *); -char *commandtext(union node *); -#else -void setjobctl(); -void showjobs(); -struct job *makejob(); -int forkshell(); -int waitforjob(); -char *commandtext(); -#endif +void setjobctl __P((int)); +int fgcmd __P((int, char **)); +int bgcmd __P((int, char **)); +int jobscmd __P((int, char **)); +void showjobs __P((int)); +int waitcmd __P((int, char **)); +int jobidcmd __P((int, char **)); +struct job *makejob __P((union node *, int)); +int forkshell __P((struct job *, union node *, int)); +int waitforjob __P((struct job *)); +int stoppedjobs __P((void)); +char *commandtext __P((union node *)); #if ! JOBS #define setjobctl(on) /* do nothing */ diff --git a/bin/sh/machdep.h b/bin/sh/machdep.h index 1d50dfb..139eaa8 100644 --- a/bin/sh/machdep.h +++ b/bin/sh/machdep.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)machdep.h 8.1 (Berkeley) 5/31/93 + * @(#)machdep.h 8.2 (Berkeley) 5/4/95 */ /* @@ -47,5 +47,5 @@ union align { char *cp; }; -#define ALIGN(nbytes) ((nbytes) + sizeof(union align) - 1 &~ (sizeof(union align) - 1)) +#define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1)) #endif diff --git a/bin/sh/mail.c b/bin/sh/mail.c index 0f74ad8..10ba3d3 100644 --- a/bin/sh/mail.c +++ b/bin/sh/mail.c @@ -35,7 +35,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)mail.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)mail.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ /* @@ -67,7 +67,9 @@ STATIC time_t mailtime[MAXMBOXES]; /* times of mailboxes */ */ void -chkmail(silent) { +chkmail(silent) + int silent; +{ register int i; char *mpath; char *p; diff --git a/bin/sh/mail.h b/bin/sh/mail.h index d859e53..e62fd12 100644 --- a/bin/sh/mail.h +++ b/bin/sh/mail.h @@ -33,11 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)mail.h 8.1 (Berkeley) 5/31/93 + * @(#)mail.h 8.2 (Berkeley) 5/4/95 */ -#ifdef __STDC__ -void chkmail(int); -#else -void chkmail(); -#endif +void chkmail __P((int)); diff --git a/bin/sh/main.c b/bin/sh/main.c index dab9e64..32f0f65 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -41,11 +41,16 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/28/95"; #endif /* not lint */ +#include <stdio.h> #include <signal.h> +#include <sys/stat.h> +#include <unistd.h> #include <fcntl.h> + + #include "shell.h" #include "main.h" #include "mail.h" @@ -53,15 +58,18 @@ static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93"; #include "output.h" #include "parser.h" #include "nodes.h" +#include "expand.h" #include "eval.h" #include "jobs.h" #include "input.h" #include "trap.h" #include "var.h" +#include "show.h" #include "memalloc.h" #include "error.h" #include "init.h" #include "mystring.h" +#include "exec.h" #define PROFILE 0 @@ -75,14 +83,8 @@ short profile_buf[16384]; extern int etext(); #endif -#ifdef __STDC__ -STATIC void read_profile(char *); -char *getenv(char *); -#else -STATIC void read_profile(); -char *getenv(); -#endif - +STATIC void read_profile __P((char *)); +STATIC char *find_dot_file __P((char *)); /* * Main routine. We initialize things, parse the arguments, execute @@ -92,7 +94,11 @@ char *getenv(); * is used to figure out how far we had gotten. */ -main(argc, argv) char **argv; { +int +main(argc, argv) + int argc; + char **argv; +{ struct jmploc jmploc; struct stackmark smark; volatile int state; @@ -108,6 +114,8 @@ main(argc, argv) char **argv; { * exception EXSHELLPROC to clean up before executing * the shell procedure. */ + if (exception == EXERROR) + exitstatus = 2; if (exception == EXSHELLPROC) { rootpid = getpid(); rootshell = 1; @@ -154,10 +162,11 @@ state1: } state2: state = 3; - if ((shinit = lookupvar("ENV")) != NULL && - *shinit != '\0') { - state = 3; - read_profile(shinit); + if (getuid() == geteuid() && getgid() == getegid()) { + if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { + state = 3; + read_profile(shinit); + } } state3: state = 4; @@ -172,6 +181,8 @@ state4: /* XXX ??? - why isn't this before the "if" statement */ monitor(0); #endif exitshell(exitstatus); + /*NOTREACHED*/ + return 0; } @@ -181,7 +192,9 @@ state4: /* XXX ??? - why isn't this before the "if" statement */ */ void -cmdloop(top) { +cmdloop(top) + int top; +{ union node *n; struct stackmark smark; int inter; @@ -251,7 +264,7 @@ read_profile(name) void readcmdfile(name) char *name; - { +{ int fd; INTOFF; @@ -268,14 +281,48 @@ readcmdfile(name) /* * Take commands from a file. To be compatable we should do a path - * search for the file, but a path search doesn't make any sense. + * search for the file, which is necessary to find sub-commands. */ -dotcmd(argc, argv) char **argv; { + +STATIC char * +find_dot_file(basename) + char *basename; +{ + static char localname[FILENAME_MAX+1]; + char *fullname; + 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) { + strcpy(localname, fullname); + stunalloc(fullname); + if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) + return localname; + } + return basename; +} + +int +dotcmd(argc, argv) + int argc; + char **argv; +{ + struct strlist *sp; exitstatus = 0; + + for (sp = cmdenviron; sp ; sp = sp->next) + setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED); + if (argc >= 2) { /* That's what SVR2 does */ - setinputfile(argv[1], 1); - commandname = argv[1]; + char *fullname = find_dot_file(argv[1]); + + setinputfile(fullname, 1); + commandname = fullname; cmdloop(0); popfile(); } @@ -283,12 +330,18 @@ dotcmd(argc, argv) char **argv; { } -exitcmd(argc, argv) char **argv; { +int +exitcmd(argc, argv) + int argc; + char **argv; +{ if (stoppedjobs()) - return; + return 0; if (argc > 1) exitstatus = number(argv[1]); exitshell(exitstatus); + /*NOTREACHED*/ + return 0; } diff --git a/bin/sh/main.h b/bin/sh/main.h index b403b2c..b454b86 100644 --- a/bin/sh/main.h +++ b/bin/sh/main.h @@ -33,16 +33,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)main.h 8.1 (Berkeley) 5/31/93 + * @(#)main.h 8.2 (Berkeley) 5/4/95 */ extern int rootpid; /* pid of main shell */ extern int rootshell; /* true if we aren't a child of the main shell */ -#ifdef __STDC__ -void readcmdfile(char *); -void cmdloop(int); -#else -void readcmdfile(); -void cmdloop(); -#endif +void readcmdfile __P((char *)); +void cmdloop __P((int)); +int dotcmd __P((int, char **)); +int exitcmd __P((int, char **)); diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c index 5fa246a..fd0df3e 100644 --- a/bin/sh/memalloc.c +++ b/bin/sh/memalloc.c @@ -35,7 +35,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)memalloc.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)memalloc.c 8.3 (Berkeley) 5/4/95"; #endif /* not lint */ #include "shell.h" @@ -44,15 +44,18 @@ static char sccsid[] = "@(#)memalloc.c 8.1 (Berkeley) 5/31/93"; #include "error.h" #include "machdep.h" #include "mystring.h" +#include <stdlib.h> +#include <unistd.h> /* * Like malloc, but returns an error when out of space. */ pointer -ckmalloc(nbytes) { +ckmalloc(nbytes) + int nbytes; +{ register pointer p; - pointer malloc(); if ((p = malloc(nbytes)) == NULL) error("Out of space"); @@ -67,8 +70,8 @@ ckmalloc(nbytes) { pointer ckrealloc(p, nbytes) register pointer p; - { - pointer realloc(); + int nbytes; +{ if ((p = realloc(p, nbytes)) == NULL) error("Out of space"); @@ -119,7 +122,9 @@ int herefd = -1; pointer -stalloc(nbytes) { +stalloc(nbytes) + int nbytes; +{ register char *p; nbytes = ALIGN(nbytes); @@ -217,16 +222,18 @@ growstackblock() { INTON; } else { p = stalloc(newlen); - bcopy(oldspace, p, oldlen); + memcpy(p, oldspace, oldlen); stacknxt = p; /* free the space */ - stacknleft += newlen; /* we just allocated */ + stacknleft += ALIGN(newlen); /* we just allocated */ } } void -grabstackblock(len) { +grabstackblock(len) + int len; +{ len = ALIGN(len); stacknxt += len; stacknleft -= len; diff --git a/bin/sh/memalloc.h b/bin/sh/memalloc.h index 3f2c800..828a6cd 100644 --- a/bin/sh/memalloc.h +++ b/bin/sh/memalloc.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)memalloc.h 8.1 (Berkeley) 5/31/93 + * @(#)memalloc.h 8.2 (Berkeley) 5/4/95 */ struct stackmark { @@ -48,35 +48,18 @@ extern int stacknleft; extern int sstrnleft; extern int herefd; -#ifdef __STDC__ -pointer ckmalloc(int); -pointer ckrealloc(pointer, int); -void free(pointer); /* defined in C library */ -char *savestr(char *); -pointer stalloc(int); -void stunalloc(pointer); -void setstackmark(struct stackmark *); -void popstackmark(struct stackmark *); -void growstackblock(void); -void grabstackblock(int); -char *growstackstr(void); -char *makestrspace(void); -void ungrabstackstr(char *, char *); -#else -pointer ckmalloc(); -pointer ckrealloc(); -void free(); /* defined in C library */ -char *savestr(); -pointer stalloc(); -void stunalloc(); -void setstackmark(); -void popstackmark(); -void growstackblock(); -void grabstackblock(); -char *growstackstr(); -char *makestrspace(); -void ungrabstackstr(); -#endif +pointer ckmalloc __P((int)); +pointer ckrealloc __P((pointer, int)); +char *savestr __P((char *)); +pointer stalloc __P((int)); +void stunalloc __P((pointer)); +void setstackmark __P((struct stackmark *)); +void popstackmark __P((struct stackmark *)); +void growstackblock __P((void)); +void grabstackblock __P((int)); +char *growstackstr __P((void)); +char *makestrspace __P((void)); +void ungrabstackstr __P((char *, char *)); @@ -84,7 +67,7 @@ void ungrabstackstr(); #define stackblocksize() stacknleft #define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize() #define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c))) -#define CHECKSTRSPACE(n, p) if (sstrnleft < n) p = makestrspace(); else +#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); } #define USTPUTC(c, p) (--sstrnleft, *p++ = (c)) #define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0')) #define STUNPUTC(p) (++sstrnleft, --p) diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c index 4ea3a4c..5421592 100644 --- a/bin/sh/miscbltin.c +++ b/bin/sh/miscbltin.c @@ -35,13 +35,20 @@ */ #ifndef lint -static char sccsid[] = "@(#)miscbltin.c 8.2 (Berkeley) 4/16/94"; +static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; #endif /* not lint */ /* * Miscelaneous builtins. */ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <unistd.h> +#include <ctype.h> + #include "shell.h" #include "options.h" #include "var.h" @@ -62,7 +69,11 @@ extern char **argptr; /* argument list for builtin command */ * This uses unbuffered input, which may be avoidable in some cases. */ -readcmd(argc, argv) char **argv; { +int +readcmd(argc, argv) + int argc; + char **argv; +{ char **ap; int backslash; char c; @@ -142,25 +153,235 @@ readcmd(argc, argv) char **argv; { -umaskcmd(argc, argv) char **argv; { +int +umaskcmd(argc, argv) + int argc; + char **argv; +{ + char *ap; int mask; - char *p; int i; + int symbolic_mode = 0; + + while ((i = nextopt("S")) != '\0') { + symbolic_mode = 1; + } + + INTOFF; + mask = umask(0); + umask(mask); + INTON; + + if ((ap = *argptr) == NULL) { + if (symbolic_mode) { + char u[4], g[4], o[4]; - if ((p = argv[1]) == NULL) { - INTOFF; - mask = umask(0); - umask(mask); - INTON; - out1fmt("%.4o\n", mask); /* %#o might be better */ + i = 0; + if ((mask & S_IRUSR) == 0) + u[i++] = 'r'; + if ((mask & S_IWUSR) == 0) + u[i++] = 'w'; + if ((mask & S_IXUSR) == 0) + u[i++] = 'x'; + u[i] = '\0'; + + i = 0; + if ((mask & S_IRGRP) == 0) + g[i++] = 'r'; + if ((mask & S_IWGRP) == 0) + g[i++] = 'w'; + if ((mask & S_IXGRP) == 0) + g[i++] = 'x'; + g[i] = '\0'; + + i = 0; + if ((mask & S_IROTH) == 0) + o[i++] = 'r'; + if ((mask & S_IWOTH) == 0) + o[i++] = 'w'; + if ((mask & S_IXOTH) == 0) + o[i++] = 'x'; + o[i] = '\0'; + + out1fmt("u=%s,g=%s,o=%s\n", u, g, o); + } else { + out1fmt("%.4o\n", mask); + } } else { - mask = 0; - do { - if ((unsigned)(i = *p - '0') >= 8) - error("Illegal number: %s", argv[1]); - mask = (mask << 3) + i; - } while (*++p != '\0'); - umask(mask); + if (isdigit(*ap)) { + mask = 0; + do { + if (*ap >= '8' || *ap < '0') + error("Illegal number: %s", argv[1]); + mask = (mask << 3) + (*ap - '0'); + } while (*++ap != '\0'); + umask(mask); + } else { + void *set; + if ((set = setmode (ap)) == 0) + error("Illegal number: %s", ap); + + mask = getmode (set, ~mask & 0777); + umask(~mask & 0777); + } + } + return 0; +} + +/* + * ulimit builtin + * + * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and + * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with + * ash by J.T. Conklin. + * + * Public domain. + */ + +struct limits { + const char *name; + int cmd; + int factor; /* multiply by to get rlim_{cur,max} values */ + char option; +}; + +static const struct limits limits[] = { +#ifdef RLIMIT_CPU + { "time(seconds)", RLIMIT_CPU, 1, 't' }, +#endif +#ifdef RLIMIT_FSIZE + { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, +#endif +#ifdef RLIMIT_DATA + { "data(kbytes)", RLIMIT_DATA, 1024, 'd' }, +#endif +#ifdef RLIMIT_STACK + { "stack(kbytes)", RLIMIT_STACK, 1024, 's' }, +#endif +#ifdef RLIMIT_CORE + { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, +#endif +#ifdef RLIMIT_RSS + { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' }, +#endif +#ifdef RLIMIT_MEMLOCK + { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, +#endif +#ifdef RLIMIT_NPROC + { "process(processes)", RLIMIT_NPROC, 1, 'p' }, +#endif +#ifdef RLIMIT_NOFILE + { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, +#endif +#ifdef RLIMIT_VMEM + { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, +#endif +#ifdef RLIMIT_SWAP + { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, +#endif + { (char *) 0, 0, 0, '\0' } +}; + +int +ulimitcmd(argc, argv) + int argc; + char **argv; +{ + register int c; + quad_t val; + enum { SOFT = 0x1, HARD = 0x2 } + how = SOFT | HARD; + const struct limits *l; + int set, all = 0; + int optc, what; + struct rlimit limit; + + what = 'f'; + while ((optc = nextopt("HSatfdsmcnpl")) != '\0') + switch (optc) { + case 'H': + how = HARD; + break; + case 'S': + how = SOFT; + break; + case 'a': + all = 1; + break; + default: + what = optc; + } + + for (l = limits; l->name && l->option != what; l++) + ; + if (!l->name) + error("ulimit: internal error (%c)\n", what); + + set = *argptr ? 1 : 0; + if (set) { + char *p = *argptr; + + if (all || argptr[1]) + error("ulimit: too many arguments\n"); + if (strcmp(p, "unlimited") == 0) + val = RLIM_INFINITY; + else { + val = (quad_t) 0; + + while ((c = *p++) >= '0' && c <= '9') + { + val = (val * 10) + (long)(c - '0'); + if (val < (quad_t) 0) + break; + } + if (c) + error("ulimit: bad number\n"); + val *= l->factor; + } + } + if (all) { + for (l = limits; l->name; l++) { + getrlimit(l->cmd, &limit); + if (how & SOFT) + val = limit.rlim_cur; + else if (how & HARD) + val = limit.rlim_max; + + out1fmt("%-20s ", l->name); + if (val == RLIM_INFINITY) + out1fmt("unlimited\n"); + else + { + val /= l->factor; + out1fmt("%ld\n", (long) val); + } + } + return 0; + } + + getrlimit(l->cmd, &limit); + if (set) { + if (how & SOFT) + limit.rlim_cur = val; + if (how & HARD) + limit.rlim_max = val; + if (setrlimit(l->cmd, &limit) < 0) + error("ulimit: bad limit\n"); + } else { + if (how & SOFT) + val = limit.rlim_cur; + else if (how & HARD) + val = limit.rlim_max; + } + + if (!set) { + if (val == RLIM_INFINITY) + out1fmt("unlimited\n"); + else + { + val /= l->factor; + out1fmt("%ld\n", (long) val); + } } return 0; } diff --git a/bin/sh/mkbuiltins b/bin/sh/mkbuiltins index 48fc572..e2e6d14 100755 --- a/bin/sh/mkbuiltins +++ b/bin/sh/mkbuiltins @@ -34,14 +34,20 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)mkbuiltins 8.1 (Berkeley) 5/31/93 +# @(#)mkbuiltins 8.2 (Berkeley) 5/4/95 temp=/tmp/ka$$ havejobs=0 if grep '^#define JOBS[ ]*1' shell.h > /dev/null then havejobs=1 fi -exec > obj/builtins.c +havehist=1 +if [ "X$1" = "X-h" ]; then + havehist=0 + shift +fi +objdir=$1 +exec > ${objdir}/builtins.c cat <<\! /* * This file was generated by the mkbuiltins program. @@ -51,8 +57,8 @@ cat <<\! #include "builtins.h" ! -awk '/^[^#]/ {if('$havejobs' || $2 != "-j") print $0}' builtins | - sed 's/-j//' > $temp +awk '/^[^#]/ {if(('$havejobs' || $2 != "-j") && ('$havehist' || $2 != "-h")) \ + print $0}' builtins.def | sed 's/-j//' > $temp awk '{ printf "int %s();\n", $1}' $temp echo ' int (*const builtinfunc[])() = {' @@ -61,12 +67,12 @@ echo '}; const struct builtincmd builtincmd[] = {' awk '{ for (i = 2 ; i <= NF ; i++) { - printf "\t\"%s\", %d,\n", $i, NR-1 + printf "\t{ \"%s\", %d },\n", $i, NR-1 }}' $temp -echo ' NULL, 0 +echo ' { NULL, 0 } };' -exec > obj/builtins.h +exec > ${objdir}/builtins.h cat <<\! /* * This file was generated by the mkbuiltins program. diff --git a/bin/sh/mkinit.c b/bin/sh/mkinit.c index eac0374..de48a73 100644 --- a/bin/sh/mkinit.c +++ b/bin/sh/mkinit.c @@ -41,7 +41,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)mkinit.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)mkinit.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ /* @@ -59,6 +59,8 @@ static char sccsid[] = "@(#)mkinit.c 8.1 (Berkeley) 5/31/93"; #include <sys/cdefs.h> #include <sys/types.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <fcntl.h> #include <unistd.h> @@ -148,22 +150,31 @@ struct text decls; /* declarations */ int amiddecls; /* for formatting */ -void readfile(), doevent(), doinclude(), dodecl(), output(); -void addstr(), addchar(), writetext(); +void readfile __P((char *)); +int match __P((char *, char *)); +int gooddefine __P((char *)); +void doevent __P((struct event *, FILE *, char *)); +void doinclude __P((char *)); +void dodecl __P((char *, FILE *)); +void output __P((void)); +int file_changed __P((void)); +int touch __P((char *)); +void addstr __P((char *, struct text *)); +void addchar __P((int, struct text *)); +void writetext __P((struct text *, FILE *)); +FILE *ckfopen __P((char *, char *)); +void *ckmalloc __P((int)); +char *savestr __P((char *)); +void error __P((char *)); #define equal(s1, s2) (strcmp(s1, s2) == 0) -FILE *ckfopen(); -char *savestr(); -void *ckmalloc __P((int)); -void error(); - +int main(argc, argv) + int argc; char **argv; - { +{ char **ap; - int fd; - char c; if (argc < 2) error("Usage: mkinit command file..."); @@ -184,6 +195,8 @@ main(argc, argv) printf("%s\n", argv[1]); execl("/bin/sh", "sh", "-c", argv[1], (char *)0); error("Can't exec shell"); + + exit(1); } @@ -226,7 +239,7 @@ int match(name, line) char *name; char *line; - { +{ register char *p, *q; p = name, q = line; @@ -243,7 +256,7 @@ match(name, line) int gooddefine(line) char *line; - { +{ register char *p; if (! match("#define", line)) @@ -350,7 +363,7 @@ dodecl(line1, fp) if (! amiddecls) addchar('\n', &decls); q = NULL; - for (p = line1 + 6 ; *p != '=' && *p != '/' ; p++); + for (p = line1 + 6 ; *p != '\0' && *p != '=' && *p != '/' ; p++); if (*p == '=') { /* eliminate initialization */ for (q = p ; *q && *q != ';' ; q++); if (*q == '\0') @@ -405,7 +418,8 @@ output() { */ int -file_changed() { +file_changed() +{ register FILE *f1, *f2; register int c; @@ -427,7 +441,7 @@ file_changed() { int touch(file) char *file; - { +{ int fd; char c; @@ -467,8 +481,9 @@ addstr(s, text) void addchar(c, text) + int c; register struct text *text; - { +{ struct block *bp; if (--text->nleft < 0) { @@ -516,9 +531,10 @@ ckfopen(file, mode) } void * -ckmalloc(nbytes) { +ckmalloc(nbytes) + int nbytes; +{ register char *p; - char *malloc(); if ((p = malloc(nbytes)) == NULL) error("Out of space"); diff --git a/bin/sh/mknodes.c b/bin/sh/mknodes.c index d93ebc0..bdd190f 100644 --- a/bin/sh/mknodes.c +++ b/bin/sh/mknodes.c @@ -41,7 +41,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)mknodes.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ /* @@ -50,6 +50,13 @@ static char sccsid[] = "@(#)mknodes.c 8.1 (Berkeley) 5/31/93"; */ #include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif #define MAXTYPES 50 /* max number of node types */ @@ -80,27 +87,35 @@ struct str { /* struct representing a node structure */ }; -int ntypes; /* number of node types */ -char *nodename[MAXTYPES]; /* names of the nodes */ -struct str *nodestr[MAXTYPES]; /* type of structure used by the node */ -int nstr; /* number of structures */ -struct str str[MAXTYPES]; /* the structures */ -struct str *curstr; /* current structure */ - - -FILE *infp = stdin; -char line[1024]; -int linno; -char *linep; - - -char *savestr(); -#define equal(s1, s2) (strcmp(s1, s2) == 0) +static int ntypes; /* number of node types */ +static char *nodename[MAXTYPES]; /* names of the nodes */ +static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */ +static int nstr; /* number of structures */ +static struct str str[MAXTYPES]; /* the structures */ +static struct str *curstr; /* current structure */ +static FILE *infp = stdin; +static char line[1024]; +static int linno; +static char *linep; + +static void parsenode __P((void)); +static void parsefield __P((void)); +static void output __P((char *)); +static void outsizes __P((FILE *)); +static void outfunc __P((FILE *, int)); +static void indent __P((int, FILE *)); +static int nextfield __P((char *)); +static void skipbl __P((void)); +static int readline __P((void)); +static void error __P((const char *, ...)); +static char *savestr __P((const char *)); +int main(argc, argv) + int argc; char **argv; - { +{ if (argc != 3) error("usage: mknodes file\n"); if ((infp = fopen(argv[1], "r")) == NULL) @@ -117,7 +132,9 @@ main(argc, argv) -parsenode() { +static void +parsenode() +{ char name[BUFLEN]; char tag[BUFLEN]; struct str *sp; @@ -131,7 +148,7 @@ parsenode() { error("Garbage at end of line"); nodename[ntypes] = savestr(name); for (sp = str ; sp < str + nstr ; sp++) { - if (equal(sp->tag, tag)) + if (strcmp(sp->tag, tag) == 0) break; } if (sp >= str + nstr) { @@ -145,7 +162,9 @@ parsenode() { } -parsefield() { +static void +parsefield() +{ char name[BUFLEN]; char type[BUFLEN]; char decl[2 * BUFLEN]; @@ -159,21 +178,21 @@ parsefield() { error("No field type"); fp = &curstr->field[curstr->nfields]; fp->name = savestr(name); - if (equal(type, "nodeptr")) { + if (strcmp(type, "nodeptr") == 0) { fp->type = T_NODE; sprintf(decl, "union node *%s", name); - } else if (equal(type, "nodelist")) { + } else if (strcmp(type, "nodelist") == 0) { fp->type = T_NODELIST; sprintf(decl, "struct nodelist *%s", name); - } else if (equal(type, "string")) { + } else if (strcmp(type, "string") == 0) { fp->type = T_STRING; sprintf(decl, "char *%s", name); - } else if (equal(type, "int")) { + } else if (strcmp(type, "int") == 0) { fp->type = T_INT; sprintf(decl, "int %s", name); - } else if (equal(type, "other")) { + } else if (strcmp(type, "other") == 0) { fp->type = T_OTHER; - } else if (equal(type, "temp")) { + } else if (strcmp(type, "temp") == 0) { fp->type = T_TEMP; } else { error("Unknown type %s", type); @@ -196,9 +215,10 @@ char writer[] = "\ */\n\ \n"; +static void output(file) char *file; - { +{ FILE *hfile; FILE *cfile; FILE *patfile; @@ -245,11 +265,11 @@ output(file) fputs(writer, cfile); while (fgets(line, sizeof line, patfile) != NULL) { for (p = line ; *p == ' ' || *p == '\t' ; p++); - if (equal(p, "%SIZES\n")) + if (strcmp(p, "%SIZES\n") == 0) outsizes(cfile); - else if (equal(p, "%CALCSIZE\n")) + else if (strcmp(p, "%CALCSIZE\n") == 0) outfunc(cfile, 1); - else if (equal(p, "%COPY\n")) + else if (strcmp(p, "%COPY\n") == 0) outfunc(cfile, 0); else fputs(line, cfile); @@ -258,9 +278,10 @@ output(file) +static void outsizes(cfile) FILE *cfile; - { +{ int i; fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes); @@ -271,9 +292,11 @@ outsizes(cfile) } +static void outfunc(cfile, calcsize) FILE *cfile; - { + int calcsize; +{ struct str *sp; struct field *fp; int i; @@ -350,9 +373,11 @@ outfunc(cfile, calcsize) } +static void indent(amount, fp) + int amount; FILE *fp; - { +{ while (amount >= 8) { putc('\t', fp); amount -= 8; @@ -363,10 +388,10 @@ indent(amount, fp) } -int +static int nextfield(buf) char *buf; - { +{ register char *p, *q; p = linep; @@ -381,14 +406,17 @@ nextfield(buf) } -skipbl() { +static void +skipbl() +{ while (*linep == ' ' || *linep == '\t') linep++; } -int -readline() { +static int +readline() +{ register char *p; if (fgets(line, 1024, infp) == NULL) @@ -406,26 +434,42 @@ readline() { -error(msg, a1, a2, a3, a4, a5, a6) +static void +#if __STDC__ +error(const char *msg, ...) +#else +error(va_alist) + va_dcl +#endif +{ + va_list va; +#if __STDC__ + va_start(va, msg); +#else char *msg; - { - fprintf(stderr, "line %d: ", linno); - fprintf(stderr, msg, a1, a2, a3, a4, a5, a6); - putc('\n', stderr); + va_start(va); + msg = va_arg(va, char *); +#endif + + (void) fprintf(stderr, "line %d: ", linno); + (void) vfprintf(stderr, msg, va); + (void) fputc('\n', stderr); + + va_end(va); + exit(2); } -char * +static char * savestr(s) - char *s; - { + const char *s; +{ register char *p; - char *malloc(); if ((p = malloc(strlen(s) + 1)) == NULL) error("Out of space"); - strcpy(p, s); + (void) strcpy(p, s); return p; } diff --git a/bin/sh/mksyntax.c b/bin/sh/mksyntax.c index 1ab323d..11a4584 100644 --- a/bin/sh/mksyntax.c +++ b/bin/sh/mksyntax.c @@ -41,7 +41,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)mksyntax.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)mksyntax.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ /* @@ -49,6 +49,7 @@ static char sccsid[] = "@(#)mksyntax.c 8.1 (Berkeley) 5/31/93"; */ #include <stdio.h> +#include <string.h> #include "parser.h" @@ -59,21 +60,21 @@ struct synclass { /* Syntax classes */ struct synclass synclass[] = { - "CWORD", "character is nothing special", - "CNL", "newline character", - "CBACK", "a backslash character", - "CSQUOTE", "single quote", - "CDQUOTE", "double quote", - "CENDQUOTE", "a terminating quote", - "CBQUOTE", "backwards single quote", - "CVAR", "a dollar sign", - "CENDVAR", "a '}' character", - "CLP", "a left paren in arithmetic", - "CRP", "a right paren in arithmetic", - "CEOF", "end of file", - "CCTL", "like CWORD, except it must be escaped", - "CSPCL", "these terminate a word", - NULL, NULL + { "CWORD", "character is nothing special" }, + { "CNL", "newline character" }, + { "CBACK", "a backslash character" }, + { "CSQUOTE", "single quote" }, + { "CDQUOTE", "double quote" }, + { "CENDQUOTE", "a terminating quote" }, + { "CBQUOTE", "backwards single quote" }, + { "CVAR", "a dollar sign" }, + { "CENDVAR", "a '}' character" }, + { "CLP", "a left paren in arithmetic" }, + { "CRP", "a right paren in arithmetic" }, + { "CEOF", "end of file" }, + { "CCTL", "like CWORD, except it must be escaped" }, + { "CSPCL", "these terminate a word" }, + { NULL, NULL } }; @@ -82,31 +83,41 @@ struct synclass synclass[] = { * you may have to change the definition of the is_in_name macro. */ struct synclass is_entry[] = { - "ISDIGIT", "a digit", - "ISUPPER", "an upper case letter", - "ISLOWER", "a lower case letter", - "ISUNDER", "an underscore", - "ISSPECL", "the name of a special parameter", - NULL, NULL, + { "ISDIGIT", "a digit" }, + { "ISUPPER", "an upper case letter" }, + { "ISLOWER", "a lower case letter" }, + { "ISUNDER", "an underscore" }, + { "ISSPECL", "the name of a special parameter" }, + { NULL, NULL } }; -char writer[] = "\ +static char writer[] = "\ /*\n\ * This file was generated by the mksyntax program.\n\ */\n\ \n"; -FILE *cfile; -FILE *hfile; -char *syntax[513]; -int base; -int size; /* number of values which a char variable can have */ -int nbits; /* number of bits in a character */ -int digit_contig; /* true if digits are contiguous */ - - -main() { +static FILE *cfile; +static FILE *hfile; +static char *syntax[513]; +static int base; +static int size; /* number of values which a char variable can have */ +static int nbits; /* number of bits in a character */ +static int digit_contig;/* true if digits are contiguous */ + +static void filltable __P((char *)); +static void init __P((void)); +static void add __P((char *, char *)); +static void print __P((char *)); +static void output_type_macros __P((void)); +static void digit_convert __P((void)); + +int +main(argc, argv) + int argc; + char **argv; +{ char c; char d; int sign; @@ -160,7 +171,7 @@ main() { for (i = 0 ; synclass[i].name ; i++) { sprintf(buf, "#define %s %d", synclass[i].name, i); fputs(buf, hfile); - for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07) + for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) putc('\t', hfile); fprintf(hfile, "/* %s */\n", synclass[i].comment); } @@ -169,7 +180,7 @@ main() { for (i = 0 ; is_entry[i].name ; i++) { sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i); fputs(buf, hfile); - for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07) + for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) putc('\t', hfile); fprintf(hfile, "/* %s */\n", is_entry[i].comment); } @@ -207,13 +218,15 @@ main() { add("`", "CBQUOTE"); add("$", "CVAR"); add("}", "CENDVAR"); - add("!*?[=~:/", "CCTL"); /* ':/' for tilde - yuck */ + /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ + add("!*?[=~:/-", "CCTL"); print("dqsyntax"); init(); fputs("\n/* syntax table used when in single quotes */\n", cfile); add("\n", "CNL"); add("'", "CENDQUOTE"); - add("!*?[=~:/", "CCTL"); /* ':/' for tilde - yuck */ + /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ + add("!*?[=~:/-", "CCTL"); print("sqsyntax"); init(); fputs("\n/* syntax table used when in arithmetic */\n", cfile); @@ -246,9 +259,10 @@ main() { * Clear the syntax table. */ +static void filltable(dftval) char *dftval; - { +{ int i; for (i = 0 ; i < size ; i++) @@ -260,7 +274,9 @@ filltable(dftval) * Initialize the syntax table with default values. */ -init() { +static void +init() +{ filltable("CWORD"); syntax[0] = "CEOF"; syntax[base + CTLESC] = "CCTL"; @@ -277,9 +293,10 @@ init() { * Add entries to the syntax table. */ +static void add(p, type) char *p, *type; - { +{ while (*p) syntax[*p++ + base] = type; } @@ -290,9 +307,10 @@ add(p, type) * Output the syntax table. */ +static void print(name) char *name; - { +{ int i; int col; @@ -323,7 +341,7 @@ print(name) * contiguous, we can test for them quickly. */ -char *macro[] = { +static char *macro[] = { "#define is_digit(c)\t((is_type+SYNBASE)[c] & ISDIGIT)", "#define is_alpha(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER))", "#define is_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER))", @@ -332,7 +350,9 @@ char *macro[] = { NULL }; -output_type_macros() { +static void +output_type_macros() +{ char **pp; if (digit_contig) @@ -351,7 +371,9 @@ output_type_macros() { * Output digit conversion table (if digits are not contiguous). */ -digit_convert() { +static void +digit_convert() +{ int maxdigit; static char digit[] = "0123456789"; char *p; diff --git a/bin/sh/myhistedit.h b/bin/sh/myhistedit.h index bfa4c11..bea6ce1 100644 --- a/bin/sh/myhistedit.h +++ b/bin/sh/myhistedit.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)myhistedit.h 8.1 (Berkeley) 5/31/93 + * @(#)myhistedit.h 8.2 (Berkeley) 5/4/95 */ #include <histedit.h> @@ -38,3 +38,10 @@ extern History *hist; extern EditLine *el; extern int displayhist; + +void histedit __P((void)); +void sethistsize __P((void)); +int histcmd __P((int, char **)); +int not_fcnumber __P((char *)); +int str_to_event __P((char *, int)); + diff --git a/bin/sh/mystring.c b/bin/sh/mystring.c index 1b9eeea..33ef29d 100644 --- a/bin/sh/mystring.c +++ b/bin/sh/mystring.c @@ -35,7 +35,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)mystring.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ /* @@ -48,6 +48,7 @@ static char sccsid[] = "@(#)mystring.c 8.1 (Berkeley) 5/31/93"; * is_number(s) Return true if s is a string of digits. */ +#include <stdlib.h> #include "shell.h" #include "syntax.h" #include "error.h" diff --git a/bin/sh/mystring.h b/bin/sh/mystring.h index 27ec4ed..d688726 100644 --- a/bin/sh/mystring.h +++ b/bin/sh/mystring.h @@ -33,22 +33,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)mystring.h 8.1 (Berkeley) 5/31/93 + * @(#)mystring.h 8.2 (Berkeley) 5/4/95 */ #include <string.h> -#ifdef __STDC__ -void scopyn(const char *, char *, int); -int prefix(const char *, const char *); -int number(const char *); -int is_number(const char *); -#else -void scopyn(); -int prefix(); -int number(); -int is_number(); -#endif +void scopyn __P((const char *, char *, int)); +int prefix __P((const char *, const char *)); +int number __P((const char *)); +int is_number __P((const char *)); #define equal(s1, s2) (strcmp(s1, s2) == 0) #define scopy(s1, s2) ((void)strcpy(s2, s1)) diff --git a/bin/sh/nodes.c.pat b/bin/sh/nodes.c.pat index 81c96bf..663ed05 100644 --- a/bin/sh/nodes.c.pat +++ b/bin/sh/nodes.c.pat @@ -33,9 +33,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)nodes.c.pat 8.1 (Berkeley) 5/31/93 + * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 */ +#include <stdlib.h> /* * Routine for dealing with parsed shell commands. */ @@ -47,31 +48,19 @@ #include "mystring.h" -int funcblocksize; /* size of structures in function */ -int funcstringsize; /* size of strings in node */ -#ifdef __STDC__ +int funcblocksize; /* size of structures in function */ +int funcstringsize; /* size of strings in node */ pointer funcblock; /* block to allocate function from */ -#else -char *funcblock; /* block to allocate function from */ -#endif -char *funcstring; /* block to allocate strings from */ +char *funcstring; /* block to allocate strings from */ %SIZES -#ifdef __STDC__ -STATIC void calcsize(union node *); -STATIC void sizenodelist(struct nodelist *); -STATIC union node *copynode(union node *); -STATIC struct nodelist *copynodelist(struct nodelist *); -STATIC char *nodesavestr(char *); -#else -STATIC void calcsize(); -STATIC void sizenodelist(); -STATIC union node *copynode(); -STATIC struct nodelist *copynodelist(); -STATIC char *nodesavestr(); -#endif +STATIC void calcsize __P((union node *)); +STATIC void sizenodelist __P((struct nodelist *)); +STATIC union node *copynode __P((union node *)); +STATIC struct nodelist *copynodelist __P((struct nodelist *)); +STATIC char *nodesavestr __P((char *)); @@ -81,85 +70,86 @@ STATIC char *nodesavestr(); union node * copyfunc(n) - union node *n; - { - if (n == NULL) - return NULL; - funcblocksize = 0; - funcstringsize = 0; - calcsize(n); - funcblock = ckmalloc(funcblocksize + funcstringsize); - funcstring = funcblock + funcblocksize; - return copynode(n); + union node *n; +{ + if (n == NULL) + return NULL; + funcblocksize = 0; + funcstringsize = 0; + calcsize(n); + funcblock = ckmalloc(funcblocksize + funcstringsize); + funcstring = funcblock + funcblocksize; + return copynode(n); } STATIC void calcsize(n) - union node *n; - { - %CALCSIZE + union node *n; +{ + %CALCSIZE } STATIC void sizenodelist(lp) - struct nodelist *lp; - { - while (lp) { - funcblocksize += ALIGN(sizeof (struct nodelist)); - calcsize(lp->n); - lp = lp->next; - } + struct nodelist *lp; +{ + while (lp) { + funcblocksize += ALIGN(sizeof(struct nodelist)); + calcsize(lp->n); + lp = lp->next; + } } STATIC union node * copynode(n) - union node *n; - { - union node *new; + union node *n; +{ + union node *new; - %COPY - return new; + %COPY + return new; } STATIC struct nodelist * copynodelist(lp) - struct nodelist *lp; - { - struct nodelist *start; - struct nodelist **lpp; - - lpp = &start; - while (lp) { - *lpp = funcblock; - funcblock += ALIGN(sizeof (struct nodelist)); - (*lpp)->n = copynode(lp->n); - lp = lp->next; - lpp = &(*lpp)->next; - } - *lpp = NULL; - return start; + struct nodelist *lp; +{ + struct nodelist *start; + struct nodelist **lpp; + + lpp = &start; + while (lp) { + *lpp = funcblock; + funcblock += ALIGN(sizeof(struct nodelist)); + (*lpp)->n = copynode(lp->n); + lp = lp->next; + lpp = &(*lpp)->next; + } + *lpp = NULL; + return start; } STATIC char * nodesavestr(s) - char *s; - { - register char *p = s; - register char *q = funcstring; - char *rtn = funcstring; - - while (*q++ = *p++); - funcstring = q; - return rtn; + char *s; +{ + register char *p = s; + register char *q = funcstring; + char *rtn = funcstring; + + while ((*q++ = *p++) != '\0') + continue; + funcstring = q; + return rtn; } @@ -170,8 +160,8 @@ nodesavestr(s) void freefunc(n) - union node *n; - { - if (n) - ckfree(n); + union node *n; +{ + if (n) + ckfree(n); } diff --git a/bin/sh/nodetypes b/bin/sh/nodetypes index d60e769..f9e3ad7 100644 --- a/bin/sh/nodetypes +++ b/bin/sh/nodetypes @@ -33,7 +33,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)nodetypes 8.1 (Berkeley) 5/31/93 +# @(#)nodetypes 8.2 (Berkeley) 5/4/95 # This file describes the nodes used in parse trees. Unindented lines # contain a node type followed by a structure tag. Subsequent indented @@ -130,6 +130,8 @@ NFROMFD ndup # fd>&dupfd next nodeptr # next redirection in list fd int # file descriptor being redirected dupfd int # file descriptor to duplicate + vname nodeptr # file name if fd>&$var + NHERE nhere # fd<<\! NXHERE nhere # fd<<! diff --git a/bin/sh/options.c b/bin/sh/options.c index 9363e62..df359f4 100644 --- a/bin/sh/options.c +++ b/bin/sh/options.c @@ -35,9 +35,13 @@ */ #ifndef lint -static char sccsid[] = "@(#)options.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> + #include "shell.h" #define DEFINE_OPTIONS #include "options.h" @@ -52,6 +56,9 @@ static char sccsid[] = "@(#)options.c 8.1 (Berkeley) 5/31/93"; #include "memalloc.h" #include "error.h" #include "mystring.h" +#ifndef NO_HISTORY +#include "myhistedit.h" +#endif char *arg0; /* value of $0 */ struct shparam shellparam; /* current positional parameters */ @@ -62,16 +69,9 @@ char *optptr; /* used by nextopt */ char *minusc; /* argument to -c option */ -#ifdef __STDC__ -STATIC void options(int); -STATIC void setoption(int, int); -STATIC void minus_o(char *, int); -#else -STATIC void options(); -STATIC void setoption(); -STATIC void minus_o(); -#endif - +STATIC void options __P((int)); +STATIC void minus_o __P((char *, int)); +STATIC void setoption __P((int, int)); /* @@ -80,8 +80,9 @@ STATIC void minus_o(); void procargs(argc, argv) + int argc; char **argv; - { +{ int i; argptr = argv; @@ -114,9 +115,13 @@ procargs(argc, argv) } -optschanged() { +void +optschanged() +{ setinteractive(iflag); +#ifndef NO_HISTORY histedit(); +#endif setjobctl(mflag); } @@ -126,7 +131,9 @@ optschanged() { */ STATIC void -options(cmdline) { +options(cmdline) + int cmdline; +{ register char *p; int val; int c; @@ -137,14 +144,14 @@ options(cmdline) { argptr++; if ((c = *p++) == '-') { val = 1; - if (p[0] == '\0' || p[0] == '-' && p[1] == '\0') { + if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { if (!cmdline) { /* "-" means turn off -x and -v */ if (p[0] == '\0') xflag = vflag = 0; /* "--" means reset params */ else if (*argptr == NULL) - setparam(argptr); + setparam(argptr); } break; /* "-" or "--" terminates options */ } @@ -288,7 +295,11 @@ freeparam(param) * The shift builtin command. */ -shiftcmd(argc, argv) char **argv; { +int +shiftcmd(argc, argv) + int argc; + char **argv; +{ int n; char **ap1, **ap2; @@ -316,7 +327,11 @@ shiftcmd(argc, argv) char **argv; { * The set command builtin. */ -setcmd(argc, argv) char **argv; { +int +setcmd(argc, argv) + int argc; + char **argv; +{ if (argc == 1) return showvarscmd(argc, argv); INTOFF; @@ -337,7 +352,11 @@ setcmd(argc, argv) char **argv; { * then it's the first time getopts has been called. */ -getoptscmd(argc, argv) char **argv; { +int +getoptscmd(argc, argv) + int argc; + char **argv; +{ register char *p, *q; char c; char s[10]; diff --git a/bin/sh/options.h b/bin/sh/options.h index 7d00f55..89dfbf7 100644 --- a/bin/sh/options.h +++ b/bin/sh/options.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)options.h 8.1 (Berkeley) 5/31/93 + * @(#)options.h 8.2 (Berkeley) 5/4/95 */ struct shparam { @@ -72,21 +72,21 @@ struct optent { #ifdef DEFINE_OPTIONS struct optent optlist[NOPTS] = { - "errexit", 'e', 0, - "noglob", 'f', 0, - "ignoreeof", 'I', 0, - "interactive", 'i', 0, - "monitor", 'm', 0, - "noexec", 'n', 0, - "stdin", 's', 0, - "xtrace", 'x', 0, - "verbose", 'v', 0, - "vi", 'V', 0, - "emacs", 'E', 0, - "noclobber", 'C', 0, - "allexport", 'a', 0, - "notify", 'b', 0, - "nounset", 'u', 0, + { "errexit", 'e', 0 }, + { "noglob", 'f', 0 }, + { "ignoreeof", 'I', 0 }, + { "interactive",'i', 0 }, + { "monitor", 'm', 0 }, + { "noexec", 'n', 0 }, + { "stdin", 's', 0 }, + { "xtrace", 'x', 0 }, + { "verbose", 'v', 0 }, + { "vi", 'V', 0 }, + { "emacs", 'E', 0 }, + { "noclobber", 'C', 0 }, + { "allexport", 'a', 0 }, + { "notify", 'b', 0 }, + { "nounset", 'u', 0 }, }; #else extern struct optent optlist[NOPTS]; @@ -100,15 +100,11 @@ extern char **argptr; /* argument list for builtin commands */ extern char *optarg; /* set by nextopt */ extern char *optptr; /* used by nextopt */ - -#ifdef __STDC__ -void procargs(int, char **); -void setparam(char **); -void freeparam(struct shparam *); -int nextopt(char *); -#else -void procargs(); -void setparam(); -void freeparam(); -int nextopt(); -#endif +void procargs __P((int, char **)); +void optschanged __P((void)); +void setparam __P((char **)); +void freeparam __P((struct shparam *)); +int shiftcmd __P((int, char **)); +int setcmd __P((int, char **)); +int getoptscmd __P((int, char **)); +int nextopt __P((char *)); diff --git a/bin/sh/output.c b/bin/sh/output.c index 88ef764..e4c5b86 100644 --- a/bin/sh/output.c +++ b/bin/sh/output.c @@ -35,7 +35,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ /* @@ -49,18 +49,24 @@ static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 5/31/93"; * Our output routines may be smaller than the stdio routines. */ +#include <sys/ioctl.h> + #include <stdio.h> /* defines BUFSIZ */ -#include "shell.h" -#include "syntax.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" +#include <string.h> #ifdef __STDC__ -#include "stdarg.h" +#include <stdarg.h> #else #include <varargs.h> #endif #include <errno.h> +#include <unistd.h> +#include <stdlib.h> + +#include "shell.h" +#include "syntax.h" +#include "output.h" +#include "memalloc.h" +#include "error.h" #define OUTBUFSIZ BUFSIZ @@ -115,7 +121,7 @@ open_mem(block, length, file) void out1str(p) - char *p; + const char *p; { outstr(p, out1); } @@ -123,7 +129,7 @@ out1str(p) void out2str(p) - char *p; + const char *p; { outstr(p, out2); } @@ -131,7 +137,7 @@ out2str(p) void outstr(p, file) - register char *p; + register const char *p; register struct output *file; { while (*p) @@ -543,10 +549,15 @@ xwrite(fd, buf, nbytes) /* * Version of ioctl that retries after a signal is caught. + * XXX unused function */ int -xioctl(fd, request, arg) { +xioctl(fd, request, arg) + int fd; + unsigned long request; + char * arg; +{ int i; while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR); diff --git a/bin/sh/output.h b/bin/sh/output.h index 5b4764c..d7690c5 100644 --- a/bin/sh/output.h +++ b/bin/sh/output.h @@ -33,11 +33,17 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)output.h 8.1 (Berkeley) 5/31/93 + * @(#)output.h 8.2 (Berkeley) 5/4/95 */ #ifndef OUTPUT_INCL +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + struct output { char *nextc; int nleft; @@ -53,38 +59,21 @@ extern struct output memout; extern struct output *out1; extern struct output *out2; - -#ifdef __STDC__ -void outstr(char *, struct output *); -void out1str(char *); -void out2str(char *); -void outfmt(struct output *, char *, ...); -void out1fmt(char *, ...); -void fmtstr(char *, int, char *, ...); -/* void doformat(struct output *, char *, va_list); */ -void doformat(); -void emptyoutbuf(struct output *); -void flushall(void); -void flushout(struct output *); -void freestdout(void); -int xwrite(int, char *, int); -int xioctl(int, int, int); -#else -void outstr(); -void out1str(); -void out2str(); -void outfmt(); -void out1fmt(); -void fmtstr(); -/* void doformat(); */ -void doformat(); -void emptyoutbuf(); -void flushall(); -void flushout(); -void freestdout(); -int xwrite(); -int xioctl(); -#endif +void open_mem __P((char *, int, struct output *)); +void out1str __P((const char *)); +void out2str __P((const char *)); +void outstr __P((const char *, struct output *)); +void emptyoutbuf __P((struct output *)); +void flushall __P((void)); +void flushout __P((struct output *)); +void freestdout __P((void)); +void outfmt __P((struct output *, char *, ...)); +void out1fmt __P((char *, ...)); +void dprintf __P((char *, ...)); +void fmtstr __P((char *, int, char *, ...)); +void doformat __P((struct output *, char *, va_list)); +int xwrite __P((int, char *, int)); +int xioctl __P((int, unsigned long, char *)); #define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c))) #define out1c(c) outc(c, out1); diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 898349f..51f2cdb 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -35,9 +35,11 @@ */ #ifndef lint -static char sccsid[] = "@(#)parser.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; #endif /* not lint */ +#include <stdlib.h> + #include "shell.h" #include "parser.h" #include "nodes.h" @@ -52,8 +54,10 @@ static char sccsid[] = "@(#)parser.c 8.1 (Berkeley) 5/31/93"; #include "memalloc.h" #include "mystring.h" #include "alias.h" +#include "show.h" +#ifndef NO_HISTORY #include "myhistedit.h" - +#endif /* * Shell command parser. @@ -102,15 +106,18 @@ STATIC union node *andor __P((void)); STATIC union node *pipeline __P((void)); STATIC union node *command __P((void)); STATIC union node *simplecmd __P((union node **, union node *)); +STATIC union node *makename __P((void)); STATIC void parsefname __P((void)); STATIC void parseheredoc __P((void)); +STATIC int peektoken __P((void)); STATIC int readtoken __P((void)); +STATIC int xxreadtoken __P((void)); STATIC int readtoken1 __P((int, char const *, char *, int)); -STATIC void attyline __P((void)); STATIC int noexpand __P((char *)); STATIC void synexpect __P((int)); STATIC void synerror __P((char *)); -STATIC void setprompt __P((int)); +STATIC void setprompt __P((int)); + /* * Read and parse a command. Returns NEOF on end of file. (NULL is a @@ -118,7 +125,9 @@ STATIC void setprompt __P((int)); */ union node * -parsecmd(interact) { +parsecmd(interact) + int interact; +{ int t; doprompt = interact; @@ -138,33 +147,49 @@ parsecmd(interact) { STATIC union node * -list(nlflag) { +list(nlflag) + int nlflag; +{ union node *n1, *n2, *n3; + int tok; checkkwd = 2; if (nlflag == 0 && tokendlist[peektoken()]) return NULL; - n1 = andor(); + n1 = NULL; for (;;) { - switch (readtoken()) { - case TBACKGND: - if (n1->type == NCMD || n1->type == NPIPE) { - n1->ncmd.backgnd = 1; - } else if (n1->type == NREDIR) { - n1->type = NBACKGND; + n2 = andor(); + tok = readtoken(); + if (tok == TBACKGND) { + if (n2->type == NCMD || n2->type == NPIPE) { + n2->ncmd.backgnd = 1; + } else if (n2->type == NREDIR) { + n2->type = NBACKGND; } else { n3 = (union node *)stalloc(sizeof (struct nredir)); n3->type = NBACKGND; - n3->nredir.n = n1; + n3->nredir.n = n2; n3->nredir.redirect = NULL; - n1 = n3; + n2 = n3; } - goto tsemi; - case TNL: - tokpushback++; + } + if (n1 == NULL) { + n1 = n2; + } + else { + n3 = (union node *)stalloc(sizeof (struct nbinary)); + n3->type = NSEMI; + n3->nbinary.ch1 = n1; + n3->nbinary.ch2 = n2; + n1 = n3; + } + switch (tok) { + case TBACKGND: + case TSEMI: + tok = readtoken(); /* fall through */ -tsemi: case TSEMI: - if (readtoken() == TNL) { + case TNL: + if (tok == TNL) { parseheredoc(); if (nlflag) return n1; @@ -174,12 +199,6 @@ tsemi: case TSEMI: checkkwd = 2; if (tokendlist[peektoken()]) return n1; - n2 = andor(); - n3 = (union node *)stalloc(sizeof (struct nbinary)); - n3->type = NSEMI; - n3->nbinary.ch1 = n1; - n3->nbinary.ch2 = n2; - n1 = n3; break; case TEOF: if (heredoclist) @@ -274,7 +293,8 @@ command() { int t; checkkwd = 2; - redir = 0; + redir = NULL; + n1 = NULL; rpp = &redir; /* Check for redirection which may precede command */ while (readtoken() == TREDIR) { @@ -392,7 +412,8 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); if (lasttoken != TWORD || ! equal(wordtext, "in")) synerror("expecting \"in\""); cpp = &n1->ncase.cases; - while (checkkwd = 2, readtoken() == TWORD) { + checkkwd = 2, readtoken(); + do { *cpp = cp = (union node *)stalloc(sizeof (struct nclist)); cp->type = NCLIST; app = &cp->nclist.pattern; @@ -401,25 +422,26 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); ap->type = NARG; ap->narg.text = wordtext; ap->narg.backquote = backquotelist; - if (readtoken() != TPIPE) + if (checkkwd = 2, readtoken() != TPIPE) break; app = &ap->narg.next; - if (readtoken() != TWORD) - synexpect(TWORD); + readtoken(); } ap->narg.next = NULL; if (lasttoken != TRP) synexpect(TRP); cp->nclist.body = list(0); - if ((t = readtoken()) == TESAC) - tokpushback++; - else if (t != TENDCASE) - synexpect(TENDCASE); + + checkkwd = 2; + if ((t = readtoken()) != TESAC) { + if (t != TENDCASE) + synexpect(TENDCASE); + else + checkkwd = 2, readtoken(); + } cpp = &cp->nclist.next; - } + } while(lasttoken != TESAC); *cpp = NULL; - if (lasttoken != TESAC) - synexpect(TESAC); checkkwd = 1; break; case TLP: @@ -438,8 +460,17 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); checkkwd = 1; break; /* Handle an empty command like other simple commands. */ + case TSEMI: + /* + * An empty command before a ; doesn't make much sense, and + * should certainly be disallowed in the case of `if ;'. + */ + if (!redir) + synexpect(-1); case TNL: + case TEOF: case TWORD: + case TRP: tokpushback++; return simplecmd(rpp, redir); default: @@ -528,6 +559,40 @@ simplecmd(rpp, redir) return n; } +STATIC union node * +makename() { + union node *n; + + n = (union node *)stalloc(sizeof (struct narg)); + n->type = NARG; + n->narg.next = NULL; + n->narg.text = wordtext; + n->narg.backquote = backquotelist; + return n; +} + +void fixredir(n, text, err) + union node *n; + const char *text; + int err; + { + TRACE(("Fix redir %s %d\n", text, err)); + if (!err) + n->ndup.vname = NULL; + + if (is_digit(text[0]) && text[1] == '\0') + n->ndup.dupfd = digit_val(text[0]); + else if (text[0] == '-' && text[1] == '\0') + n->ndup.dupfd = -1; + else { + + if (err) + synerror("Bad fd number"); + else + n->ndup.vname = makename(); + } +} + STATIC void parsefname() { @@ -559,23 +624,9 @@ parsefname() { p->next = here; } } else if (n->type == NTOFD || n->type == NFROMFD) { - if (is_digit(wordtext[0])) - n->ndup.dupfd = digit_val(wordtext[0]); - else if (wordtext[0] == '-') - n->ndup.dupfd = -1; - else - goto bad; - if (wordtext[1] != '\0') { -bad: - synerror("Bad fd number"); - } + fixredir(n, wordtext, 0); } else { - n->nfile.fname = (union node *)stalloc(sizeof (struct narg)); - n = n->nfile.fname; - n->type = NARG; - n->narg.next = NULL; - n->narg.text = wordtext; - n->narg.backquote = backquotelist; + n->nfile.fname = makename(); } } @@ -645,17 +696,19 @@ readtoken() { /* * check for keywords and aliases */ - if (t == TWORD && !quoteflag) { - register char * const *pp, *s; + if (t == TWORD && !quoteflag) + { + register char * const *pp; for (pp = (char **)parsekwd; *pp; pp++) { - if (**pp == *wordtext && equal(*pp, wordtext)) { + if (**pp == *wordtext && equal(*pp, wordtext)) + { lasttoken = t = pp - parsekwd + KWDOFFSET; TRACE(("keyword %s recognized\n", tokname[t])); goto out; } } - if (ap = lookupalias(wordtext, 1)) { + if ((ap = lookupalias(wordtext, 1)) != NULL) { pushstring(ap->val, strlen(ap->val), ap); checkkwd = savecheckkwd; goto top; @@ -791,8 +844,8 @@ readtoken1(firstc, syntax, eofmark, striptabs) char *eofmark; int striptabs; { - register c = firstc; - register char *out; + int c = firstc; + char *out; int len; char line[EOFMARKLEN + 1]; struct nodelist *bqlist; @@ -803,6 +856,18 @@ readtoken1(firstc, syntax, eofmark, striptabs) int parenlevel; /* levels of parens in arithmetic */ int oldstyle; char const *prevsyntax; /* syntax before arithmetic */ +#if __GNUC__ + /* Avoid longjmp clobbering */ + (void) &out; + (void) "ef; + (void) &dblquote; + (void) &varnest; + (void) &arinest; + (void) &parenlevel; + (void) &oldstyle; + (void) &prevsyntax; + (void) &syntax; +#endif startlinno = plinno; dblquote = 0; @@ -829,13 +894,6 @@ readtoken1(firstc, syntax, eofmark, striptabs) CHECKEND(); /* set c to PEOF if at end of here document */ for (;;) { /* until end of line or end of word */ CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ - if (parsebackquote && c == '\\') { - c = pgetc(); /* XXX - compat with old /bin/sh */ - if (c != '\\' && c != '`' && c != '$') { - pungetc(); - c = '\\'; - } - } switch(syntax[c]) { case CNL: /* '\n' */ if (syntax == BASESYNTAX) @@ -1093,7 +1151,14 @@ parsesub: { subtype = VSNORMAL; if (c == '{') { c = pgetc(); - subtype = 0; + if (c == '#') { + if ((c = pgetc()) == '}') + c = '#'; + else + subtype = VSLENGTH; + } + else + subtype = 0; } if (is_name(c)) { do { @@ -1109,14 +1174,31 @@ badsub: synerror("Bad substitution"); STPUTC('=', out); flags = 0; if (subtype == 0) { - if (c == ':') { + switch (c) { + case ':': flags = VSNUL; c = pgetc(); + /*FALLTHROUGH*/ + default: + p = strchr(types, c); + if (p == NULL) + goto badsub; + subtype = p - types + VSNORMAL; + break; + case '%': + case '#': + { + int cc = c; + subtype = c == '#' ? VSTRIMLEFT : + VSTRIMRIGHT; + c = pgetc(); + if (c == cc) + subtype++; + else + pungetc(); + break; + } } - p = strchr(types, c); - if (p == NULL) - goto badsub; - subtype = p - types + VSNORMAL; } else { pungetc(); } @@ -1159,7 +1241,7 @@ parsebackq: { savelen = out - stackblock(); if (savelen > 0) { str = ckmalloc(savelen); - bcopy(stackblock(), str, savelen); + memcpy(str, stackblock(), savelen); } savehandler = handler; handler = &jmploc; @@ -1187,9 +1269,9 @@ parsebackq: { savelen = out - stackblock(); if (savelen > 0) { str = ckmalloc(savelen); - bcopy(stackblock(), str, savelen); + memcpy(str, stackblock(), savelen); + setinputstring(str, 1); } - setinputstring(str, 1); } nlpp = &bqlist; while (*nlpp) @@ -1208,7 +1290,7 @@ parsebackq: { growstackblock(); STARTSTACKSTR(out); if (str) { - bcopy(str, out, savelen); + memcpy(out, str, savelen); STADJUST(savelen, out); INTOFF; ckfree(str); @@ -1309,7 +1391,9 @@ goodname(name) */ STATIC void -synexpect(token) { +synexpect(token) + int token; +{ char msg[64]; if (token >= 0) { @@ -1338,7 +1422,9 @@ setprompt(which) { whichprompt = which; +#ifndef NO_HISTORY if (!el) +#endif out2str(getprompt(NULL)); } diff --git a/bin/sh/parser.h b/bin/sh/parser.h index e1c3c23..0134c3f 100644 --- a/bin/sh/parser.h +++ b/bin/sh/parser.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)parser.h 8.1 (Berkeley) 5/31/93 + * @(#)parser.h 8.3 (Berkeley) 5/4/95 */ /* control characters in argument strings */ @@ -47,16 +47,21 @@ #define CTLENDARI '\207' /* variable substitution byte (follows CTLVAR) */ -#define VSTYPE 07 /* type of variable substitution */ -#define VSNUL 040 /* colon--treat the empty string as unset */ -#define VSQUOTE 0100 /* inside double quotes--suppress splitting */ +#define VSTYPE 0x0f /* type of variable substitution */ +#define VSNUL 0x10 /* colon--treat the empty string as unset */ +#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */ /* values of VSTYPE field */ -#define VSNORMAL 1 /* normal variable: $var or ${var} */ -#define VSMINUS 2 /* ${var-text} */ -#define VSPLUS 3 /* ${var+text} */ -#define VSQUESTION 4 /* ${var?message} */ -#define VSASSIGN 5 /* ${var=text} */ +#define VSNORMAL 0x1 /* normal variable: $var or ${var} */ +#define VSMINUS 0x2 /* ${var-text} */ +#define VSPLUS 0x3 /* ${var+text} */ +#define VSQUESTION 0x4 /* ${var?message} */ +#define VSASSIGN 0x5 /* ${var=text} */ +#define VSTRIMLEFT 0x6 /* ${var#pattern} */ +#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */ +#define VSTRIMRIGHT 0x8 /* ${var%pattern} */ +#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ +#define VSLENGTH 0xa /* ${#var} */ /* @@ -69,12 +74,7 @@ extern int tokpushback; extern int whichprompt; /* 1 == PS1, 2 == PS2 */ -#ifdef __STDC__ -union node *parsecmd(int); -int goodname(char *); -char *getprompt(void *); -#else -union node *parsecmd(); -int goodname(); -char *getprompt(); -#endif +union node *parsecmd __P((int)); +void fixredir __P((union node *, const char *, int)); +int goodname __P((char *)); +char *getprompt __P((void *)); diff --git a/bin/sh/redir.c b/bin/sh/redir.c index b91ce5a..26b0a32 100644 --- a/bin/sh/redir.c +++ b/bin/sh/redir.c @@ -35,9 +35,17 @@ */ #ifndef lint -static char sccsid[] = "@(#)redir.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ +#include <sys/types.h> +#include <signal.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> + /* * Code for dealing with input/output redirection. */ @@ -50,11 +58,6 @@ static char sccsid[] = "@(#)redir.c 8.1 (Berkeley) 5/31/93"; #include "output.h" #include "memalloc.h" #include "error.h" -#include <sys/types.h> -#include <signal.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> #define EMPTY -2 /* marks an unused slot in redirtab */ @@ -77,14 +80,8 @@ MKINIT struct redirtab *redirlist; */ int fd0_redirected = 0; -#ifdef __STDC__ -STATIC void openredirect(union node *, char *); -STATIC int openhere(union node *); -#else -STATIC void openredirect(); -STATIC int openhere(); -#endif - +STATIC void openredirect __P((union node *, char[10 ])); +STATIC int openhere __P((union node *)); /* @@ -221,7 +218,7 @@ openhere(redir) union node *redir; { int pip[2]; - int len; + int len = 0; if (pipe(pip) < 0) error("Pipe call failed"); @@ -333,7 +330,10 @@ clearredir() { */ int -copyfd(from, to) { +copyfd(from, to) + int from; + int to; +{ int newfd; newfd = fcntl(from, F_DUPFD, to); diff --git a/bin/sh/redir.h b/bin/sh/redir.h index 81cc760..9a3ba17 100644 --- a/bin/sh/redir.h +++ b/bin/sh/redir.h @@ -33,24 +33,17 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)redir.h 8.1 (Berkeley) 5/31/93 + * @(#)redir.h 8.2 (Berkeley) 5/4/95 */ /* flags passed to redirect */ #define REDIR_PUSH 01 /* save previous values of file descriptors */ #define REDIR_BACKQ 02 /* save the command output in memory */ -#ifdef __STDC__ union node; -void redirect(union node *, int); -void popredir(void); -void clearredir(void); -int copyfd(int, int); -int fd0_redirected_p(void); -#else -void redirect(); -void popredir(); -void clearredir(); -int copyfd(); -int fd0_redirected_p(); -#endif +void redirect __P((union node *, int)); +void popredir __P((void)); +int fd0_redirected_p __P((void)); +void clearredir __P((void)); +int copyfd __P((int, int)); + diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 8bec2e7..0ec1561 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -32,7 +32,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)sh.1 8.4 (Berkeley) 4/18/94 +.\" @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" .na .TH SH 1 @@ -884,7 +884,6 @@ If parameter is * or @, the result of the expansion is unspecified. Enclosing the full parameter expansion string in double-quotes does not cause the following four varieties of pattern characters to be quoted, whereas quoting characters within the braces has this effect. -(UNIMPLEMENTED IN 4.4alpha) .TP ${parameter%word} Remove Smallest Suffix Pattern. The word @@ -1029,6 +1028,12 @@ that can't be performed by a separate process. In addition to these, there are s be builtin for efficiency (e.g. printf(1), echo(1), test(1), etc). .TP +: +A null command that returns a 0 (true) exit value. +.TP +\&. file +The commands in the specified file are read and executed by the shell. +.TP alias [ name[=string] ... ] If name=string is specified, the shell defines the alias ``name'' with value ``string''. If just ``name'' @@ -1057,9 +1062,6 @@ different from the name that the user gave. These may be different either because the CDPATH mechanism was used or because a symbolic link was crossed. .TP -\&. file -The commands in the specified file are read and executed by the shell. -.TP eval string... Concatenate all the arguments with spaces. Then re-parse and execute the command. diff --git a/bin/sh/shell.h b/bin/sh/shell.h index 87f4795..b97e392 100644 --- a/bin/sh/shell.h +++ b/bin/sh/shell.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)shell.h 8.1 (Berkeley) 5/31/93 + * @(#)shell.h 8.2 (Berkeley) 5/4/95 */ /* diff --git a/bin/sh/show.c b/bin/sh/show.c index 9807c99..4319809 100644 --- a/bin/sh/show.c +++ b/bin/sh/show.c @@ -35,37 +35,53 @@ */ #ifndef lint -static char sccsid[] = "@(#)show.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95"; #endif /* not lint */ #include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + #include "shell.h" #include "parser.h" #include "nodes.h" #include "mystring.h" +#include "show.h" #ifdef DEBUG -static shtree(), shcmd(), sharg(), indent(); +static void shtree __P((union node *, int, char *, FILE*)); +static void shcmd __P((union node *, FILE *)); +static void sharg __P((union node *, FILE *)); +static void indent __P((int, char *, FILE *)); +static void trstring __P((char *)); +void showtree(n) union node *n; - { +{ trputs("showtree called\n"); shtree(n, 1, NULL, stdout); } -static +static void shtree(n, ind, pfx, fp) union node *n; + int ind; char *pfx; FILE *fp; - { +{ struct nodelist *lp; char *s; + if (n == NULL) + return; + indent(ind, pfx, fp); switch(n->type) { case NSEMI: @@ -108,11 +124,11 @@ binop: -static +static void shcmd(cmd, fp) union node *cmd; FILE *fp; - { +{ union node *np; int first; char *s; @@ -134,6 +150,7 @@ shcmd(cmd, fp) case NTOFD: s = ">&"; dftfd = 1; break; case NFROM: s = "<"; dftfd = 0; break; case NFROMFD: s = "<&"; dftfd = 0; break; + default: s = "*error*"; dftfd = 0; break; } if (np->nfile.fd != dftfd) fprintf(fp, "%d", np->nfile.fd); @@ -149,7 +166,7 @@ shcmd(cmd, fp) -static +static void sharg(arg, fp) union node *arg; FILE *fp; @@ -173,10 +190,15 @@ sharg(arg, fp) putc('$', fp); putc('{', fp); subtype = *++p; + if (subtype == VSLENGTH) + putc('#', fp); + while (*p != '=') putc(*p++, fp); + if (subtype & VSNUL) putc(':', fp); + switch (subtype & VSTYPE) { case VSNORMAL: putc('}', fp); @@ -193,6 +215,22 @@ sharg(arg, fp) case VSASSIGN: putc('=', fp); break; + case VSTRIMLEFT: + putc('#', fp); + break; + case VSTRIMLEFTMAX: + putc('#', fp); + putc('#', fp); + break; + case VSTRIMRIGHT: + putc('%', fp); + break; + case VSTRIMRIGHTMAX: + putc('%', fp); + putc('%', fp); + break; + case VSLENGTH: + break; default: printf("<subtype %d>", subtype); } @@ -215,11 +253,12 @@ sharg(arg, fp) } -static +static void indent(amount, pfx, fp) + int amount; char *pfx; FILE *fp; - { +{ int i; for (i = 0 ; i < amount ; i++) { @@ -246,7 +285,10 @@ int debug = 0; #endif -trputc(c) { +void +trputc(c) + int c; +{ #ifdef DEBUG if (tracefile == NULL) return; @@ -256,23 +298,37 @@ trputc(c) { #endif } - -trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8) - char *fmt; - { +void +#if __STDC__ +trace(const char *fmt, ...) +#else +trace(va_alist) + va_dcl +#endif +{ #ifdef DEBUG - if (tracefile == NULL) - return; - fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8); - if (strchr(fmt, '\n')) - fflush(tracefile); + va_list va; +#if __STDC__ + va_start(va, fmt); +#else + char *fmt; + va_start(va); + fmt = va_arg(va, char *); +#endif + if (tracefile != NULL) { + (void) vfprintf(tracefile, fmt, va); + if (strchr(fmt, '\n')) + (void) fflush(tracefile); + } + va_end(va); #endif } +void trputs(s) char *s; - { +{ #ifdef DEBUG if (tracefile == NULL) return; @@ -283,9 +339,10 @@ trputs(s) } +static void trstring(s) char *s; - { +{ register char *p; char c; @@ -325,9 +382,10 @@ backslash: putc('\\', tracefile); } +void trargs(ap) char **ap; - { +{ #ifdef DEBUG if (tracefile == NULL) return; @@ -343,24 +401,29 @@ trargs(ap) } +void opentrace() { char s[100]; - char *p; char *getenv(); +#ifdef O_APPEND int flags; +#endif #ifdef DEBUG if (!debug) return; #ifdef not_this_way - if ((p = getenv("HOME")) == NULL) { - if (geteuid() == 0) - p = "/"; - else - p = "/tmp"; + { + char *p; + if ((p = getenv("HOME")) == NULL) { + if (geteuid() == 0) + p = "/"; + else + p = "/tmp"; + } + scopy(p, s); + strcat(s, "/trace"); } - scopy(p, s); - strcat(s, "/trace"); #else scopy("./trace", s); #endif /* not_this_way */ diff --git a/bin/sh/show.h b/bin/sh/show.h new file mode 100644 index 0000000..2d620d7 --- /dev/null +++ b/bin/sh/show.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)show.h 1.1 (Berkeley) 5/4/95 + */ + +void showtree __P((union node *)); +void trputc __P((int)); +void trace __P((const char *, ...)); +void trputs __P((char *)); +void trargs __P((char **)); +void opentrace __P((void)); diff --git a/bin/sh/trap.c b/bin/sh/trap.c index dde6dbc..b8704fa 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -35,23 +35,26 @@ */ #ifndef lint -static char sccsid[] = "@(#)trap.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95"; #endif /* not lint */ +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> + #include "shell.h" #include "main.h" #include "nodes.h" /* for other headers */ #include "eval.h" #include "jobs.h" +#include "show.h" #include "options.h" #include "syntax.h" -#include "signames.h" #include "output.h" #include "memalloc.h" #include "error.h" #include "trap.h" #include "mystring.h" -#include <signal.h> /* @@ -69,22 +72,28 @@ static char sccsid[] = "@(#)trap.c 8.1 (Berkeley) 5/31/93"; extern char nullstr[1]; /* null string */ -char *trap[MAXSIG+1]; /* trap handler commands */ -MKINIT char sigmode[MAXSIG]; /* current value of signal */ -char gotsig[MAXSIG]; /* indicates specified signal received */ +char *trap[NSIG+1]; /* trap handler commands */ +MKINIT char sigmode[NSIG]; /* current value of signal */ +char gotsig[NSIG]; /* indicates specified signal received */ int pendingsigs; /* indicates some signal received */ +static int getsigaction __P((int, sig_t *)); + /* * The trap builtin. */ -trapcmd(argc, argv) char **argv; { +int +trapcmd(argc, argv) + int argc; + char **argv; +{ char *action; char **ap; int signo; if (argc <= 1) { - for (signo = 0 ; signo <= MAXSIG ; signo++) { + for (signo = 0 ; signo <= NSIG ; signo++) { if (trap[signo] != NULL) out1fmt("%d: %s\n", signo, trap[signo]); } @@ -96,7 +105,7 @@ trapcmd(argc, argv) char **argv; { else action = *ap++; while (*ap) { - if ((signo = number(*ap)) < 0 || signo > MAXSIG) + if ((signo = number(*ap)) < 0 || signo > NSIG) error("%s: bad trap", *ap); INTOFF; if (action) @@ -122,7 +131,7 @@ void clear_traps() { char **tp; - for (tp = trap ; tp <= &trap[MAXSIG] ; tp++) { + for (tp = trap ; tp <= &trap[NSIG] ; tp++) { if (*tp && **tp) { /* trap not NULL or SIG_IGN */ INTOFF; ckfree(*tp); @@ -141,13 +150,14 @@ clear_traps() { * out what it should be set to. */ -int -setsignal(signo) { +long +setsignal(signo) + int signo; +{ int action; - sig_t sigact; + sig_t sigact = SIG_DFL; char *t; extern void onsig(); - extern sig_t getsigaction(); if ((t = trap[signo]) == NULL) action = S_DFL; @@ -184,12 +194,20 @@ setsignal(signo) { #endif } } + t = &sigmode[signo - 1]; if (*t == 0) { /* * current setting unknown */ - sigact = getsigaction(signo); + if (!getsigaction(signo, &sigact)) { + /* + * Pretend it worked; maybe we should give a warning + * here, but other shells don't. We don't alter + * sigmode, so that we retry every time. + */ + return 0; + } if (sigact == SIG_IGN) { if (mflag && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)) { @@ -208,20 +226,23 @@ setsignal(signo) { case S_IGN: sigact = SIG_IGN; break; } *t = action; - return (int)signal(signo, sigact); + return (long)signal(signo, sigact); } /* * Return the current setting for sig w/o changing it. */ -sig_t -getsigaction(signo) { +static int +getsigaction(signo, sigact) + int signo; + sig_t *sigact; +{ struct sigaction sa; if (sigaction(signo, (struct sigaction *)0, &sa) == -1) - error("Sigaction system call failed"); - - return sa.sa_handler; + return 0; + *sigact = (sig_t) sa.sa_handler; + return 1; } /* @@ -229,7 +250,9 @@ getsigaction(signo) { */ void -ignoresig(signo) { +ignoresig(signo) + int signo; +{ if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { signal(signo, SIG_IGN); } @@ -238,14 +261,14 @@ ignoresig(signo) { #ifdef mkinit -INCLUDE "signames.h" +INCLUDE <signal.h> INCLUDE "trap.h" SHELLPROC { char *sm; clear_traps(); - for (sm = sigmode ; sm < sigmode + MAXSIG ; sm++) { + for (sm = sigmode ; sm < sigmode + NSIG ; sm++) { if (*sm == S_IGN) *sm = S_HARD_IGN; } @@ -259,7 +282,9 @@ SHELLPROC { */ void -onsig(signo) { +onsig(signo) + int signo; +{ signal(signo, onsig); if (signo == SIGINT && trap[SIGINT] == NULL) { onint(); @@ -285,7 +310,7 @@ dotrap() { for (i = 1 ; ; i++) { if (gotsig[i - 1]) break; - if (i >= MAXSIG) + if (i >= NSIG) goto done; } gotsig[i - 1] = 0; @@ -305,7 +330,9 @@ done: void -setinteractive(on) { +setinteractive(on) + int on; +{ static int is_interactive; if (on == is_interactive) @@ -323,7 +350,9 @@ setinteractive(on) { */ void -exitshell(status) { +exitshell(status) + int status; +{ struct jmploc loc1, loc2; char *p; diff --git a/bin/sh/trap.h b/bin/sh/trap.h index d59ee60..1611fce 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -33,23 +33,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)trap.h 8.1 (Berkeley) 5/31/93 + * @(#)trap.h 8.3 (Berkeley) 6/5/95 */ extern int pendingsigs; -#ifdef __STDC__ -void clear_traps(void); -int setsignal(int); -void ignoresig(int); -void dotrap(void); -void setinteractive(int); -void exitshell(int); -#else -void clear_traps(); -int setsignal(); -void ignoresig(); -void dotrap(); -void setinteractive(); -void exitshell(); -#endif +int trapcmd __P((int, char **)); +void clear_traps __P((void)); +long setsignal __P((int)); +void ignoresig __P((int)); +void onsig __P((int)); +void dotrap __P((void)); +void setinteractive __P((int)); +void exitshell __P((int)); diff --git a/bin/sh/var.c b/bin/sh/var.c index 0629de8..ab44a2a 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -35,9 +35,12 @@ */ #ifndef lint -static char sccsid[] = "@(#)var.c 8.1 (Berkeley) 5/31/93"; +static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; #endif /* not lint */ +#include <unistd.h> +#include <stdlib.h> + /* * Shell variables. */ @@ -55,6 +58,9 @@ static char sccsid[] = "@(#)var.c 8.1 (Berkeley) 5/31/93"; #include "memalloc.h" #include "error.h" #include "mystring.h" +#ifndef NO_HISTORY +#include "myhistedit.h" +#endif #define VTABSIZE 39 @@ -70,7 +76,9 @@ struct varinit { #if ATTY struct var vatty; #endif +#ifndef NO_HISTORY struct var vhistsize; +#endif struct var vifs; struct var vmail; struct var vmpath; @@ -86,11 +94,13 @@ const struct varinit varinit[] = { #if ATTY {&vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY="}, #endif +#ifndef NO_HISTORY {&vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE="}, +#endif {&vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n"}, {&vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL="}, {&vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH="}, - {&vpath, VSTRFIXED|VTEXTFIXED, "PATH=:/bin:/usr/bin"}, + {&vpath, VSTRFIXED|VTEXTFIXED, "PATH=/bin:/usr/bin"}, /* * vps1 depends on uid */ @@ -167,7 +177,8 @@ initvar() { void setvar(name, val, flags) char *name, *val; - { + int flags; +{ char *p, *q; int len; int namelen; @@ -218,7 +229,8 @@ setvar(name, val, flags) void setvareq(s, flags) char *s; - { + int flags; +{ struct var *vp, **vpp; vpp = hashvar(s); @@ -238,8 +250,10 @@ setvareq(s, flags) vp->text = s; if (vp == &vmpath || (vp == &vmail && ! mpathset())) chkmail(1); +#ifndef NO_HISTORY if (vp == &vhistsize) sethistsize(); +#endif INTON; return; } @@ -304,7 +318,8 @@ lookupvar(name) char * bltinlookup(name, doall) char *name; - { + int doall; +{ struct strlist *sp; struct var *v; @@ -314,8 +329,8 @@ bltinlookup(name, doall) } for (v = *hashvar(name) ; v ; v = v->next) { if (varequal(v->text, name)) { - if (v->flags & VUNSET - || ! doall && (v->flags & VEXPORT) == 0) + if ((v->flags & VUNSET) + || (!doall && (v->flags & VEXPORT) == 0)) return NULL; return strchr(v->text, '=') + 1; } @@ -402,7 +417,10 @@ shprocvar() { */ int -showvarscmd(argc, argv) char **argv; { +showvarscmd(argc, argv) + int argc; + char **argv; +{ struct var **vpp; struct var *vp; @@ -422,7 +440,10 @@ showvarscmd(argc, argv) char **argv; { */ int -exportcmd(argc, argv) char **argv; { +exportcmd(argc, argv) + int argc; + char **argv; +{ struct var **vpp; struct var *vp; char *name; @@ -465,7 +486,11 @@ found:; * The "local" command. */ -localcmd(argc, argv) char **argv; { +int +localcmd(argc, argv) + int argc; + char **argv; +{ char *name; if (! in_function()) @@ -496,7 +521,7 @@ mklocal(name) lvp = ckmalloc(sizeof (struct localvar)); if (name[0] == '-' && name[1] == '\0') { lvp->text = ckmalloc(sizeof optlist); - bcopy(optlist, lvp->text, sizeof optlist); + memcpy(lvp->text, optlist, sizeof optlist); vp = NULL; } else { vpp = hashvar(name); @@ -537,7 +562,7 @@ poplocalvars() { localvars = lvp->next; vp = lvp->vp; if (vp == NULL) { /* $- saved */ - bcopy(lvp->text, optlist, sizeof optlist); + memcpy(optlist, lvp->text, sizeof optlist); ckfree(lvp->text); } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { (void)unsetvar(vp->text); @@ -552,7 +577,11 @@ poplocalvars() { } -setvarcmd(argc, argv) char **argv; { +int +setvarcmd(argc, argv) + int argc; + char **argv; +{ if (argc <= 2) return unsetcmd(argc, argv); else if (argc == 3) @@ -569,7 +598,11 @@ setvarcmd(argc, argv) char **argv; { * with the same name. */ -unsetcmd(argc, argv) char **argv; { +int +unsetcmd(argc, argv) + int argc; + char **argv; +{ char **ap; int i; int flg_func = 0; diff --git a/bin/sh/var.h b/bin/sh/var.h index 92b4d0d..94446db 100644 --- a/bin/sh/var.h +++ b/bin/sh/var.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)var.h 8.1 (Berkeley) 5/31/93 + * @(#)var.h 8.2 (Berkeley) 5/4/95 */ /* @@ -100,28 +100,19 @@ extern struct var vterm; #endif #define mpathset() ((vmpath.flags & VUNSET) == 0) - -#ifdef __STDC__ -void initvar(); -void setvar(char *, char *, int); -void setvareq(char *, int); +void initvar __P((void)); +void setvar __P((char *, char *, int)); +void setvareq __P((char *, int)); struct strlist; -void listsetvar(struct strlist *); -char *lookupvar(char *); -char *bltinlookup(char *, int); -char **environment(); -int showvarscmd(int, char **); -void mklocal(char *); -void poplocalvars(void); -#else -void initvar(); -void setvar(); -void setvareq(); -void listsetvar(); -char *lookupvar(); -char *bltinlookup(); -char **environment(); -int showvarscmd(); -void mklocal(); -void poplocalvars(); -#endif +void listsetvar __P((struct strlist *)); +char *lookupvar __P((char *)); +char *bltinlookup __P((char *, int)); +char **environment __P((void)); +void shprocvar __P((void)); +int showvarscmd __P((int, char **)); +int exportcmd __P((int, char **)); +int localcmd __P((int, char **)); +void mklocal __P((char *)); +void poplocalvars __P((void)); +int setvarcmd __P((int, char **)); +int unsetcmd __P((int, char **)); |