svn commit: r218306 - head/bin/sh

Jilles Tjoelker jilles at FreeBSD.org
Fri Feb 4 22:47:56 UTC 2011


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)
 {


More information about the svn-src-all mailing list