summaryrefslogtreecommitdiffstats
path: root/bin/sh
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2011-02-04 22:47:55 +0000
committerjilles <jilles@FreeBSD.org>2011-02-04 22:47:55 +0000
commit95ad413d4a493285a5560182fb10217819d7c357 (patch)
tree88fab75180accb5d4fe09924cbd01e047b9e4903 /bin/sh
parent88f7b7c78b4285a838792e26cf3806ab40f879d2 (diff)
downloadFreeBSD-src-95ad413d4a493285a5560182fb10217819d7c357.zip
FreeBSD-src-95ad413d4a493285a5560182fb10217819d7c357.tar.gz
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.
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/TOUR19
-rw-r--r--bin/sh/alias.c10
-rw-r--r--bin/sh/alias.h1
-rw-r--r--bin/sh/error.h3
-rw-r--r--bin/sh/eval.c28
-rw-r--r--bin/sh/exec.c49
-rw-r--r--bin/sh/exec.h1
-rw-r--r--bin/sh/init.h1
-rw-r--r--bin/sh/input.c7
-rw-r--r--bin/sh/jobs.c16
-rw-r--r--bin/sh/main.c18
-rw-r--r--bin/sh/mkinit.c6
-rw-r--r--bin/sh/options.c15
-rw-r--r--bin/sh/redir.c4
-rw-r--r--bin/sh/sh.114
-rw-r--r--bin/sh/trap.c16
-rw-r--r--bin/sh/var.c43
17 files changed, 27 insertions, 224 deletions
diff --git a/bin/sh/TOUR b/bin/sh/TOUR
index af2773a..8448966 100644
--- a/bin/sh/TOUR
+++ b/bin/sh/TOUR
@@ -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 exceptions appears in
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.c sticks any environment
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
diff --git a/bin/sh/alias.c b/bin/sh/alias.c
index 0b7e31a..4662519 100644
--- a/bin/sh/alias.c
+++ b/bin/sh/alias.c
@@ -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;
diff --git a/bin/sh/alias.h b/bin/sh/alias.h
index d8f0308..7983663 100644
--- a/bin/sh/alias.h
+++ b/bin/sh/alias.h
@@ -45,4 +45,3 @@ struct alias {
struct alias *lookupalias(const char *, int);
int aliascmd(int, char **);
int unaliascmd(int, char **);
-void rmaliases(void);
diff --git a/bin/sh/error.h b/bin/sh/error.h
index bf11c67..a1d2b4f 100644
--- a/bin/sh/error.h
+++ b/bin/sh/error.h
@@ -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 */
/*
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 0bb5322..2d3f631 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -111,10 +111,6 @@ RESET {
loopnest = 0;
funcnest = 0;
}
-
-SHELLPROC {
- exitstatus = 0;
-}
#endif
@@ -732,7 +728,9 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
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, struct backcmd *backcmd)
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;
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index 2d781ab..07fa8bb 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -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 **envp)
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
diff --git a/bin/sh/exec.h b/bin/sh/exec.h
index 45330a1..45a647e 100644
--- a/bin/sh/exec.h
+++ b/bin/sh/exec.h
@@ -71,7 +71,6 @@ void find_command(const char *, struct cmdentry *, int, const char *);
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 *);
diff --git a/bin/sh/init.h b/bin/sh/init.h
index 1ec8343..dd0c4a8 100644
--- a/bin/sh/init.h
+++ b/bin/sh/init.h
@@ -35,4 +35,3 @@
void init(void);
void reset(void);
-void initshellproc(void);
diff --git a/bin/sh/input.c b/bin/sh/input.c
index 21a9134..e7baed3 100644
--- a/bin/sh/input.c
+++ b/bin/sh/input.c
@@ -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
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index 7ffdc2a..f4f1dac 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -177,22 +177,6 @@ out: out2fmt_flush("sh: can't access tty; job control turned off\n");
#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)
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 88483b0..c5de899 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -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");
diff --git a/bin/sh/mkinit.c b/bin/sh/mkinit.c
index 89385ff..82f2a55 100644
--- a/bin/sh/mkinit.c
+++ b/bin/sh/mkinit.c
@@ -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 } }
};
diff --git a/bin/sh/options.c b/bin/sh/options.c
index 389e555..de1f3ff 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -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.
*/
diff --git a/bin/sh/redir.c b/bin/sh/redir.c
index 6e6f7a5..915b2fc 100644
--- a/bin/sh/redir.c
+++ b/bin/sh/redir.c
@@ -324,10 +324,6 @@ RESET {
popredir();
}
-SHELLPROC {
- clearredir();
-}
-
#endif
/* Return true if fd 0 has already been redirected at least once. */
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 32b76c8..2ecdcf0 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -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
diff --git a/bin/sh/trap.c b/bin/sh/trap.c
index 3ddd5a9..aaa4753 100644
--- a/bin/sh/trap.c
+++ b/bin/sh/trap.c
@@ -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.
*/
diff --git a/bin/sh/var.c b/bin/sh/var.c
index 44d2028..e14027f 100644
--- a/bin/sh/var.c
+++ b/bin/sh/var.c
@@ -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)
{
OpenPOWER on IntegriCloud