From b03d8724a74c2429cd45bfb9b45cbe7bcc1f08c5 Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Wed, 29 May 2024 01:54:55 -0300 Subject: [PATCH 1/5] Variable assignment from pipes and redirections --- sh.func.c | 17 +++++++++++++++-- sh.set.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/sh.func.c b/sh.func.c index a9c0dd6f..db4c8904 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_dflg & F_PIPEIN || c->t_dlef) { + 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 | LITERAL); + } + Strbuf_terminate(&s); + lp = s.s; + } else + lp = STRNULL; + } lp = globone(lp, G_APPEND); cleanup_push(lp, xfree); diff --git a/sh.set.c b/sh.set.c index ac73af9f..09b6886e 100644 --- a/sh.set.c +++ b/sh.set.c @@ -248,7 +248,8 @@ doset(Char **v, struct command *c) int flags = VAR_READWRITE; int first_match = 0; int last_match = 0; - int changed = 0; + int changed; + int pipe; USE(c); v++; @@ -278,6 +279,9 @@ doset(Char **v, struct command *c) plist(&shvhed, flags); return; } + pipe = 0; + if (c->t_dflg & F_PIPEIN || c->t_dlef) + pipe = 1; do { hadsub = 0; vp = p; @@ -300,6 +304,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 +333,51 @@ doset(Char **v, struct command *c) else if (hadsub) { Char *copy; - copy = Strsave(p); + if (pipe) { + 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 | LITERAL); + } + 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) { + Char c; + struct Strbuf s = Strbuf_INIT; + int empty = 1; + + while (wide_read(0, &c, (size_t) 1, 0) > 0) { + if (c == '\n') { + empty = 0; + + break; + } + Strbuf_append1(&s, c | LITERAL); + } + if (empty && s.s == NULL) { + Char **empty; + + *(empty = xmalloc(sizeof *empty)) = NULL; + 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); } From 67e978507a7ef8a0dfcedf7e3c3b3d4ff3253b65 Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Wed, 29 May 2024 08:38:48 -0300 Subject: [PATCH 2/5] sh.set.c: indexing should read until EOF --- sh.set.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sh.set.c b/sh.set.c index 09b6886e..ac1d7de3 100644 --- a/sh.set.c +++ b/sh.set.c @@ -337,11 +337,8 @@ doset(Char **v, struct command *c) Char c; struct Strbuf s = Strbuf_INIT; - while (wide_read(0, &c, (size_t) 1, 0) > 0) { - if (c == '\n') - break; + while (wide_read(0, &c, (size_t) 1, 0) > 0) Strbuf_append1(&s, c | LITERAL); - } Strbuf_terminate(&s); copy = s.s; } else From a3a0ce99b72c9931d7e84ca0aba113ae362e7bbf Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Fri, 31 May 2024 00:18:12 -0300 Subject: [PATCH 3/5] Fix pipes + test improvement --- sh.func.c | 2 +- sh.sem.c | 33 +++++---------------------------- sh.set.c | 2 +- 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/sh.func.c b/sh.func.c index db4c8904..9d9dcd77 100644 --- a/sh.func.c +++ b/sh.func.c @@ -1354,7 +1354,7 @@ dosetenv(Char **v, struct command *c) stderror(ERR_NAME | ERR_VARALNUM); if ((lp = *v++) == 0) { - if (c->t_dflg & F_PIPEIN || c->t_dlef) { + if (c->t_dlef || !isatty(OLDSTD)) { Char c; struct Strbuf s = Strbuf_INIT; diff --git a/sh.sem.c b/sh.sem.c index 0674a2e3..8448cdc6 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]); + OLDSTD = 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])); + SHOUT = 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)); + SHDIAG = dcopy(1, 2); is2atty = is1atty; } else { diff --git a/sh.set.c b/sh.set.c index ac1d7de3..e4bf0ea5 100644 --- a/sh.set.c +++ b/sh.set.c @@ -280,7 +280,7 @@ doset(Char **v, struct command *c) return; } pipe = 0; - if (c->t_dflg & F_PIPEIN || c->t_dlef) + if (c->t_dlef || !isatty(OLDSTD)) pipe = 1; do { hadsub = 0; From 481ff5c3d24d10bd4efcec37ed5ac1bf3034e724 Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Wed, 5 Jun 2024 21:02:47 -0300 Subject: [PATCH 4/5] sh.sem.c: fix stderr redirections --- sh.sem.c | 6 +++--- sh.set.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sh.sem.c b/sh.sem.c index 8448cdc6..d5781896 100644 --- a/sh.sem.c +++ b/sh.sem.c @@ -849,7 +849,7 @@ doio(struct command *t, int *pipein, int *pipeout) } else if (flags & F_PIPEIN) { xclose(0); - OLDSTD = dmove(pipein[0], 0); + (void) dmove(pipein[0], 0); xclose(pipein[1]); } else if ((flags & F_NOINTERRUPT) && tpgrp == -1) { @@ -911,7 +911,7 @@ doio(struct command *t, int *pipein, int *pipeout) } else if (flags & F_PIPEOUT) { xclose(1); - SHOUT = dcopy(pipeout[1], 1); + (void) dcopy(pipeout[1], 1); is1atty = 0; } else { @@ -925,7 +925,7 @@ doio(struct command *t, int *pipein, int *pipeout) xclose(2); if (flags & F_STDERR) { - SHDIAG = dcopy(1, 2); + (void) dcopy(1, 2); is2atty = is1atty; } else { diff --git a/sh.set.c b/sh.set.c index e4bf0ea5..97ad9bc8 100644 --- a/sh.set.c +++ b/sh.set.c @@ -365,7 +365,7 @@ doset(Char **v, struct command *c) if (empty && s.s == NULL) { Char **empty; - *(empty = xmalloc(sizeof *empty)) = NULL; + empty = xcalloc(1, sizeof *empty); set1(vp, empty, &shvhed, flags); } else { From 008345d68838a55790a5ef1b295f455781a6b133 Mon Sep 17 00:00:00 2001 From: Krush206 <37114863+Krush206@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:48:50 -0300 Subject: [PATCH 5/5] Prefer QUOTE over LITERAL --- sh.func.c | 2 +- sh.set.c | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/sh.func.c b/sh.func.c index 9d9dcd77..5a996871 100644 --- a/sh.func.c +++ b/sh.func.c @@ -1361,7 +1361,7 @@ dosetenv(Char **v, struct command *c) while (wide_read(0, &c, (size_t) 1, 0) > 0) { if (c == '\n') break; - Strbuf_append1(&s, c | LITERAL); + Strbuf_append1(&s, c | QUOTE); } Strbuf_terminate(&s); lp = s.s; diff --git a/sh.set.c b/sh.set.c index 97ad9bc8..5d28c59f 100644 --- a/sh.set.c +++ b/sh.set.c @@ -248,8 +248,7 @@ doset(Char **v, struct command *c) int flags = VAR_READWRITE; int first_match = 0; int last_match = 0; - int changed; - int pipe; + int changed, pipe; USE(c); v++; @@ -283,6 +282,9 @@ doset(Char **v, struct command *c) if (c->t_dlef || !isatty(OLDSTD)) pipe = 1; do { + Char c; + struct Strbuf s; + hadsub = 0; vp = p; if (!letter(*p)) @@ -334,11 +336,9 @@ doset(Char **v, struct command *c) Char *copy; if (pipe) { - Char c; - struct Strbuf s = Strbuf_INIT; - + memset(&s, 0, sizeof s); while (wide_read(0, &c, (size_t) 1, 0) > 0) - Strbuf_append1(&s, c | LITERAL); + Strbuf_append1(&s, c | QUOTE); Strbuf_terminate(&s); copy = s.s; } else @@ -350,17 +350,16 @@ doset(Char **v, struct command *c) } else { if (pipe) { - Char c; - struct Strbuf s = Strbuf_INIT; 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 | LITERAL); + Strbuf_append1(&s, c | QUOTE); } if (empty && s.s == NULL) { Char **empty;