Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/sh VFork()ing shell: From elric%netbsd.org@localhost:
details: https://anonhg.NetBSD.org/src/rev/87b4114e0621
branches: trunk
changeset: 537166:87b4114e0621
user: christos <christos%NetBSD.org@localhost>
date: Fri Sep 27 18:56:50 2002 +0000
description:
VFork()ing shell: From elric%netbsd.org@localhost:
Plus my changes:
- walking process group fix in foregrounding a job.
- reset of process group in parent shell if interrupted before the wait.
- move INTON lower in the dowait so that the job structure is
consistent.
- error check all setpgid(), tcsetpgrp() calls.
- eliminate unneeded strpgid() call.
- check that we don't belong in the process group before we try to
set it.
diffstat:
bin/sh/eval.c | 97 ++++++++++++++++++---
bin/sh/exec.c | 25 ++++-
bin/sh/exec.h | 4 +-
bin/sh/input.c | 18 +++-
bin/sh/input.h | 4 +-
bin/sh/jobs.c | 247 ++++++++++++++++++++++++++++++++++++--------------------
bin/sh/jobs.h | 4 +-
bin/sh/main.c | 6 +-
bin/sh/redir.c | 16 ++-
bin/sh/redir.h | 5 +-
bin/sh/shell.h | 11 ++-
bin/sh/trap.c | 57 +++++++-----
bin/sh/trap.h | 8 +-
bin/sh/var.c | 14 +-
bin/sh/var.h | 4 +-
15 files changed, 355 insertions(+), 165 deletions(-)
diffs (truncated from 1129 to 300 lines):
diff -r 2a74db8b973b -r 87b4114e0621 bin/sh/eval.c
--- a/bin/sh/eval.c Fri Sep 27 18:38:53 2002 +0000
+++ b/bin/sh/eval.c Fri Sep 27 18:56:50 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: eval.c,v 1.60 2002/09/27 17:37:12 mycroft Exp $ */
+/* $NetBSD: eval.c,v 1.61 2002/09/27 18:56:50 christos Exp $ */
/*-
* Copyright (c) 1993
@@ -41,13 +41,16 @@
#if 0
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
#else
-__RCSID("$NetBSD: eval.c,v 1.60 2002/09/27 17:37:12 mycroft Exp $");
+__RCSID("$NetBSD: eval.c,v 1.61 2002/09/27 18:56:50 christos Exp $");
#endif
#endif /* not lint */
#include <signal.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
/*
* Evaluate a command.
*/
@@ -587,6 +590,7 @@
}
+int vforked = 0;
/*
* Execute a simple command.
@@ -626,6 +630,7 @@
(void) &flags;
#endif
+ vforked = 0;
/* First expand the arguments. */
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
setstackmark(&smark);
@@ -728,7 +733,6 @@
&& (cmdentry.cmdtype != CMDBUILTIN
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD))) {
- INTOFF;
jp = makejob(cmd, 1);
mode = cmd->ncmd.backgnd;
if (flags & EV_BACKCMD) {
@@ -736,11 +740,73 @@
if (pipe(pip) < 0)
error("Pipe call failed");
}
- if (forkshell(jp, cmd, mode) != 0)
- goto parent; /* at end of routine */
- INTON;
+#ifdef DO_SHAREDVFORK
+ /* It is essential that if DO_SHAREDVFORK is defined that the
+ * child's address space is actually shared with the parent as
+ * we rely on this.
+ */
+ if (cmdentry.cmdtype == CMDNORMAL) {
+ pid_t pid;
+
+ INTOFF;
+ savelocalvars = localvars;
+ localvars = NULL;
+ for (sp = varlist.list ; sp ; sp = sp->next)
+ mklocal(sp->text, VEXPORT);
+ vforked = 1;
+ switch (pid = vfork()) {
+ case -1:
+ TRACE(("Vfork failed, errno=%d", errno));
+ INTON;
+ error("Cannot vfork");
+ break;
+ case 0:
+ /* Make sure that exceptions only unwind to
+ * after the vfork(2)
+ */
+ if (setjmp(jmploc.loc)) {
+ if (exception == EXSHELLPROC) {
+ /* We can't progress with the vfork,
+ * so, set vforked = 2 so the parent
+ * knows, and _exit();
+ */
+ vforked = 2;
+ _exit(0);
+ } else {
+ _exit(exerrno);
+ }
+ }
+ savehandler = handler;
+ handler = &jmploc;
+ forkchild(jp, cmd, mode, vforked);
+ break;
+ default:
+ handler = savehandler; /* restore from vfork(2) */
+ poplocalvars();
+ localvars = savelocalvars;
+ if (vforked == 2) {
+ vforked = 0;
+
+ (void)waitpid(pid, NULL, 0);
+ /* We need to progress in a normal fork fashion */
+ goto normal_fork;
+ }
+ vforked = 0;
+ forkparent(jp, cmd, mode, pid);
+ goto parent;
+ }
+ } else {
+normal_fork:
+#endif
+ if (forkshell(jp, cmd, mode) != 0)
+ goto parent; /* at end of routine */
+#ifdef DO_SHAREDVFORK
+ }
+#endif
if (flags & EV_BACKCMD) {
- FORCEINTON;
+ if (!vforked) {
+ FORCEINTON;
+ }
close(pip[0]);
if (pip[1] != 1) {
close(1);
@@ -784,7 +850,7 @@
savehandler = handler;
handler = &jmploc;
for (sp = varlist.list ; sp ; sp = sp->next)
- mklocal(sp->text);
+ mklocal(sp->text, 0);
funcnest++;
evaltree(cmdentry.u.func, flags & EV_TESTED);
funcnest--;
@@ -863,12 +929,13 @@
#ifdef DEBUG
trputs("normal command: "); trargs(argv);
#endif
- clearredir();
- redirect(cmd->ncmd.redirect, 0);
- for (sp = varlist.list ; sp ; sp = sp->next)
- setvareq(sp->text, VEXPORT|VSTACK);
+ clearredir(vforked);
+ redirect(cmd->ncmd.redirect, vforked ? REDIR_VFORK : 0);
+ if (!vforked)
+ for (sp = varlist.list ; sp ; sp = sp->next)
+ setvareq(sp->text, VEXPORT|VSTACK);
envp = environment();
- shellexec(argv, envp, pathval(), cmdentry.u.index);
+ shellexec(argv, envp, pathval(), cmdentry.u.index, vforked);
}
goto out;
@@ -880,7 +947,6 @@
close(pip[1]);
backcmd->jp = jp;
}
- INTON;
out:
if (lastarg)
@@ -892,7 +958,6 @@
}
-
/*
* Search for a command. This is called before we fork so that the
* location of the command will be available in the parent as well as
@@ -1022,7 +1087,7 @@
optschanged();
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
- shellexec(argv + 1, environment(), pathval(), 0);
+ shellexec(argv + 1, environment(), pathval(), 0, 0);
}
return 0;
}
diff -r 2a74db8b973b -r 87b4114e0621 bin/sh/exec.c
--- a/bin/sh/exec.c Fri Sep 27 18:38:53 2002 +0000
+++ b/bin/sh/exec.c Fri Sep 27 18:56:50 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.32 2001/02/04 19:52:06 christos Exp $ */
+/* $NetBSD: exec.c,v 1.33 2002/09/27 18:56:50 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -41,15 +41,17 @@
#if 0
static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95";
#else
-__RCSID("$NetBSD: exec.c,v 1.32 2001/02/04 19:52:06 christos Exp $");
+__RCSID("$NetBSD: exec.c,v 1.33 2002/09/27 18:56:50 christos Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
/*
@@ -102,7 +104,7 @@
int exerrno = 0; /* Last exec error */
-STATIC void tryexec __P((char *, char **, char **));
+STATIC void tryexec __P((char *, char **, char **, int));
STATIC void execinterp __P((char **, char **));
STATIC void printentry __P((struct tblentry *, int));
STATIC void clearcmdentry __P((int));
@@ -118,22 +120,23 @@
*/
void
-shellexec(argv, envp, path, idx)
+shellexec(argv, envp, path, idx, vforked)
char **argv, **envp;
const char *path;
int idx;
+ int vforked;
{
char *cmdname;
int e;
if (strchr(argv[0], '/') != NULL) {
- tryexec(argv[0], argv, envp);
+ tryexec(argv[0], argv, envp, vforked);
e = errno;
} else {
e = ENOENT;
while ((cmdname = padvance(&path, argv[0])) != NULL) {
if (--idx < 0 && pathopt == NULL) {
- tryexec(cmdname, argv, envp);
+ tryexec(cmdname, argv, envp, vforked);
if (errno != ENOENT && errno != ENOTDIR)
e = errno;
}
@@ -159,10 +162,11 @@
STATIC void
-tryexec(cmd, argv, envp)
+tryexec(cmd, argv, envp, vforked)
char *cmd;
char **argv;
char **envp;
+ int vforked;
{
int e;
#ifndef BSD
@@ -178,6 +182,13 @@
#endif
e = errno;
if (e == ENOEXEC) {
+ if (vforked) {
+ /* We are currently vfork(2)ed, so raise an
+ * exception, and evalcommand will try again
+ * with a normal fork(2).
+ */
+ exraise(EXSHELLPROC);
+ }
initshellproc();
setinputfile(cmd, 0);
commandname = arg0 = savestr(argv[0]);
diff -r 2a74db8b973b -r 87b4114e0621 bin/sh/exec.h
--- a/bin/sh/exec.h Fri Sep 27 18:38:53 2002 +0000
+++ b/bin/sh/exec.h Fri Sep 27 18:56:50 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.h,v 1.17 2000/05/22 10:18:47 elric Exp $ */
+/* $NetBSD: exec.h,v 1.18 2002/09/27 18:56:51 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -60,7 +60,7 @@
extern const char *pathopt; /* set by padvance */
extern int exerrno; /* last exec error */
-void shellexec __P((char **, char **, const char *, int))
+void shellexec __P((char **, char **, const char *, int, int))
__attribute__((noreturn));
char *padvance __P((const char **, const char *));
int hashcmd __P((int, char **));
diff -r 2a74db8b973b -r 87b4114e0621 bin/sh/input.c
--- a/bin/sh/input.c Fri Sep 27 18:38:53 2002 +0000
+++ b/bin/sh/input.c Fri Sep 27 18:56:50 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: input.c,v 1.35 2001/02/04 19:52:06 christos Exp $ */
+/* $NetBSD: input.c,v 1.36 2002/09/27 18:56:52 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
Home |
Main Index |
Thread Index |
Old Index