mirror of
https://github.com/sheumann/hush.git
synced 2025-02-05 21:30:50 +00:00
ash: cleanup part 6
This commit is contained in:
parent
5c67e3ed90
commit
a6704933dd
577
shell/ash.c
577
shell/ash.c
@ -3664,7 +3664,6 @@ printalias(const struct alias *ap)
|
|||||||
#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
|
#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
|
||||||
#define EV_BACKCMD 04 /* command executing within back quotes */
|
#define EV_BACKCMD 04 /* command executing within back quotes */
|
||||||
|
|
||||||
|
|
||||||
static void evalloop(union node *, int);
|
static void evalloop(union node *, int);
|
||||||
static void evalfor(union node *, int);
|
static void evalfor(union node *, int);
|
||||||
static void evalcase(union node *, int);
|
static void evalcase(union node *, int);
|
||||||
@ -3677,13 +3676,11 @@ static int evalfun(struct funcnode *, int, char **, int);
|
|||||||
static void prehash(union node *);
|
static void prehash(union node *);
|
||||||
static int bltincmd(int, char **);
|
static int bltincmd(int, char **);
|
||||||
|
|
||||||
|
|
||||||
static const struct builtincmd bltin = {
|
static const struct builtincmd bltin = {
|
||||||
"\0\0", bltincmd
|
"\0\0", bltincmd
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Evaluate a parse tree. The value is left in the global variable
|
* Evaluate a parse tree. The value is left in the global variable
|
||||||
* exitstatus.
|
* exitstatus.
|
||||||
@ -7277,13 +7274,6 @@ static struct job *curjob;
|
|||||||
/* number of presumed living untracked jobs */
|
/* number of presumed living untracked jobs */
|
||||||
static int jobless;
|
static int jobless;
|
||||||
|
|
||||||
#if JOBS
|
|
||||||
static char *commandtext(union node *);
|
|
||||||
static void cmdlist(union node *, int);
|
|
||||||
static void cmdtxt(union node *);
|
|
||||||
static void cmdputs(const char *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_curjob(struct job *jp, unsigned mode)
|
set_curjob(struct job *jp, unsigned mode)
|
||||||
{
|
{
|
||||||
@ -7887,10 +7877,8 @@ showjob(FILE *out, struct job *jp, int mode)
|
|||||||
col += sizeof("Running") - 1;
|
col += sizeof("Running") - 1;
|
||||||
} else {
|
} else {
|
||||||
int status = psend[-1].status;
|
int status = psend[-1].status;
|
||||||
#if JOBS
|
|
||||||
if (jp->state == JOBSTOPPED)
|
if (jp->state == JOBSTOPPED)
|
||||||
status = jp->stopstatus;
|
status = jp->stopstatus;
|
||||||
#endif
|
|
||||||
col += sprint_status(s + col, status, 0);
|
col += sprint_status(s + col, status, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8143,6 +8131,288 @@ makejob(union node *node, int nprocs)
|
|||||||
return jp;
|
return jp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if JOBS
|
||||||
|
/*
|
||||||
|
* Return a string identifying a command (to be printed by the
|
||||||
|
* jobs command).
|
||||||
|
*/
|
||||||
|
static char *cmdnextc;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmdputs(const char *s)
|
||||||
|
{
|
||||||
|
const char *p, *str;
|
||||||
|
char c, cc[2] = " ";
|
||||||
|
char *nextc;
|
||||||
|
int subtype = 0;
|
||||||
|
int quoted = 0;
|
||||||
|
static const char vstype[VSTYPE + 1][4] = {
|
||||||
|
"", "}", "-", "+", "?", "=",
|
||||||
|
"%", "%%", "#", "##"
|
||||||
|
};
|
||||||
|
|
||||||
|
nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
|
||||||
|
p = s;
|
||||||
|
while ((c = *p++) != 0) {
|
||||||
|
str = 0;
|
||||||
|
switch (c) {
|
||||||
|
case CTLESC:
|
||||||
|
c = *p++;
|
||||||
|
break;
|
||||||
|
case CTLVAR:
|
||||||
|
subtype = *p++;
|
||||||
|
if ((subtype & VSTYPE) == VSLENGTH)
|
||||||
|
str = "${#";
|
||||||
|
else
|
||||||
|
str = "${";
|
||||||
|
if (!(subtype & VSQUOTE) == !(quoted & 1))
|
||||||
|
goto dostr;
|
||||||
|
quoted ^= 1;
|
||||||
|
c = '"';
|
||||||
|
break;
|
||||||
|
case CTLENDVAR:
|
||||||
|
str = "\"}" + !(quoted & 1);
|
||||||
|
quoted >>= 1;
|
||||||
|
subtype = 0;
|
||||||
|
goto dostr;
|
||||||
|
case CTLBACKQ:
|
||||||
|
str = "$(...)";
|
||||||
|
goto dostr;
|
||||||
|
case CTLBACKQ+CTLQUOTE:
|
||||||
|
str = "\"$(...)\"";
|
||||||
|
goto dostr;
|
||||||
|
#if ENABLE_ASH_MATH_SUPPORT
|
||||||
|
case CTLARI:
|
||||||
|
str = "$((";
|
||||||
|
goto dostr;
|
||||||
|
case CTLENDARI:
|
||||||
|
str = "))";
|
||||||
|
goto dostr;
|
||||||
|
#endif
|
||||||
|
case CTLQUOTEMARK:
|
||||||
|
quoted ^= 1;
|
||||||
|
c = '"';
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
if (subtype == 0)
|
||||||
|
break;
|
||||||
|
if ((subtype & VSTYPE) != VSNORMAL)
|
||||||
|
quoted <<= 1;
|
||||||
|
str = vstype[subtype & VSTYPE];
|
||||||
|
if (subtype & VSNUL)
|
||||||
|
c = ':';
|
||||||
|
else
|
||||||
|
goto checkstr;
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
case '\\':
|
||||||
|
case '"':
|
||||||
|
case '$':
|
||||||
|
/* These can only happen inside quotes */
|
||||||
|
cc[0] = c;
|
||||||
|
str = cc;
|
||||||
|
c = '\\';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
USTPUTC(c, nextc);
|
||||||
|
checkstr:
|
||||||
|
if (!str)
|
||||||
|
continue;
|
||||||
|
dostr:
|
||||||
|
while ((c = *str++)) {
|
||||||
|
USTPUTC(c, nextc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quoted & 1) {
|
||||||
|
USTPUTC('"', nextc);
|
||||||
|
}
|
||||||
|
*nextc = 0;
|
||||||
|
cmdnextc = nextc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cmdtxt() and cmdlist() call each other */
|
||||||
|
static void cmdtxt(union node *n);
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmdlist(union node *np, int sep)
|
||||||
|
{
|
||||||
|
for (; np; np = np->narg.next) {
|
||||||
|
if (!sep)
|
||||||
|
cmdputs(spcstr);
|
||||||
|
cmdtxt(np);
|
||||||
|
if (sep && np->narg.next)
|
||||||
|
cmdputs(spcstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmdtxt(union node *n)
|
||||||
|
{
|
||||||
|
union node *np;
|
||||||
|
struct nodelist *lp;
|
||||||
|
const char *p;
|
||||||
|
char s[2];
|
||||||
|
|
||||||
|
if (!n)
|
||||||
|
return;
|
||||||
|
switch (n->type) {
|
||||||
|
default:
|
||||||
|
#if DEBUG
|
||||||
|
abort();
|
||||||
|
#endif
|
||||||
|
case NPIPE:
|
||||||
|
lp = n->npipe.cmdlist;
|
||||||
|
for (;;) {
|
||||||
|
cmdtxt(lp->n);
|
||||||
|
lp = lp->next;
|
||||||
|
if (!lp)
|
||||||
|
break;
|
||||||
|
cmdputs(" | ");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NSEMI:
|
||||||
|
p = "; ";
|
||||||
|
goto binop;
|
||||||
|
case NAND:
|
||||||
|
p = " && ";
|
||||||
|
goto binop;
|
||||||
|
case NOR:
|
||||||
|
p = " || ";
|
||||||
|
binop:
|
||||||
|
cmdtxt(n->nbinary.ch1);
|
||||||
|
cmdputs(p);
|
||||||
|
n = n->nbinary.ch2;
|
||||||
|
goto donode;
|
||||||
|
case NREDIR:
|
||||||
|
case NBACKGND:
|
||||||
|
n = n->nredir.n;
|
||||||
|
goto donode;
|
||||||
|
case NNOT:
|
||||||
|
cmdputs("!");
|
||||||
|
n = n->nnot.com;
|
||||||
|
donode:
|
||||||
|
cmdtxt(n);
|
||||||
|
break;
|
||||||
|
case NIF:
|
||||||
|
cmdputs("if ");
|
||||||
|
cmdtxt(n->nif.test);
|
||||||
|
cmdputs("; then ");
|
||||||
|
n = n->nif.ifpart;
|
||||||
|
if (n->nif.elsepart) {
|
||||||
|
cmdtxt(n);
|
||||||
|
cmdputs("; else ");
|
||||||
|
n = n->nif.elsepart;
|
||||||
|
}
|
||||||
|
p = "; fi";
|
||||||
|
goto dotail;
|
||||||
|
case NSUBSHELL:
|
||||||
|
cmdputs("(");
|
||||||
|
n = n->nredir.n;
|
||||||
|
p = ")";
|
||||||
|
goto dotail;
|
||||||
|
case NWHILE:
|
||||||
|
p = "while ";
|
||||||
|
goto until;
|
||||||
|
case NUNTIL:
|
||||||
|
p = "until ";
|
||||||
|
until:
|
||||||
|
cmdputs(p);
|
||||||
|
cmdtxt(n->nbinary.ch1);
|
||||||
|
n = n->nbinary.ch2;
|
||||||
|
p = "; done";
|
||||||
|
dodo:
|
||||||
|
cmdputs("; do ");
|
||||||
|
dotail:
|
||||||
|
cmdtxt(n);
|
||||||
|
goto dotail2;
|
||||||
|
case NFOR:
|
||||||
|
cmdputs("for ");
|
||||||
|
cmdputs(n->nfor.var);
|
||||||
|
cmdputs(" in ");
|
||||||
|
cmdlist(n->nfor.args, 1);
|
||||||
|
n = n->nfor.body;
|
||||||
|
p = "; done";
|
||||||
|
goto dodo;
|
||||||
|
case NDEFUN:
|
||||||
|
cmdputs(n->narg.text);
|
||||||
|
p = "() { ... }";
|
||||||
|
goto dotail2;
|
||||||
|
case NCMD:
|
||||||
|
cmdlist(n->ncmd.args, 1);
|
||||||
|
cmdlist(n->ncmd.redirect, 0);
|
||||||
|
break;
|
||||||
|
case NARG:
|
||||||
|
p = n->narg.text;
|
||||||
|
dotail2:
|
||||||
|
cmdputs(p);
|
||||||
|
break;
|
||||||
|
case NHERE:
|
||||||
|
case NXHERE:
|
||||||
|
p = "<<...";
|
||||||
|
goto dotail2;
|
||||||
|
case NCASE:
|
||||||
|
cmdputs("case ");
|
||||||
|
cmdputs(n->ncase.expr->narg.text);
|
||||||
|
cmdputs(" in ");
|
||||||
|
for (np = n->ncase.cases; np; np = np->nclist.next) {
|
||||||
|
cmdtxt(np->nclist.pattern);
|
||||||
|
cmdputs(") ");
|
||||||
|
cmdtxt(np->nclist.body);
|
||||||
|
cmdputs(";; ");
|
||||||
|
}
|
||||||
|
p = "esac";
|
||||||
|
goto dotail2;
|
||||||
|
case NTO:
|
||||||
|
p = ">";
|
||||||
|
goto redir;
|
||||||
|
case NCLOBBER:
|
||||||
|
p = ">|";
|
||||||
|
goto redir;
|
||||||
|
case NAPPEND:
|
||||||
|
p = ">>";
|
||||||
|
goto redir;
|
||||||
|
case NTOFD:
|
||||||
|
p = ">&";
|
||||||
|
goto redir;
|
||||||
|
case NFROM:
|
||||||
|
p = "<";
|
||||||
|
goto redir;
|
||||||
|
case NFROMFD:
|
||||||
|
p = "<&";
|
||||||
|
goto redir;
|
||||||
|
case NFROMTO:
|
||||||
|
p = "<>";
|
||||||
|
redir:
|
||||||
|
s[0] = n->nfile.fd + '0';
|
||||||
|
s[1] = '\0';
|
||||||
|
cmdputs(s);
|
||||||
|
cmdputs(p);
|
||||||
|
if (n->type == NTOFD || n->type == NFROMFD) {
|
||||||
|
s[0] = n->ndup.dupfd + '0';
|
||||||
|
p = s;
|
||||||
|
goto dotail2;
|
||||||
|
}
|
||||||
|
n = n->nfile.fname;
|
||||||
|
goto donode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
commandtext(union node *n)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
STARTSTACKSTR(cmdnextc);
|
||||||
|
cmdtxt(n);
|
||||||
|
name = stackblock();
|
||||||
|
TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
|
||||||
|
name, cmdnextc, cmdnextc));
|
||||||
|
return ckstrdup(name);
|
||||||
|
}
|
||||||
|
#endif /* JOBS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fork off a subshell. If we are doing job control, give the subshell its
|
* Fork off a subshell. If we are doing job control, give the subshell its
|
||||||
* own process group. Jp is a job structure that the job is to be added to.
|
* own process group. Jp is a job structure that the job is to be added to.
|
||||||
@ -8332,289 +8602,10 @@ stoppedjobs(void)
|
|||||||
job_warning = 2;
|
job_warning = 2;
|
||||||
retval++;
|
retval++;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
out:
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return a string identifying a command (to be printed by the
|
|
||||||
* jobs command).
|
|
||||||
*/
|
|
||||||
#if JOBS
|
|
||||||
static char *cmdnextc;
|
|
||||||
|
|
||||||
static char *
|
|
||||||
commandtext(union node *n)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
STARTSTACKSTR(cmdnextc);
|
|
||||||
cmdtxt(n);
|
|
||||||
name = stackblock();
|
|
||||||
TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
|
|
||||||
name, cmdnextc, cmdnextc));
|
|
||||||
return ckstrdup(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cmdtxt(union node *n)
|
|
||||||
{
|
|
||||||
union node *np;
|
|
||||||
struct nodelist *lp;
|
|
||||||
const char *p;
|
|
||||||
char s[2];
|
|
||||||
|
|
||||||
if (!n)
|
|
||||||
return;
|
|
||||||
switch (n->type) {
|
|
||||||
default:
|
|
||||||
#if DEBUG
|
|
||||||
abort();
|
|
||||||
#endif
|
|
||||||
case NPIPE:
|
|
||||||
lp = n->npipe.cmdlist;
|
|
||||||
for (;;) {
|
|
||||||
cmdtxt(lp->n);
|
|
||||||
lp = lp->next;
|
|
||||||
if (!lp)
|
|
||||||
break;
|
|
||||||
cmdputs(" | ");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NSEMI:
|
|
||||||
p = "; ";
|
|
||||||
goto binop;
|
|
||||||
case NAND:
|
|
||||||
p = " && ";
|
|
||||||
goto binop;
|
|
||||||
case NOR:
|
|
||||||
p = " || ";
|
|
||||||
binop:
|
|
||||||
cmdtxt(n->nbinary.ch1);
|
|
||||||
cmdputs(p);
|
|
||||||
n = n->nbinary.ch2;
|
|
||||||
goto donode;
|
|
||||||
case NREDIR:
|
|
||||||
case NBACKGND:
|
|
||||||
n = n->nredir.n;
|
|
||||||
goto donode;
|
|
||||||
case NNOT:
|
|
||||||
cmdputs("!");
|
|
||||||
n = n->nnot.com;
|
|
||||||
donode:
|
|
||||||
cmdtxt(n);
|
|
||||||
break;
|
|
||||||
case NIF:
|
|
||||||
cmdputs("if ");
|
|
||||||
cmdtxt(n->nif.test);
|
|
||||||
cmdputs("; then ");
|
|
||||||
n = n->nif.ifpart;
|
|
||||||
if (n->nif.elsepart) {
|
|
||||||
cmdtxt(n);
|
|
||||||
cmdputs("; else ");
|
|
||||||
n = n->nif.elsepart;
|
|
||||||
}
|
|
||||||
p = "; fi";
|
|
||||||
goto dotail;
|
|
||||||
case NSUBSHELL:
|
|
||||||
cmdputs("(");
|
|
||||||
n = n->nredir.n;
|
|
||||||
p = ")";
|
|
||||||
goto dotail;
|
|
||||||
case NWHILE:
|
|
||||||
p = "while ";
|
|
||||||
goto until;
|
|
||||||
case NUNTIL:
|
|
||||||
p = "until ";
|
|
||||||
until:
|
|
||||||
cmdputs(p);
|
|
||||||
cmdtxt(n->nbinary.ch1);
|
|
||||||
n = n->nbinary.ch2;
|
|
||||||
p = "; done";
|
|
||||||
dodo:
|
|
||||||
cmdputs("; do ");
|
|
||||||
dotail:
|
|
||||||
cmdtxt(n);
|
|
||||||
goto dotail2;
|
|
||||||
case NFOR:
|
|
||||||
cmdputs("for ");
|
|
||||||
cmdputs(n->nfor.var);
|
|
||||||
cmdputs(" in ");
|
|
||||||
cmdlist(n->nfor.args, 1);
|
|
||||||
n = n->nfor.body;
|
|
||||||
p = "; done";
|
|
||||||
goto dodo;
|
|
||||||
case NDEFUN:
|
|
||||||
cmdputs(n->narg.text);
|
|
||||||
p = "() { ... }";
|
|
||||||
goto dotail2;
|
|
||||||
case NCMD:
|
|
||||||
cmdlist(n->ncmd.args, 1);
|
|
||||||
cmdlist(n->ncmd.redirect, 0);
|
|
||||||
break;
|
|
||||||
case NARG:
|
|
||||||
p = n->narg.text;
|
|
||||||
dotail2:
|
|
||||||
cmdputs(p);
|
|
||||||
break;
|
|
||||||
case NHERE:
|
|
||||||
case NXHERE:
|
|
||||||
p = "<<...";
|
|
||||||
goto dotail2;
|
|
||||||
case NCASE:
|
|
||||||
cmdputs("case ");
|
|
||||||
cmdputs(n->ncase.expr->narg.text);
|
|
||||||
cmdputs(" in ");
|
|
||||||
for (np = n->ncase.cases; np; np = np->nclist.next) {
|
|
||||||
cmdtxt(np->nclist.pattern);
|
|
||||||
cmdputs(") ");
|
|
||||||
cmdtxt(np->nclist.body);
|
|
||||||
cmdputs(";; ");
|
|
||||||
}
|
|
||||||
p = "esac";
|
|
||||||
goto dotail2;
|
|
||||||
case NTO:
|
|
||||||
p = ">";
|
|
||||||
goto redir;
|
|
||||||
case NCLOBBER:
|
|
||||||
p = ">|";
|
|
||||||
goto redir;
|
|
||||||
case NAPPEND:
|
|
||||||
p = ">>";
|
|
||||||
goto redir;
|
|
||||||
case NTOFD:
|
|
||||||
p = ">&";
|
|
||||||
goto redir;
|
|
||||||
case NFROM:
|
|
||||||
p = "<";
|
|
||||||
goto redir;
|
|
||||||
case NFROMFD:
|
|
||||||
p = "<&";
|
|
||||||
goto redir;
|
|
||||||
case NFROMTO:
|
|
||||||
p = "<>";
|
|
||||||
redir:
|
|
||||||
s[0] = n->nfile.fd + '0';
|
|
||||||
s[1] = '\0';
|
|
||||||
cmdputs(s);
|
|
||||||
cmdputs(p);
|
|
||||||
if (n->type == NTOFD || n->type == NFROMFD) {
|
|
||||||
s[0] = n->ndup.dupfd + '0';
|
|
||||||
p = s;
|
|
||||||
goto dotail2;
|
|
||||||
}
|
|
||||||
n = n->nfile.fname;
|
|
||||||
goto donode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cmdlist(union node *np, int sep)
|
|
||||||
{
|
|
||||||
for (; np; np = np->narg.next) {
|
|
||||||
if (!sep)
|
|
||||||
cmdputs(spcstr);
|
|
||||||
cmdtxt(np);
|
|
||||||
if (sep && np->narg.next)
|
|
||||||
cmdputs(spcstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cmdputs(const char *s)
|
|
||||||
{
|
|
||||||
const char *p, *str;
|
|
||||||
char c, cc[2] = " ";
|
|
||||||
char *nextc;
|
|
||||||
int subtype = 0;
|
|
||||||
int quoted = 0;
|
|
||||||
static const char vstype[VSTYPE + 1][4] = {
|
|
||||||
"", "}", "-", "+", "?", "=",
|
|
||||||
"%", "%%", "#", "##"
|
|
||||||
};
|
|
||||||
|
|
||||||
nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
|
|
||||||
p = s;
|
|
||||||
while ((c = *p++) != 0) {
|
|
||||||
str = 0;
|
|
||||||
switch (c) {
|
|
||||||
case CTLESC:
|
|
||||||
c = *p++;
|
|
||||||
break;
|
|
||||||
case CTLVAR:
|
|
||||||
subtype = *p++;
|
|
||||||
if ((subtype & VSTYPE) == VSLENGTH)
|
|
||||||
str = "${#";
|
|
||||||
else
|
|
||||||
str = "${";
|
|
||||||
if (!(subtype & VSQUOTE) == !(quoted & 1))
|
|
||||||
goto dostr;
|
|
||||||
quoted ^= 1;
|
|
||||||
c = '"';
|
|
||||||
break;
|
|
||||||
case CTLENDVAR:
|
|
||||||
str = "\"}" + !(quoted & 1);
|
|
||||||
quoted >>= 1;
|
|
||||||
subtype = 0;
|
|
||||||
goto dostr;
|
|
||||||
case CTLBACKQ:
|
|
||||||
str = "$(...)";
|
|
||||||
goto dostr;
|
|
||||||
case CTLBACKQ+CTLQUOTE:
|
|
||||||
str = "\"$(...)\"";
|
|
||||||
goto dostr;
|
|
||||||
#if ENABLE_ASH_MATH_SUPPORT
|
|
||||||
case CTLARI:
|
|
||||||
str = "$((";
|
|
||||||
goto dostr;
|
|
||||||
case CTLENDARI:
|
|
||||||
str = "))";
|
|
||||||
goto dostr;
|
|
||||||
#endif
|
|
||||||
case CTLQUOTEMARK:
|
|
||||||
quoted ^= 1;
|
|
||||||
c = '"';
|
|
||||||
break;
|
|
||||||
case '=':
|
|
||||||
if (subtype == 0)
|
|
||||||
break;
|
|
||||||
if ((subtype & VSTYPE) != VSNORMAL)
|
|
||||||
quoted <<= 1;
|
|
||||||
str = vstype[subtype & VSTYPE];
|
|
||||||
if (subtype & VSNUL)
|
|
||||||
c = ':';
|
|
||||||
else
|
|
||||||
goto checkstr;
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
case '\\':
|
|
||||||
case '"':
|
|
||||||
case '$':
|
|
||||||
/* These can only happen inside quotes */
|
|
||||||
cc[0] = c;
|
|
||||||
str = cc;
|
|
||||||
c = '\\';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
USTPUTC(c, nextc);
|
|
||||||
checkstr:
|
|
||||||
if (!str)
|
|
||||||
continue;
|
|
||||||
dostr:
|
|
||||||
while ((c = *str++)) {
|
|
||||||
USTPUTC(c, nextc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (quoted & 1) {
|
|
||||||
USTPUTC('"', nextc);
|
|
||||||
}
|
|
||||||
*nextc = 0;
|
|
||||||
cmdnextc = nextc;
|
|
||||||
}
|
|
||||||
#endif /* JOBS */
|
|
||||||
|
|
||||||
#if ENABLE_ASH_MAIL
|
#if ENABLE_ASH_MAIL
|
||||||
/* mail.c */
|
/* mail.c */
|
||||||
@ -11348,8 +11339,6 @@ redirectsafe(union node *redir, int flags)
|
|||||||
|
|
||||||
/* trap.c */
|
/* trap.c */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The trap builtin.
|
* The trap builtin.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user