diff --git a/sh.func.c b/sh.func.c index a9c0dd6f..5a996871 100644 --- a/sh.func.c +++ b/sh.func.c @@ -1353,8 +1353,21 @@ dosetenv(Char **v, struct command *c) if (*lp != '\0') stderror(ERR_NAME | ERR_VARALNUM); - if ((lp = *v++) == 0) - lp = STRNULL; + if ((lp = *v++) == 0) { + if (c->t_dlef || !isatty(OLDSTD)) { + Char c; + struct Strbuf s = Strbuf_INIT; + + while (wide_read(0, &c, (size_t) 1, 0) > 0) { + if (c == '\n') + break; + Strbuf_append1(&s, c | QUOTE); + } + Strbuf_terminate(&s); + lp = s.s; + } else + lp = STRNULL; + } lp = globone(lp, G_APPEND); cleanup_push(lp, xfree); diff --git a/sh.sem.c b/sh.sem.c index 0674a2e3..d5781896 100644 --- a/sh.sem.c +++ b/sh.sem.c @@ -367,23 +367,13 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, if (bifunc && (t->t_dflg & F_PIPEIN)) t->t_dflg &= ~(F_NOFORK); #endif /* BACKPIPE */ - /* - * Prevent forking cd, pushd, popd, chdir cause this will cause the - * shell not to change dir! (XXX: but only for nice?) - */ - if (bifunc && (bifunc->bfunct == (bfunc_t)dochngd || - bifunc->bfunct == (bfunc_t)dopushd || - bifunc->bfunct == (bfunc_t)dopopd)) - t->t_dflg &= ~(F_NICE); - if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 && (!bifunc || t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP | F_HUP)))) || /* - * We have to fork for eval too. + * We have to fork for piped built-ins too. */ - (bifunc && (t->t_dflg & F_PIPEIN) != 0 && - bifunc->bfunct == (bfunc_t)doeval)) { + (bifunc && (t->t_dflg & F_PIPEIN) != 0)) { #ifdef VFORK if (t->t_dtyp == NODE_PAREN || t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) @@ -631,17 +621,6 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, } doio(t, pipein, pipeout); -#ifdef BACKPIPE - if (t->t_dflg & F_PIPEIN) { - xclose(pipein[0]); - xclose(pipein[1]); - } -#else /* !BACKPIPE */ - if (t->t_dflg & F_PIPEOUT) { - xclose(pipeout[0]); - xclose(pipeout[1]); - } -#endif /* BACKPIPE */ /* * Perform a builtin function. If we are not forked, arrange for * possible stopping @@ -717,7 +696,6 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, execute(t->t_dcdr, wanttty, pv, pipeout, do_glob); #endif /* BACKPIPE */ break; - case NODE_LIST: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ); @@ -871,8 +849,7 @@ doio(struct command *t, int *pipein, int *pipeout) } else if (flags & F_PIPEIN) { xclose(0); - TCSH_IGNORE(dup(pipein[0])); - xclose(pipein[0]); + (void) dmove(pipein[0], 0); xclose(pipein[1]); } else if ((flags & F_NOINTERRUPT) && tpgrp == -1) { @@ -934,7 +911,7 @@ doio(struct command *t, int *pipein, int *pipeout) } else if (flags & F_PIPEOUT) { xclose(1); - TCSH_IGNORE(dup(pipeout[1])); + (void) dcopy(pipeout[1], 1); is1atty = 0; } else { @@ -948,7 +925,7 @@ doio(struct command *t, int *pipein, int *pipeout) xclose(2); if (flags & F_STDERR) { - TCSH_IGNORE(dup(1)); + (void) dcopy(1, 2); is2atty = is1atty; } else { diff --git a/sh.set.c b/sh.set.c index ac73af9f..5d28c59f 100644 --- a/sh.set.c +++ b/sh.set.c @@ -248,7 +248,7 @@ doset(Char **v, struct command *c) int flags = VAR_READWRITE; int first_match = 0; int last_match = 0; - int changed = 0; + int changed, pipe; USE(c); v++; @@ -278,7 +278,13 @@ doset(Char **v, struct command *c) plist(&shvhed, flags); return; } + pipe = 0; + if (c->t_dlef || !isatty(OLDSTD)) + pipe = 1; do { + Char c; + struct Strbuf s; + hadsub = 0; vp = p; if (!letter(*p)) @@ -300,6 +306,7 @@ doset(Char **v, struct command *c) else if (*v && eq(*v, STRequal)) { if (*++v != NULL) p = *v++; + pipe = 0; } if (eq(p, STRLparen)) { Char **e = v; @@ -328,14 +335,45 @@ doset(Char **v, struct command *c) else if (hadsub) { Char *copy; - copy = Strsave(p); + if (pipe) { + memset(&s, 0, sizeof s); + while (wide_read(0, &c, (size_t) 1, 0) > 0) + Strbuf_append1(&s, c | QUOTE); + Strbuf_terminate(&s); + copy = s.s; + } else + copy = Strsave(p); cleanup_push(copy, xfree); asx(vp, subscr, copy); cleanup_ignore(copy); cleanup_until(copy); } - else - setv(vp, Strsave(p), flags); + else { + if (pipe) { + int empty = 1; + + memset(&s, 0, sizeof s); + while (wide_read(0, &c, (size_t) 1, 0) > 0) { + if (c == '\n') { + empty = 0; + + break; + } + Strbuf_append1(&s, c | QUOTE); + } + if (empty && s.s == NULL) { + Char **empty; + + empty = xcalloc(1, sizeof *empty); + set1(vp, empty, &shvhed, flags); + } + else { + Strbuf_terminate(&s); + setv(vp, s.s, flags); + } + } else + setv(vp, Strsave(p), flags); + } update_vars(vp); } while ((p = *v++) != NULL); }