Date: Fri, 4 Feb 2011 22:47:56 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r218306 - head/bin/sh Message-ID: <201102042247.p14Mlum2006603@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jilles Date: Fri Feb 4 22:47:55 2011 New Revision: 218306 URL: http://svn.freebsd.org/changeset/base/218306 Log: sh: Remove special code for shell scripts without magic number. These are called "shell procedures" in the source. If execve() failed with [ENOEXEC], the shell would reinitialize itself and execute the program as a script. This requires a fair amount of code which is not frequently used (most scripts have a #! magic number). Therefore just execute a new instance of sh (_PATH_BSHELL) to run the script. Modified: head/bin/sh/TOUR head/bin/sh/alias.c head/bin/sh/alias.h head/bin/sh/error.h head/bin/sh/eval.c head/bin/sh/exec.c head/bin/sh/exec.h head/bin/sh/init.h head/bin/sh/input.c head/bin/sh/jobs.c head/bin/sh/main.c head/bin/sh/mkinit.c head/bin/sh/options.c head/bin/sh/redir.c head/bin/sh/sh.1 head/bin/sh/trap.c head/bin/sh/var.c Modified: head/bin/sh/TOUR ============================================================================== --- head/bin/sh/TOUR Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/TOUR Fri Feb 4 22:47:55 2011 (r218306) @@ -44,10 +44,6 @@ C source files for entries looking like: back to the main command loop */ } - SHELLPROC { - x = 3; /* executed when the shell runs a shell procedure */ - } - It pulls this code out into routines which are when particular events occur. The intent is to improve modularity by isolating the information about which modules need to be explicitly @@ -80,12 +76,7 @@ EXCEPTIONS: Code for dealing with excep exceptions.c. The C language doesn't include exception handling, so I implement it using setjmp and longjmp. The global variable exception contains the type of exception. EXERROR is raised by -calling error. EXINT is an interrupt. EXSHELLPROC is an excep- -tion which is raised when a shell procedure is invoked. The pur- -pose of EXSHELLPROC is to perform the cleanup actions associated -with other exceptions. After these cleanup actions, the shell -can interpret a shell procedure itself without exec'ing a new -copy of the shell. +calling error. EXINT is an interrupt. INTERRUPTS: In an interactive shell, an interrupt will cause an EXINT exception to return to the main command loop. (Exception: @@ -270,14 +261,6 @@ When a program is run, the code in eval. variables which precede the command (as in "PATH=xxx command") in the variable table as the simplest way to strip duplicates, and then calls "environment" to get the value of the environment. -There are two consequences of this. First, if an assignment to -PATH precedes the command, the value of PATH before the assign- -ment must be remembered and passed to shellexec. Second, if the -program turns out to be a shell procedure, the strings from the -environment variables which preceded the command must be pulled -out of the table and replaced with strings obtained from malloc, -since the former will automatically be freed when the stack (see -the entry on memalloc.c) is emptied. BUILTIN COMMANDS: The procedures for handling these are scat- tered throughout the code, depending on which location appears Modified: head/bin/sh/alias.c ============================================================================== --- head/bin/sh/alias.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/alias.c Fri Feb 4 22:47:55 2011 (r218306) @@ -145,15 +145,7 @@ unalias(const char *name) return (1); } -#ifdef mkinit -MKINIT void rmaliases(void); - -SHELLPROC { - rmaliases(); -} -#endif - -void +static void rmaliases(void) { struct alias *ap, *tmp; Modified: head/bin/sh/alias.h ============================================================================== --- head/bin/sh/alias.h Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/alias.h Fri Feb 4 22:47:55 2011 (r218306) @@ -45,4 +45,3 @@ struct alias { struct alias *lookupalias(const char *, int); int aliascmd(int, char **); int unaliascmd(int, char **); -void rmaliases(void); Modified: head/bin/sh/error.h ============================================================================== --- head/bin/sh/error.h Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/error.h Fri Feb 4 22:47:55 2011 (r218306) @@ -56,8 +56,7 @@ extern volatile sig_atomic_t exception; /* exceptions */ #define EXINT 0 /* SIGINT received */ #define EXERROR 1 /* a generic error */ -#define EXSHELLPROC 2 /* execute a shell procedure */ -#define EXEXEC 3 /* command execution failed */ +#define EXEXEC 2 /* command execution failed */ /* Modified: head/bin/sh/eval.c ============================================================================== --- head/bin/sh/eval.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/eval.c Fri Feb 4 22:47:55 2011 (r218306) @@ -111,10 +111,6 @@ RESET { loopnest = 0; funcnest = 0; } - -SHELLPROC { - exitstatus = 0; -} #endif @@ -732,7 +728,9 @@ evalcommand(union node *cmd, int flags, argc = 0; for (sp = arglist.list ; sp ; sp = sp->next) argc++; - argv = stalloc(sizeof (char *) * (argc + 1)); + /* Add one slot at the beginning for tryexec(). */ + argv = stalloc(sizeof (char *) * (argc + 2)); + argv++; for (sp = arglist.list ; sp ; sp = sp->next) { TRACE(("evalcommand arg: %s\n", sp->text)); @@ -927,14 +925,10 @@ evalcommand(union node *cmd, int flags, reffunc(cmdentry.u.func); savehandler = handler; if (setjmp(jmploc.loc)) { - if (exception == EXSHELLPROC) - freeparam(&saveparam); - else { - freeparam(&shellparam); - shellparam = saveparam; - if (exception == EXERROR || exception == EXEXEC) - popredir(); - } + freeparam(&shellparam); + shellparam = saveparam; + if (exception == EXERROR || exception == EXEXEC) + popredir(); unreffunc(cmdentry.u.func); poplocalvars(); localvars = savelocalvars; @@ -1016,11 +1010,9 @@ cmddone: out2 = &errout; freestdout(); handler = savehandler; - if (e != EXSHELLPROC) { - commandname = savecmdname; - if (jp) - exitshell(exitstatus); - } + commandname = savecmdname; + if (jp) + exitshell(exitstatus); if (flags == EV_BACKCMD) { backcmd->buf = memout.buf; backcmd->nleft = memout.nextc - memout.buf; Modified: head/bin/sh/exec.c ============================================================================== --- head/bin/sh/exec.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/exec.c Fri Feb 4 22:47:55 2011 (r218306) @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include <fcntl.h> #include <errno.h> +#include <paths.h> #include <stdlib.h> /* @@ -105,6 +106,8 @@ static void delete_cmd_entry(void); /* * Exec a program. Never returns. If you change this routine, you may * have to change the find_command routine as well. + * + * The argv array may be changed and element argv[-1] should be writable. */ void @@ -147,12 +150,9 @@ tryexec(char *cmd, char **argv, char **e execve(cmd, argv, envp); e = errno; if (e == ENOEXEC) { - initshellproc(); - setinputfile(cmd, 0); - commandname = arg0 = savestr(argv[0]); - setparam(argv + 1); - exraise(EXSHELLPROC); - /*NOTREACHED*/ + *argv = cmd; + *--argv = _PATH_BSHELL; + execve(_PATH_BSHELL, argv, envp); } errno = e; } @@ -537,43 +537,6 @@ clearcmdentry(int firstchange) /* - * Delete all functions. - */ - -#ifdef mkinit -MKINIT void deletefuncs(void); - -SHELLPROC { - deletefuncs(); -} -#endif - -void -deletefuncs(void) -{ - struct tblentry **tblp; - struct tblentry **pp; - struct tblentry *cmdp; - - INTOFF; - for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { - pp = tblp; - while ((cmdp = *pp) != NULL) { - if (cmdp->cmdtype == CMDFUNCTION) { - *pp = cmdp->next; - unreffunc(cmdp->param.func); - ckfree(cmdp); - } else { - pp = &cmdp->next; - } - } - } - INTON; -} - - - -/* * Locate a command in the command hash table. If "add" is nonzero, * add the command to the table if it is not already present. The * variable "lastcmdentry" is set to point to the address of the link Modified: head/bin/sh/exec.h ============================================================================== --- head/bin/sh/exec.h Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/exec.h Fri Feb 4 22:47:55 2011 (r218306) @@ -71,7 +71,6 @@ void find_command(const char *, struct c int find_builtin(const char *, int *); void hashcd(void); void changepath(const char *); -void deletefuncs(void); void addcmdentry(const char *, struct cmdentry *); void defun(const char *, union node *); int unsetfunc(const char *); Modified: head/bin/sh/init.h ============================================================================== --- head/bin/sh/init.h Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/init.h Fri Feb 4 22:47:55 2011 (r218306) @@ -35,4 +35,3 @@ void init(void); void reset(void); -void initshellproc(void); Modified: head/bin/sh/input.c ============================================================================== --- head/bin/sh/input.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/input.c Fri Feb 4 22:47:55 2011 (r218306) @@ -119,12 +119,7 @@ INIT { RESET { popallfiles(); - if (exception != EXSHELLPROC) - parselleft = parsenleft = 0; /* clear input buffer */ -} - -SHELLPROC { - popallfiles(); + parselleft = parsenleft = 0; /* clear input buffer */ } #endif Modified: head/bin/sh/jobs.c ============================================================================== --- head/bin/sh/jobs.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/jobs.c Fri Feb 4 22:47:55 2011 (r218306) @@ -177,22 +177,6 @@ out: out2fmt_flush("sh: can't access #endif -#ifdef mkinit -INCLUDE <sys/types.h> -INCLUDE <stdlib.h> - -SHELLPROC { - backgndpid = -1; - bgjob = NULL; -#if JOBS - jobctl = 0; -#endif -} - -#endif - - - #if JOBS int fgcmd(int argc __unused, char **argv) Modified: head/bin/sh/main.c ============================================================================== --- head/bin/sh/main.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/main.c Fri Feb 4 22:47:55 2011 (r218306) @@ -98,19 +98,7 @@ main(int argc, char *argv[]) (void) setlocale(LC_ALL, ""); state = 0; if (setjmp(main_handler.loc)) { - /* - * When a shell procedure is executed, we raise the - * exception EXSHELLPROC to clean up before executing - * the shell procedure. - */ switch (exception) { - case EXSHELLPROC: - rootpid = getpid(); - rootshell = 1; - minusc = NULL; - state = 3; - break; - case EXEXEC: exitstatus = exerrno; break; @@ -123,10 +111,8 @@ main(int argc, char *argv[]) break; } - if (exception != EXSHELLPROC) { - if (state == 0 || iflag == 0 || ! rootshell) - exitshell(exitstatus); - } + if (state == 0 || iflag == 0 || ! rootshell) + exitshell(exitstatus); reset(); if (exception == EXINT) out2fmt_flush("\n"); Modified: head/bin/sh/mkinit.c ============================================================================== --- head/bin/sh/mkinit.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/mkinit.c Fri Feb 4 22:47:55 2011 (r218306) @@ -126,16 +126,10 @@ char reset[] = "\ * interactive shell and control is returned to the main command loop.\n\ */\n"; -char shellproc[] = "\ -/*\n\ - * This routine is called to initialize the shell to run a shell procedure.\n\ - */\n"; - struct event event[] = { { "INIT", "init", init, { NULL, 0, NULL, NULL } }, { "RESET", "reset", reset, { NULL, 0, NULL, NULL } }, - { "SHELLPROC", "initshellproc", shellproc, { NULL, 0, NULL, NULL } }, { NULL, NULL, NULL, { NULL, 0, NULL, NULL } } }; Modified: head/bin/sh/options.c ============================================================================== --- head/bin/sh/options.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/options.c Fri Feb 4 22:47:55 2011 (r218306) @@ -304,21 +304,6 @@ setoption(int flag, int val) } - -#ifdef mkinit -INCLUDE "options.h" - -SHELLPROC { - int i; - - for (i = 0; i < NOPTS; i++) - optlist[i].val = 0; - optschanged(); - -} -#endif - - /* * Set the shell parameters. */ Modified: head/bin/sh/redir.c ============================================================================== --- head/bin/sh/redir.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/redir.c Fri Feb 4 22:47:55 2011 (r218306) @@ -324,10 +324,6 @@ RESET { popredir(); } -SHELLPROC { - clearredir(); -} - #endif /* Return true if fd 0 has already been redirected at least once. */ Modified: head/bin/sh/sh.1 ============================================================================== --- head/bin/sh/sh.1 Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/sh.1 Fri Feb 4 22:47:55 2011 (r218306) @@ -32,7 +32,7 @@ .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" $FreeBSD$ .\" -.Dd January 16, 2011 +.Dd February 4, 2011 .Dt SH 1 .Os .Sh NAME @@ -647,15 +647,9 @@ resulting in an .Er ENOEXEC return value from .Xr execve 2 ) -the shell will interpret the program in a subshell. -The child shell will reinitialize itself in this case, -so that the effect will be -as if a new shell had been invoked to handle the ad-hoc shell script, -except that the location of hashed commands located in -the parent shell will be remembered by the child -(see the description of the -.Ic hash -built-in command below). +the shell will run a new instance of +.Nm +to interpret it. .Pp Note that previous versions of this document and the source code itself misleadingly and sporadically Modified: head/bin/sh/trap.c ============================================================================== --- head/bin/sh/trap.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/trap.c Fri Feb 4 22:47:55 2011 (r218306) @@ -367,22 +367,6 @@ ignoresig(int signo) } -#ifdef mkinit -INCLUDE <signal.h> -INCLUDE "trap.h" - -SHELLPROC { - char *sm; - - clear_traps(); - for (sm = sigmode ; sm < sigmode + NSIG ; sm++) { - if (*sm == S_IGN) - *sm = S_HARD_IGN; - } -} -#endif - - /* * Signal handler. */ Modified: head/bin/sh/var.c ============================================================================== --- head/bin/sh/var.c Fri Feb 4 21:54:06 2011 (r218305) +++ head/bin/sh/var.c Fri Feb 4 22:47:55 2011 (r218306) @@ -161,7 +161,7 @@ INIT { /* * This routine initializes the builtin variables. It is called when the - * shell is initialized and again when a shell procedure is spawned. + * shell is initialized. */ void @@ -542,47 +542,6 @@ environment(void) } -/* - * Called when a shell procedure is invoked to clear out nonexported - * variables. It is also necessary to reallocate variables of with - * VSTACK set since these are currently allocated on the stack. - */ - -MKINIT void shprocvar(void); - -#ifdef mkinit -SHELLPROC { - shprocvar(); -} -#endif - -void -shprocvar(void) -{ - struct var **vpp; - struct var *vp, **prev; - - for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { - for (prev = vpp ; (vp = *prev) != NULL ; ) { - if ((vp->flags & VEXPORT) == 0) { - *prev = vp->next; - if ((vp->flags & VTEXTFIXED) == 0) - ckfree(vp->text); - if ((vp->flags & VSTRFIXED) == 0) - ckfree(vp); - } else { - if (vp->flags & VSTACK) { - vp->text = savestr(vp->text); - vp->flags &=~ VSTACK; - } - prev = &vp->next; - } - } - } - initvar(); -} - - static int var_compare(const void *a, const void *b) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102042247.p14Mlum2006603>