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)
 {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to