Jim "wilson@moria.cygnus.com" Wilson's patches to make C News (and other
things) work.
This commit is contained in:
parent
ff0dc1f3c7
commit
c39b5ce332
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue