Remove broken and incomplete support for old releases of System V,
don't support system that implement getcwd(3) with a pipe to /bin/pwd.
This commit is contained in:
parent
5959d16036
commit
2628ebdbd1
55
bin/sh/cd.c
55
bin/sh/cd.c
@ -369,20 +369,6 @@ getpwd(void)
|
||||
|
||||
if (curdir)
|
||||
return curdir;
|
||||
/*
|
||||
* Things are a bit complicated here; we could have just used
|
||||
* getcwd, but traditionally getcwd is implemented using popen
|
||||
* to /bin/pwd. This creates a problem for us, since we cannot
|
||||
* keep track of the job if it is being ran behind our backs.
|
||||
* So we re-implement getcwd(), and we suppress interrupts
|
||||
* throughout the process. This is not completely safe, since
|
||||
* the user can still break out of it by killing the pwd program.
|
||||
* We still try to use getcwd for systems that we know have a
|
||||
* c implementation of getcwd, that does not open a pipe to
|
||||
* /bin/pwd.
|
||||
*/
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__SVR4)
|
||||
|
||||
if (getcwd(buf, sizeof(buf)) == NULL) {
|
||||
char *pwd = getenv("PWD");
|
||||
struct stat stdot, stpwd;
|
||||
@ -397,47 +383,6 @@ getpwd(void)
|
||||
return NULL;
|
||||
}
|
||||
curdir = savestr(buf);
|
||||
#else
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
int status;
|
||||
struct job *jp;
|
||||
int pip[2];
|
||||
|
||||
INTOFF;
|
||||
if (pipe(pip) < 0)
|
||||
error("Pipe call failed: %s", strerror(errno));
|
||||
jp = makejob((union node *)NULL, 1);
|
||||
if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) {
|
||||
(void) close(pip[0]);
|
||||
if (pip[1] != 1) {
|
||||
close(1);
|
||||
copyfd(pip[1], 1);
|
||||
close(pip[1]);
|
||||
}
|
||||
(void) execl("/bin/pwd", "pwd", (char *)0);
|
||||
error("Cannot exec /bin/pwd");
|
||||
}
|
||||
(void) close(pip[1]);
|
||||
pip[1] = -1;
|
||||
p = buf;
|
||||
while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0
|
||||
|| (i == -1 && errno == EINTR)) {
|
||||
if (i > 0)
|
||||
p += i;
|
||||
}
|
||||
(void) close(pip[0]);
|
||||
pip[0] = -1;
|
||||
status = waitforjob(jp);
|
||||
if (status != 0)
|
||||
error((char *)0);
|
||||
if (i < 0 || p == buf || p[-1] != '\n')
|
||||
error("pwd command failed");
|
||||
p[-1] = '\0';
|
||||
}
|
||||
curdir = savestr(buf);
|
||||
INTON;
|
||||
#endif
|
||||
return curdir;
|
||||
}
|
||||
|
@ -221,9 +221,6 @@ STATIC const struct errname errormsg[] = {
|
||||
{ ENXIO, ALL, "no such device or address" },
|
||||
{ EROFS, ALL, "read-only filesystem" },
|
||||
{ ETXTBSY, ALL, "text busy" },
|
||||
#ifdef SYSV
|
||||
{ EAGAIN, E_EXEC, "not enough memory" },
|
||||
#endif
|
||||
{ ENOMEM, ALL, "not enough memory" },
|
||||
#ifdef ENOLINK
|
||||
{ ENOLINK, ALL, "remote access failed" },
|
||||
|
@ -101,7 +101,5 @@ char *errmsg(int, int);
|
||||
* so we use _setjmp instead.
|
||||
*/
|
||||
|
||||
#ifdef BSD
|
||||
#define setjmp(jmploc) _setjmp(jmploc)
|
||||
#define longjmp(jmploc, val) _longjmp(jmploc, val)
|
||||
#endif
|
||||
|
105
bin/sh/exec.c
105
bin/sh/exec.c
@ -100,9 +100,6 @@ int exerrno = 0; /* Last exec error */
|
||||
|
||||
|
||||
STATIC void tryexec(char *, char **, char **);
|
||||
#ifndef BSD
|
||||
STATIC void execinterp(char **, char **);
|
||||
#endif
|
||||
STATIC void printentry(struct tblentry *, int);
|
||||
STATIC struct tblentry *cmdlookup(char *, int);
|
||||
STATIC void delete_cmd_entry(void);
|
||||
@ -155,30 +152,13 @@ STATIC void
|
||||
tryexec(char *cmd, char **argv, char **envp)
|
||||
{
|
||||
int e;
|
||||
#ifndef BSD
|
||||
char *p;
|
||||
#endif
|
||||
|
||||
#ifdef SYSV
|
||||
do {
|
||||
execve(cmd, argv, envp);
|
||||
} while (errno == EINTR);
|
||||
#else
|
||||
execve(cmd, argv, envp);
|
||||
#endif
|
||||
e = errno;
|
||||
if (e == ENOEXEC) {
|
||||
initshellproc();
|
||||
setinputfile(cmd, 0);
|
||||
commandname = arg0 = savestr(argv[0]);
|
||||
#ifndef BSD
|
||||
pgetc(); pungetc(); /* fill up input buffer */
|
||||
p = parsenextc;
|
||||
if (parsenleft > 2 && p[0] == '#' && p[1] == '!') {
|
||||
argv[0] = cmd;
|
||||
execinterp(argv, envp);
|
||||
}
|
||||
#endif
|
||||
setparam(argv + 1);
|
||||
exraise(EXSHELLPROC);
|
||||
/*NOTREACHED*/
|
||||
@ -186,85 +166,6 @@ tryexec(char *cmd, char **argv, char **envp)
|
||||
errno = e;
|
||||
}
|
||||
|
||||
|
||||
#ifndef BSD
|
||||
/*
|
||||
* Execute an interpreter introduced by "#!", for systems where this
|
||||
* feature has not been built into the kernel. If the interpreter is
|
||||
* the shell, return (effectively ignoring the "#!"). If the execution
|
||||
* of the interpreter fails, exit.
|
||||
*
|
||||
* This code peeks inside the input buffer in order to avoid actually
|
||||
* reading any input. It would benefit from a rewrite.
|
||||
*/
|
||||
|
||||
#define NEWARGS 5
|
||||
|
||||
STATIC void
|
||||
execinterp(char **argv, char **envp)
|
||||
{
|
||||
int n;
|
||||
char *inp;
|
||||
char *outp;
|
||||
char c;
|
||||
char *p;
|
||||
char **ap;
|
||||
char *newargs[NEWARGS];
|
||||
int i;
|
||||
char **ap2;
|
||||
char **new;
|
||||
|
||||
n = parsenleft - 2;
|
||||
inp = parsenextc + 2;
|
||||
ap = newargs;
|
||||
for (;;) {
|
||||
while (--n >= 0 && (*inp == ' ' || *inp == '\t'))
|
||||
inp++;
|
||||
if (n < 0)
|
||||
goto bad;
|
||||
if ((c = *inp++) == '\n')
|
||||
break;
|
||||
if (ap == &newargs[NEWARGS])
|
||||
bad: error("Bad #! line");
|
||||
STARTSTACKSTR(outp);
|
||||
do {
|
||||
STPUTC(c, outp);
|
||||
} while (--n >= 0 && (c = *inp++) != ' ' && c != '\t' && c != '\n');
|
||||
STPUTC('\0', outp);
|
||||
n++, inp--;
|
||||
*ap++ = grabstackstr(outp);
|
||||
}
|
||||
if (ap == newargs + 1) { /* if no args, maybe no exec is needed */
|
||||
p = newargs[0];
|
||||
for (;;) {
|
||||
if (equal(p, "sh") || equal(p, "ash")) {
|
||||
return;
|
||||
}
|
||||
while (*p != '/') {
|
||||
if (*p == '\0')
|
||||
goto break2;
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
break2:;
|
||||
}
|
||||
i = (char *)ap - (char *)newargs; /* size in bytes */
|
||||
if (i == 0)
|
||||
error("Bad #! line");
|
||||
for (ap2 = argv ; *ap2++ != NULL ; );
|
||||
new = ckmalloc(i + ((char *)ap2 - (char *)argv));
|
||||
ap = newargs, ap2 = new;
|
||||
while ((i -= sizeof (char **)) >= 0)
|
||||
*ap2++ = *ap++;
|
||||
ap = argv;
|
||||
while (*ap2++ = *ap++);
|
||||
shellexec(new, envp, pathval(), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Do a path search. The variable path (passed by reference) should be
|
||||
* set to the start of the path before the first call; padvance will update
|
||||
@ -478,11 +379,7 @@ loop:
|
||||
TRACE(("searchexec \"%s\": no change\n", name));
|
||||
goto success;
|
||||
}
|
||||
while (stat(fullname, &statb) < 0) {
|
||||
#ifdef SYSV
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
#endif
|
||||
if (stat(fullname, &statb) < 0) {
|
||||
if (errno != ENOENT && errno != ENOTDIR)
|
||||
e = errno;
|
||||
goto loop;
|
||||
|
@ -49,12 +49,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#ifdef BSD
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <paths.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "shell.h"
|
||||
@ -96,9 +94,6 @@ STATIC void restartjob(struct job *);
|
||||
STATIC void freejob(struct job *);
|
||||
STATIC struct job *getjob(char *);
|
||||
STATIC pid_t dowait(int, struct job *);
|
||||
#if SYSV
|
||||
STATIC int onsigchild(void);
|
||||
#endif
|
||||
STATIC pid_t waitproc(int, int *);
|
||||
STATIC void cmdtxt(union node *);
|
||||
STATIC void cmdputs(char *);
|
||||
@ -112,10 +107,6 @@ STATIC void showjob(struct job *, pid_t, int, int);
|
||||
|
||||
/*
|
||||
* Turn job control on and off.
|
||||
*
|
||||
* Note: This code assumes that the third arg to ioctl is a character
|
||||
* pointer, which is true on Berkeley systems but not System V. Since
|
||||
* System V doesn't have job control yet, this isn't a problem now.
|
||||
*/
|
||||
|
||||
MKINIT int jobctl;
|
||||
@ -1005,44 +996,10 @@ dowait(int block, struct job *job)
|
||||
* Do a wait system call. If job control is compiled in, we accept
|
||||
* stopped processes. If block is zero, we return a value of zero
|
||||
* rather than blocking.
|
||||
*
|
||||
* System V doesn't have a non-blocking wait system call. It does
|
||||
* have a SIGCLD signal that is sent to a process when one of it's
|
||||
* children dies. The obvious way to use SIGCLD would be to install
|
||||
* a handler for SIGCLD which simply bumped a counter when a SIGCLD
|
||||
* was received, and have waitproc bump another counter when it got
|
||||
* the status of a process. Waitproc would then know that a wait
|
||||
* system call would not block if the two counters were different.
|
||||
* This approach doesn't work because if a process has children that
|
||||
* have not been waited for, System V will send it a SIGCLD when it
|
||||
* installs a signal handler for SIGCLD. What this means is that when
|
||||
* a child exits, the shell will be sent SIGCLD signals continuously
|
||||
* until is runs out of stack space, unless it does a wait call before
|
||||
* restoring the signal handler. The code below takes advantage of
|
||||
* this (mis)feature by installing a signal handler for SIGCLD and
|
||||
* then checking to see whether it was called. If there are any
|
||||
* children to be waited for, it will be.
|
||||
*
|
||||
* If neither SYSV nor BSD is defined, we don't implement nonblocking
|
||||
* waits at all. In this case, the user will not be informed when
|
||||
* a background process until the next time she runs a real program
|
||||
* (as opposed to running a builtin command or just typing return),
|
||||
* and the jobs command may give out of date information.
|
||||
*/
|
||||
|
||||
#ifdef SYSV
|
||||
STATIC sig_atomic_t gotsigchild;
|
||||
|
||||
STATIC int onsigchild() {
|
||||
gotsigchild = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
STATIC pid_t
|
||||
waitproc(int block, int *status)
|
||||
{
|
||||
#ifdef BSD
|
||||
int flags;
|
||||
|
||||
#if JOBS
|
||||
@ -1053,24 +1010,6 @@ waitproc(int block, int *status)
|
||||
if (block == 0)
|
||||
flags |= WNOHANG;
|
||||
return wait3(status, flags, (struct rusage *)NULL);
|
||||
#else
|
||||
#ifdef SYSV
|
||||
int (*save)();
|
||||
|
||||
if (block == 0) {
|
||||
gotsigchild = 0;
|
||||
save = signal(SIGCLD, onsigchild);
|
||||
signal(SIGCLD, save);
|
||||
if (gotsigchild == 0)
|
||||
return 0;
|
||||
}
|
||||
return wait(status);
|
||||
#else
|
||||
if (block == 0)
|
||||
return 0;
|
||||
return wait(status);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -40,9 +40,6 @@
|
||||
/*
|
||||
* The follow should be set to reflect the type of system you have:
|
||||
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
|
||||
* SHORTNAMES -> 1 if your linker cannot handle long names.
|
||||
* define BSD if you are running 4.2 BSD or later.
|
||||
* define SYSV if you are running under System V.
|
||||
* define DEBUG=1 to compile in debugging (set global "debug" to turn on)
|
||||
* define DEBUG=2 to compile in and turn on debugging.
|
||||
*
|
||||
@ -52,9 +49,6 @@
|
||||
|
||||
|
||||
#define JOBS 1
|
||||
#ifndef BSD
|
||||
#define BSD 1
|
||||
#endif
|
||||
/* #define DEBUG 1 */
|
||||
|
||||
typedef void *pointer;
|
||||
|
@ -281,10 +281,8 @@ setsignal(int signo)
|
||||
}
|
||||
*t = action;
|
||||
sig = signal(signo, sigact);
|
||||
#ifdef BSD
|
||||
if (sig != SIG_ERR && action == S_CATCH)
|
||||
siginterrupt(signo, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -340,9 +338,6 @@ void
|
||||
onsig(int signo)
|
||||
{
|
||||
|
||||
#ifndef BSD
|
||||
signal(signo, onsig);
|
||||
#endif
|
||||
if (signo == SIGINT && trap[SIGINT] == NULL) {
|
||||
onint();
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user