Jim "wilson@moria.cygnus.com" Wilson's patches to make C News (and other

things) work.
This commit is contained in:
sef 1993-05-02 01:28:40 +00:00
parent ff0dc1f3c7
commit c39b5ce332
5 changed files with 105 additions and 32 deletions

View File

@ -36,7 +36,7 @@
#ifndef lint
static char sccsid[] = "@(#)expand.c 5.1 (Berkeley) 3/7/91";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/expand.c,v 1.3 1993/03/23 00:28:00 cgd Exp $";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/expand.c,v 1.4 1993/05/02 01:28:40 sef Exp $";
#endif /* not lint */
/*
@ -301,7 +301,7 @@ expbackq(cmd, quoted, full)
if (in.buf)
ckfree(in.buf);
if (in.jp)
waitforjob(in.jp);
exitstatus = waitforjob(in.jp);
if (quoted == 0)
recordregion(startloc, dest - stackblock(), 0);
TRACE(("evalbackq: size=%d: \"%.*s\"\n",
@ -500,7 +500,9 @@ numvar:
case '*':
sep = ' ';
allargs:
syntax = quoted? DQSYNTAX : BASESYNTAX;
/* Only emit CTLESC if we will do further processing,
i.e. if allow_split is set. */
syntax = quoted && allow_split ? DQSYNTAX : BASESYNTAX;
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
/* should insert CTLESC characters */
while (*p) {
@ -515,7 +517,9 @@ allargs:
case '0':
p = arg0;
string:
syntax = quoted? DQSYNTAX : BASESYNTAX;
/* Only emit CTLESC if we will do further processing,
i.e. if allow_split is set. */
syntax = quoted && allow_split ? DQSYNTAX : BASESYNTAX;
while (*p) {
if (syntax[*p] == CCTL)
STPUTC(CTLESC, expdest);
@ -1096,7 +1100,9 @@ casematch(pattern, val)
argbackq = pattern->narg.backquote;
STARTSTACKSTR(expdest);
ifslastp = NULL;
argstr(pattern->narg.text, 0);
/* Preserve any CTLESC characters inserted previously, so that
we won't expand reg exps which are inside strings. */
argstr(pattern->narg.text, 1);
STPUTC('\0', expdest);
p = grabstackstr(expdest);
result = patmatch(p, val);

View File

@ -36,7 +36,7 @@
#ifndef lint
static char sccsid[] = "@(#)jobs.c 5.1 (Berkeley) 3/7/91";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/jobs.c,v 1.4 1993/04/26 06:09:17 dpassage Exp $";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/jobs.c,v 1.5 1993/05/02 01:28:41 sef Exp $";
#endif /* not lint */
#include "shell.h"
@ -57,6 +57,7 @@ static char rcsid[] = "$Header: /cvsroot/src/bin/sh/jobs.c,v 1.4 1993/04/26 06:0
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "redir.h"
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
@ -551,7 +552,8 @@ forkshell(jp, n, mode)
} else if (mode == FORK_BG) {
ignoresig(SIGINT);
ignoresig(SIGQUIT);
if (jp == NULL || jp->nprocs == 0) {
if ((jp == NULL || jp->nprocs == 0)
&& ! fd0_redirected_p ()) {
close(0);
if (open("/dev/null", O_RDONLY) != 0)
error("Can't open /dev/null");
@ -561,7 +563,8 @@ forkshell(jp, n, mode)
if (mode == FORK_BG) {
ignoresig(SIGINT);
ignoresig(SIGQUIT);
if (jp == NULL || jp->nprocs == 0) {
if ((jp == NULL || jp->nprocs == 0)
&& ! fd0_redirected_p ()) {
close(0);
if (open("/dev/null", O_RDONLY) != 0)
error("Can't open /dev/null");

View File

@ -36,7 +36,7 @@
#ifndef lint
static char sccsid[] = "@(#)parser.c 5.3 (Berkeley) 4/12/91";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/parser.c,v 1.4 1993/04/26 22:07:46 dpassage Exp $";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/parser.c,v 1.5 1993/05/02 01:28:43 sef Exp $";
#endif /* not lint */
#include "shell.h"
@ -100,7 +100,7 @@ STATIC union node *list __P((int));
STATIC union node *andor __P((void));
STATIC union node *pipeline __P((void));
STATIC union node *command __P((void));
STATIC union node *simplecmd __P((void));
STATIC union node *simplecmd __P((union node **, union node *));
STATIC void parsefname __P((void));
STATIC void parseheredoc __P((void));
STATIC int readtoken __P((void));
@ -265,6 +265,16 @@ command() {
int t;
checkkwd = 2;
redir = 0;
rpp = &redir;
/* Check for redirection which may precede command */
while (readtoken() == TREDIR) {
*rpp = n2 = redirnode;
rpp = &n2->nfile.next;
parsefname();
}
tokpushback++;
switch (readtoken()) {
case TIF:
n1 = (union node *)stalloc(sizeof (struct nif));
@ -327,6 +337,10 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
}
*app = NULL;
n1->nfor.args = ap;
/* A newline or semicolon is required here to end
the list. */
if (lasttoken != TNL && lasttoken != TSEMI)
synexpect(-1);
} else {
#ifndef GDB_HACK
static const char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
@ -338,9 +352,11 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
n2->narg.backquote = NULL;
n2->narg.next = NULL;
n1->nfor.args = n2;
/* A newline or semicolon is optional here. Anything
else gets pushed back so we can read it again. */
if (lasttoken != TNL && lasttoken != TSEMI)
tokpushback++;
}
if (lasttoken != TNL && lasttoken != TSEMI)
synexpect(-1);
checkkwd = 2;
if ((t = readtoken()) == TDO)
t = TDONE;
@ -412,16 +428,16 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
synexpect(TEND);
checkkwd = 1;
break;
/* Handle an empty command like other simple commands. */
case TNL:
case TWORD:
case TREDIR:
tokpushback++;
return simplecmd();
return simplecmd(rpp, redir);
default:
synexpect(-1);
}
/* Now check for redirection which may follow command */
rpp = &redir;
while (readtoken() == TREDIR) {
*rpp = n2 = redirnode;
rpp = &n2->nfile.next;
@ -443,14 +459,24 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
STATIC union node *
simplecmd() {
simplecmd(rpp, redir)
union node **rpp, *redir;
{
union node *args, **app;
union node *redir, **rpp;
union node **orig_rpp = rpp;
union node *n;
/* If we don't have any redirections already, then we must reset
rpp to be the address of the local redir variable. */
if (redir == 0)
rpp = &redir;
args = NULL;
app = &args;
rpp = &redir;
/* We save the incoming value, because we need this for shell
functions. There can not be a redirect or an argument between
the function name and the open parenthesis. */
orig_rpp = rpp;
for (;;) {
if (readtoken() == TWORD) {
n = (union node *)stalloc(sizeof (struct narg));
@ -464,7 +490,7 @@ simplecmd() {
rpp = &n->nfile.next;
parsefname(); /* read name of redirection file */
} else if (lasttoken == TLP && app == &args->narg.next
&& rpp == &redir) {
&& rpp == orig_rpp) {
/* We have a function */
if (readtoken() != TRP)
synexpect(TRP);
@ -837,12 +863,6 @@ readtoken1(firstc, syntax, eofmark, striptabs)
}
break;
case CBQUOTE: /* '`' */
if (parsebackquote && syntax == BASESYNTAX) {
if (out == stackblock())
return lasttoken = TENDBQUOTE;
else
goto endword; /* exit outer loop */
}
PARSEBACKQOLD();
break;
case CEOF:
@ -856,7 +876,7 @@ readtoken1(firstc, syntax, eofmark, striptabs)
}
}
endword:
if (syntax != BASESYNTAX && eofmark == NULL)
if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
synerror("Unterminated quoted string");
if (varnest != 0) {
startlinno = plinno;
@ -1049,7 +1069,6 @@ parsebackq: {
struct jmploc jmploc;
struct jmploc *volatile savehandler;
int savelen;
int t;
savepbq = parsebackquote;
if (setjmp(jmploc.loc)) {
@ -1069,6 +1088,33 @@ parsebackq: {
savehandler = handler;
handler = &jmploc;
INTON;
if (oldstyle) {
/* We must read until the closing backquote, giving special
treatment to some slashes, and then push the string and
reread it as input, interpreting it normally. */
register char *out;
register c;
int savelen;
char *str;
STARTSTACKSTR(out);
while ((c = pgetc ()) != '`') {
if (c == '\\') {
c = pgetc ();
if (c != '\\' && c != '`' && c != '$'
&& (!dblquote || c != '"'))
STPUTC('\\', out);
}
STPUTC(c, out);
}
STPUTC('\0', out);
savelen = out - stackblock();
if (savelen > 0) {
str = ckmalloc(savelen);
bcopy(stackblock(), str, savelen);
}
setinputstring(str, 1);
}
nlpp = &bqlist;
while (*nlpp)
nlpp = &(*nlpp)->next;
@ -1076,10 +1122,12 @@ parsebackq: {
(*nlpp)->next = NULL;
parsebackquote = oldstyle;
n = list(0);
t = oldstyle? TENDBQUOTE : TRP;
if (readtoken() != t)
synexpect(t);
if (!oldstyle && (readtoken() != TRP))
synexpect(TRP);
(*nlpp)->n = n;
/* Start reading from old file again. */
if (oldstyle)
popfile();
while (stackblocksize() <= savelen)
growstackblock();
STARTSTACKSTR(out);

View File

@ -36,7 +36,7 @@
#ifndef lint
static char sccsid[] = "@(#)redir.c 5.1 (Berkeley) 3/7/91";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/redir.c,v 1.3 1993/03/23 00:29:14 cgd Exp $";
static char rcsid[] = "$Header: /cvsroot/src/bin/sh/redir.c,v 1.4 1993/05/02 01:28:44 sef Exp $";
#endif /* not lint */
/*
@ -69,6 +69,10 @@ struct redirtab {
MKINIT struct redirtab *redirlist;
/* We keep track of whether or not fd0 has been redirected. This is for
background commands, where we want to redirect fd0 to /dev/null only
if it hasn't already been redirected. */
int fd0_redirected = 0;
#ifdef __STDC__
STATIC void openredirect(union node *, char *);
@ -123,6 +127,8 @@ redirect(redir, flags)
} else {
close(fd);
}
if (fd == 0)
fd0_redirected++;
openredirect(n, memory);
}
if (memory[1])
@ -256,6 +262,8 @@ popredir() {
for (i = 0 ; i < 10 ; i++) {
if (rp->renamed[i] != EMPTY) {
if (i == 0)
fd0_redirected--;
close(i);
if (rp->renamed[i] >= 0) {
copyfd(rp->renamed[i], i);
@ -349,3 +357,9 @@ copyfd(from, to) {
return newfd;
#endif
}
/* Return true if fd 0 has already been redirected at least once. */
int
fd0_redirected_p () {
return fd0_redirected != 0;
}

View File

@ -35,7 +35,7 @@
*
* @(#)redir.h 5.1 (Berkeley) 3/7/91
*
* $Header: /cvsroot/src/bin/sh/redir.h,v 1.3 1993/03/23 00:29:16 cgd Exp $
* $Header: /cvsroot/src/bin/sh/redir.h,v 1.4 1993/05/02 01:28:45 sef Exp $
*/
/* flags passed to redirect */
@ -48,9 +48,11 @@ void redirect(union node *, int);
void popredir(void);
void clearredir(void);
int copyfd(int, int);
int fd0_redirected_p(void);
#else
void redirect();
void popredir();
void clearredir();
int copyfd();
int fd0_redirected_p();
#endif