Sat Aug 25 14:22:50 2018 UTC ()
Pull up following revision(s) (requested by kre in ticket #983):

	bin/sh/eval.c: revision 1.158
	bin/sh/eval.h: revision 1.21
	bin/sh/main.c: revision 1.74

PR bin/48875

Revert the changes that were made 19 May 2016 (principally eval.c 1.125)
and the bug fixes in subsequent days (eval.c 1.126 and 1.127) and also
update some newer code that was added more recently which acted in
accordance with those changes (make that code be as it would have been
if the changes now being reverted had never been made).

While the changes made did solve the problem, in a sense, they were
never correct (see the PR for some discussion) and it had always been
intended that they be reverted.   However, in practical sh code, no
issues were reported - until just recently - so nothing was done,
until now...

After this commit, the validate_fn_redirects test case of the sh ATF
test t_redir will fail.   In particular, the subtest of that test
case which is described in the source (of the test) as:

	This one is the real test for PR bin/48875

will fail.

Alternative changes, not to "fix" the problem in the PR, but to
often avoid it will be coming very soon - after which that ATF
test will succeed again.

XXX pullup-8


(martin)
diff -r1.140.2.4 -r1.140.2.5 src/bin/sh/eval.c
diff -r1.19 -r1.19.8.1 src/bin/sh/eval.h
diff -r1.70.2.1 -r1.70.2.2 src/bin/sh/main.c

cvs diff -r1.140.2.4 -r1.140.2.5 src/bin/sh/eval.c (expand / switch to unified diff)

--- src/bin/sh/eval.c 2018/08/25 11:45:40 1.140.2.4
+++ src/bin/sh/eval.c 2018/08/25 14:22:49 1.140.2.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: eval.c,v 1.140.2.4 2018/08/25 11:45:40 martin Exp $ */ 1/* $NetBSD: eval.c,v 1.140.2.5 2018/08/25 14:22:49 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1993 4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist. 8 * Kenneth Almquist.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36#ifndef lint 36#ifndef lint
37#if 0 37#if 0
38static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; 38static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
39#else 39#else
40__RCSID("$NetBSD: eval.c,v 1.140.2.4 2018/08/25 11:45:40 martin Exp $"); 40__RCSID("$NetBSD: eval.c,v 1.140.2.5 2018/08/25 14:22:49 martin Exp $");
41#endif 41#endif
42#endif /* not lint */ 42#endif /* not lint */
43 43
44#include <stdbool.h> 44#include <stdbool.h>
45#include <stdlib.h> 45#include <stdlib.h>
46#include <signal.h> 46#include <signal.h>
47#include <stdio.h> 47#include <stdio.h>
48#include <string.h> 48#include <string.h>
49#include <errno.h> 49#include <errno.h>
50#include <limits.h> 50#include <limits.h>
51#include <unistd.h> 51#include <unistd.h>
52#include <sys/fcntl.h> 52#include <sys/fcntl.h>
53#include <sys/stat.h> 53#include <sys/stat.h>
@@ -211,27 +211,27 @@ evalcmd(int argc, char **argv) @@ -211,27 +211,27 @@ evalcmd(int argc, char **argv)
211 211
212void 212void
213evalstring(char *s, int flag) 213evalstring(char *s, int flag)
214{ 214{
215 union node *n; 215 union node *n;
216 struct stackmark smark; 216 struct stackmark smark;
217 217
218 setstackmark(&smark); 218 setstackmark(&smark);
219 setinputstring(s, 1, line_number); 219 setinputstring(s, 1, line_number);
220 220
221 while ((n = parsecmd(0)) != NEOF) { 221 while ((n = parsecmd(0)) != NEOF) {
222 XTRACE(DBG_EVAL, ("evalstring: "), showtree(n)); 222 XTRACE(DBG_EVAL, ("evalstring: "), showtree(n));
223 if (n && nflag == 0) 223 if (n && nflag == 0)
224 evaltree(n, flag | EV_MORE); 224 evaltree(n, flag);
225 popstackmark(&smark); 225 popstackmark(&smark);
226 } 226 }
227 popfile(); 227 popfile();
228 popstackmark(&smark); 228 popstackmark(&smark);
229} 229}
230 230
231 231
232 232
233/* 233/*
234 * Evaluate a parse tree. The value is left in the global variable 234 * Evaluate a parse tree. The value is left in the global variable
235 * exitstatus. 235 * exitstatus.
236 */ 236 */
237 237
@@ -246,74 +246,73 @@ evaltree(union node *n, int flags) @@ -246,74 +246,73 @@ evaltree(union node *n, int flags)
246 VTRACE(DBG_EVAL, ("evaltree(%s) called\n", 246 VTRACE(DBG_EVAL, ("evaltree(%s) called\n",
247 n == NULL ? "NULL" : "-n")); 247 n == NULL ? "NULL" : "-n"));
248 if (nflag == 0) 248 if (nflag == 0)
249 exitstatus = 0; 249 exitstatus = 0;
250 goto out; 250 goto out;
251 } 251 }
252#ifndef SMALL 252#ifndef SMALL
253 displayhist = 1; /* show history substitutions done with fc */ 253 displayhist = 1; /* show history substitutions done with fc */
254#endif 254#endif
255 CTRACE(DBG_EVAL, ("pid %d, evaltree(%p: %s(%d), %#x) called\n", 255 CTRACE(DBG_EVAL, ("pid %d, evaltree(%p: %s(%d), %#x) called\n",
256 getpid(), n, NODETYPENAME(n->type), n->type, flags)); 256 getpid(), n, NODETYPENAME(n->type), n->type, flags));
257 switch (n->type) { 257 switch (n->type) {
258 case NSEMI: 258 case NSEMI:
259 evaltree(n->nbinary.ch1, (sflags & EV_TESTED) | 259 evaltree(n->nbinary.ch1, flags & EV_TESTED);
260 (n->nbinary.ch2 ? EV_MORE : 0)); 
261 if (nflag || evalskip) 260 if (nflag || evalskip)
262 goto out; 261 goto out;
263 evaltree(n->nbinary.ch2, flags); 262 evaltree(n->nbinary.ch2, flags);
264 break; 263 break;
265 case NAND: 264 case NAND:
266 evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE); 265 evaltree(n->nbinary.ch1, EV_TESTED);
267 if (nflag || evalskip || exitstatus != 0) 266 if (nflag || evalskip || exitstatus != 0)
268 goto out; 267 goto out;
269 evaltree(n->nbinary.ch2, flags); 268 evaltree(n->nbinary.ch2, flags);
270 break; 269 break;
271 case NOR: 270 case NOR:
272 evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE); 271 evaltree(n->nbinary.ch1, EV_TESTED);
273 if (nflag || evalskip || exitstatus == 0) 272 if (nflag || evalskip || exitstatus == 0)
274 goto out; 273 goto out;
275 evaltree(n->nbinary.ch2, flags); 274 evaltree(n->nbinary.ch2, flags);
276 break; 275 break;
277 case NREDIR: 276 case NREDIR:
278 expredir(n->nredir.redirect); 277 expredir(n->nredir.redirect);
279 if (xflag && n->nredir.redirect) { 278 if (xflag && n->nredir.redirect) {
280 union node *rn; 279 union node *rn;
281 280
282 out2str(expandstr(ps4val(), line_number)); 281 out2str(expandstr(ps4val(), line_number));
283 out2str("using redirections:"); 282 out2str("using redirections:");
284 for (rn = n->nredir.redirect; rn; rn = rn->nfile.next) 283 for (rn = n->nredir.redirect; rn; rn = rn->nfile.next)
285 (void) outredir(&errout, rn, ' '); 284 (void) outredir(&errout, rn, ' ');
286 out2str(" do\n"); 285 out2str(" do\n");
287 flushout(&errout); 286 flushout(&errout);
288 } 287 }
289 redirect(n->nredir.redirect, REDIR_PUSH | REDIR_KEEP); 288 redirect(n->nredir.redirect, REDIR_PUSH | REDIR_KEEP);
290 evaltree(n->nredir.n, flags); 289 evaltree(n->nredir.n, flags);
291 popredir(); 290 popredir();
292 if (xflag && n->nredir.redirect) { 291 if (xflag && n->nredir.redirect) {
293 out2str(expandstr(ps4val(), line_number)); 292 out2str(expandstr(ps4val(), line_number));
294 out2str("done\n"); 293 out2str("done\n");
295 flushout(&errout); 294 flushout(&errout);
296 } 295 }
297 break; 296 break;
298 case NSUBSHELL: 297 case NSUBSHELL:
299 evalsubshell(n, flags & ~EV_MORE); 298 evalsubshell(n, flags);
300 do_etest = !(flags & EV_TESTED); 299 do_etest = !(flags & EV_TESTED);
301 break; 300 break;
302 case NBACKGND: 301 case NBACKGND:
303 evalsubshell(n, flags & ~EV_MORE); 302 evalsubshell(n, flags);
304 break; 303 break;
305 case NIF: { 304 case NIF: {
306 evaltree(n->nif.test, EV_TESTED | EV_MORE); 305 evaltree(n->nif.test, EV_TESTED);
307 if (nflag || evalskip) 306 if (nflag || evalskip)
308 goto out; 307 goto out;
309 if (exitstatus == 0) 308 if (exitstatus == 0)
310 evaltree(n->nif.ifpart, flags); 309 evaltree(n->nif.ifpart, flags);
311 else if (n->nif.elsepart) 310 else if (n->nif.elsepart)
312 evaltree(n->nif.elsepart, flags); 311 evaltree(n->nif.elsepart, flags);
313 else 312 else
314 exitstatus = 0; 313 exitstatus = 0;
315 break; 314 break;
316 } 315 }
317 case NWHILE: 316 case NWHILE:
318 case NUNTIL: 317 case NUNTIL:
319 evalloop(n, sflags); 318 evalloop(n, sflags);
@@ -321,31 +320,31 @@ evaltree(union node *n, int flags) @@ -321,31 +320,31 @@ evaltree(union node *n, int flags)
321 case NFOR: 320 case NFOR:
322 evalfor(n, sflags); 321 evalfor(n, sflags);
323 break; 322 break;
324 case NCASE: 323 case NCASE:
325 evalcase(n, sflags); 324 evalcase(n, sflags);
326 break; 325 break;
327 case NDEFUN: 326 case NDEFUN:
328 CTRACE(DBG_EVAL, ("Defining fn %s @%d%s\n", n->narg.text, 327 CTRACE(DBG_EVAL, ("Defining fn %s @%d%s\n", n->narg.text,
329 n->narg.lineno, fnline1 ? " LINENO=1" : "")); 328 n->narg.lineno, fnline1 ? " LINENO=1" : ""));
330 defun(n->narg.text, n->narg.next, n->narg.lineno); 329 defun(n->narg.text, n->narg.next, n->narg.lineno);
331 exitstatus = 0; 330 exitstatus = 0;
332 break; 331 break;
333 case NNOT: 332 case NNOT:
334 evaltree(n->nnot.com, (sflags & EV_MORE) | EV_TESTED); 333 evaltree(n->nnot.com, EV_TESTED);
335 exitstatus = !exitstatus; 334 exitstatus = !exitstatus;
336 break; 335 break;
337 case NDNOT: 336 case NDNOT:
338 evaltree(n->nnot.com, (sflags & EV_MORE) | EV_TESTED); 337 evaltree(n->nnot.com, EV_TESTED);
339 if (exitstatus != 0) 338 if (exitstatus != 0)
340 exitstatus = 1; 339 exitstatus = 1;
341 break; 340 break;
342 case NPIPE: 341 case NPIPE:
343 evalpipe(n); 342 evalpipe(n);
344 do_etest = !(flags & EV_TESTED); 343 do_etest = !(flags & EV_TESTED);
345 break; 344 break;
346 case NCMD: 345 case NCMD:
347 evalcommand(n, flags, NULL); 346 evalcommand(n, flags, NULL);
348 do_etest = !(flags & EV_TESTED); 347 do_etest = !(flags & EV_TESTED);
349 break; 348 break;
350 default: 349 default:
351#ifdef NODETYPENAME 350#ifdef NODETYPENAME
@@ -369,46 +368,46 @@ evalloop(union node *n, int flags) @@ -369,46 +368,46 @@ evalloop(union node *n, int flags)
369{ 368{
370 int status; 369 int status;
371 370
372 loopnest++; 371 loopnest++;
373 status = 0; 372 status = 0;
374 373
375 CTRACE(DBG_EVAL, ("evalloop %s:", NODETYPENAME(n->type))); 374 CTRACE(DBG_EVAL, ("evalloop %s:", NODETYPENAME(n->type)));
376 VXTRACE(DBG_EVAL, (" "), showtree(n->nbinary.ch1)); 375 VXTRACE(DBG_EVAL, (" "), showtree(n->nbinary.ch1));
377 VXTRACE(DBG_EVAL, ("evalloop do: "), showtree(n->nbinary.ch2)); 376 VXTRACE(DBG_EVAL, ("evalloop do: "), showtree(n->nbinary.ch2));
378 VTRACE(DBG_EVAL, ("evalloop done\n")); 377 VTRACE(DBG_EVAL, ("evalloop done\n"));
379 CTRACE(DBG_EVAL, ("\n")); 378 CTRACE(DBG_EVAL, ("\n"));
380 379
381 for (;;) { 380 for (;;) {
382 evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE); 381 evaltree(n->nbinary.ch1, EV_TESTED);
383 if (nflag) 382 if (nflag)
384 break; 383 break;
385 if (evalskip) { 384 if (evalskip) {
386 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { 385 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
387 evalskip = SKIPNONE; 386 evalskip = SKIPNONE;
388 continue; 387 continue;
389 } 388 }
390 if (evalskip == SKIPBREAK && --skipcount <= 0) 389 if (evalskip == SKIPBREAK && --skipcount <= 0)
391 evalskip = SKIPNONE; 390 evalskip = SKIPNONE;
392 break; 391 break;
393 } 392 }
394 if (n->type == NWHILE) { 393 if (n->type == NWHILE) {
395 if (exitstatus != 0) 394 if (exitstatus != 0)
396 break; 395 break;
397 } else { 396 } else {
398 if (exitstatus == 0) 397 if (exitstatus == 0)
399 break; 398 break;
400 } 399 }
401 evaltree(n->nbinary.ch2, (flags & EV_TESTED) | EV_MORE); 400 evaltree(n->nbinary.ch2, flags & EV_TESTED);
402 status = exitstatus; 401 status = exitstatus;
403 if (evalskip) 402 if (evalskip)
404 goto skipping; 403 goto skipping;
405 } 404 }
406 loopnest--; 405 loopnest--;
407 exitstatus = status; 406 exitstatus = status;
408} 407}
409 408
410 409
411 410
412STATIC void 411STATIC void
413evalfor(union node *n, int flags) 412evalfor(union node *n, int flags)
414{ 413{
@@ -421,43 +420,38 @@ evalfor(union node *n, int flags) @@ -421,43 +420,38 @@ evalfor(union node *n, int flags)
421 status = nflag ? exitstatus : 0; 420 status = nflag ? exitstatus : 0;
422 421
423 setstackmark(&smark); 422 setstackmark(&smark);
424 arglist.lastp = &arglist.list; 423 arglist.lastp = &arglist.list;
425 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { 424 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
426 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); 425 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
427 if (evalskip) 426 if (evalskip)
428 goto out; 427 goto out;
429 } 428 }
430 *arglist.lastp = NULL; 429 *arglist.lastp = NULL;
431 430
432 loopnest++; 431 loopnest++;
433 for (sp = arglist.list ; sp ; sp = sp->next) { 432 for (sp = arglist.list ; sp ; sp = sp->next) {
434 int f = flags & (EV_TESTED | EV_MORE); 
435 
436 if (sp->next) 
437 f |= EV_MORE; 
438 
439 if (xflag) { 433 if (xflag) {
440 out2str(expandstr(ps4val(), line_number)); 434 out2str(expandstr(ps4val(), line_number));
441 out2str("for "); 435 out2str("for ");
442 out2str(n->nfor.var); 436 out2str(n->nfor.var);
443 out2c('='); 437 out2c('=');
444 out2shstr(sp->text); 438 out2shstr(sp->text);
445 out2c('\n'); 439 out2c('\n');
446 flushout(&errout); 440 flushout(&errout);
447 } 441 }
448 442
449 setvar(n->nfor.var, sp->text, 0); 443 setvar(n->nfor.var, sp->text, 0);
450 evaltree(n->nfor.body, f); 444 evaltree(n->nfor.body, flags & EV_TESTED);
451 status = exitstatus; 445 status = exitstatus;
452 if (nflag) 446 if (nflag)
453 break; 447 break;
454 if (evalskip) { 448 if (evalskip) {
455 if (evalskip == SKIPCONT && --skipcount <= 0) { 449 if (evalskip == SKIPCONT && --skipcount <= 0) {
456 evalskip = SKIPNONE; 450 evalskip = SKIPNONE;
457 continue; 451 continue;
458 } 452 }
459 if (evalskip == SKIPBREAK && --skipcount <= 0) 453 if (evalskip == SKIPBREAK && --skipcount <= 0)
460 evalskip = SKIPNONE; 454 evalskip = SKIPNONE;
461 break; 455 break;
462 } 456 }
463 } 457 }
@@ -483,28 +477,27 @@ evalcase(union node *n, int flags) @@ -483,28 +477,27 @@ evalcase(union node *n, int flags)
483 line_number = n->ncase.lineno; 477 line_number = n->ncase.lineno;
484 expandarg(n->ncase.expr, &arglist, EXP_TILDE); 478 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
485 for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) { 479 for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
486 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) { 480 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
487 line_number = patp->narg.lineno; 481 line_number = patp->narg.lineno;
488 if (casematch(patp, arglist.list->text)) { 482 if (casematch(patp, arglist.list->text)) {
489 while (cp != NULL && evalskip == 0 && 483 while (cp != NULL && evalskip == 0 &&
490 nflag == 0) { 484 nflag == 0) {
491 if (cp->type == NCLISTCONT) 485 if (cp->type == NCLISTCONT)
492 ncp = cp->nclist.next; 486 ncp = cp->nclist.next;
493 else 487 else
494 ncp = NULL; 488 ncp = NULL;
495 line_number = cp->nclist.lineno; 489 line_number = cp->nclist.lineno;
496 evaltree(cp->nclist.body, 490 evaltree(cp->nclist.body, flags);
497 ncp ? (flags | EV_MORE) : flags); 
498 status = exitstatus; 491 status = exitstatus;
499 cp = ncp; 492 cp = ncp;
500 } 493 }
501 goto out; 494 goto out;
502 } 495 }
503 } 496 }
504 } 497 }
505 out: 498 out:
506 exitstatus = status; 499 exitstatus = status;
507 popstackmark(&smark); 500 popstackmark(&smark);
508} 501}
509 502
510 503
@@ -955,28 +948,26 @@ evalcommand(union node *cmd, int flgs, s @@ -955,28 +948,26 @@ evalcommand(union node *cmd, int flgs, s
955 } 948 }
956 949
957 /* Fork off a child process if necessary. */ 950 /* Fork off a child process if necessary. */
958 if (cmd->ncmd.backgnd || (trap[0] && (flags & EV_EXIT) != 0) 951 if (cmd->ncmd.backgnd || (trap[0] && (flags & EV_EXIT) != 0)
959 || ((cmdentry.cmdtype == CMDNORMAL || cmdentry.cmdtype == CMDUNKNOWN) 952 || ((cmdentry.cmdtype == CMDNORMAL || cmdentry.cmdtype == CMDUNKNOWN)
960 && (flags & EV_EXIT) == 0) 953 && (flags & EV_EXIT) == 0)
961 || ((flags & EV_BACKCMD) != 0 && 954 || ((flags & EV_BACKCMD) != 0 &&
962 ((cmdentry.cmdtype != CMDBUILTIN && cmdentry.cmdtype != CMDSPLBLTIN) 955 ((cmdentry.cmdtype != CMDBUILTIN && cmdentry.cmdtype != CMDSPLBLTIN)
963 || cmdentry.u.bltin == dotcmd 956 || cmdentry.u.bltin == dotcmd
964 || cmdentry.u.bltin == evalcmd))) { 957 || cmdentry.u.bltin == evalcmd))) {
965 INTOFF; 958 INTOFF;
966 jp = makejob(cmd, 1); 959 jp = makejob(cmd, 1);
967 mode = cmd->ncmd.backgnd; 960 mode = cmd->ncmd.backgnd;
968 if (mode) 
969 flags &= ~EV_MORE; 
970 if (flags & EV_BACKCMD) { 961 if (flags & EV_BACKCMD) {
971 mode = FORK_NOJOB; 962 mode = FORK_NOJOB;
972 if (sh_pipe(pip) < 0) 963 if (sh_pipe(pip) < 0)
973 error("Pipe call failed"); 964 error("Pipe call failed");
974 } 965 }
975#ifdef DO_SHAREDVFORK 966#ifdef DO_SHAREDVFORK
976 /* It is essential that if DO_SHAREDVFORK is defined that the 967 /* It is essential that if DO_SHAREDVFORK is defined that the
977 * child's address space is actually shared with the parent as 968 * child's address space is actually shared with the parent as
978 * we rely on this. 969 * we rely on this.
979 */ 970 */
980 if (usefork == 0 && cmdentry.cmdtype == CMDNORMAL) { 971 if (usefork == 0 && cmdentry.cmdtype == CMDNORMAL) {
981 pid_t pid; 972 pid_t pid;
982 int serrno; 973 int serrno;
@@ -1058,26 +1049,27 @@ evalcommand(union node *cmd, int flgs, s @@ -1058,26 +1049,27 @@ evalcommand(union node *cmd, int flgs, s
1058 } 1049 }
1059 close(pip[0]); 1050 close(pip[0]);
1060 movefd(pip[1], 1); 1051 movefd(pip[1], 1);
1061 } 1052 }
1062 flags |= EV_EXIT; 1053 flags |= EV_EXIT;
1063 } 1054 }
1064 1055
1065 /* This is the child process if a fork occurred. */ 1056 /* This is the child process if a fork occurred. */
1066 /* Execute the command. */ 1057 /* Execute the command. */
1067 switch (cmdentry.cmdtype) { 1058 switch (cmdentry.cmdtype) {
1068 case CMDFUNCTION: 1059 case CMDFUNCTION:
1069 VXTRACE(DBG_EVAL, ("Shell function: "), trargs(argv)); 1060 VXTRACE(DBG_EVAL, ("Shell function: "), trargs(argv));
1070 redirect(cmd->ncmd.redirect, flags & EV_MORE ? REDIR_PUSH : 0); 1061 redirect(cmd->ncmd.redirect, flags & EV_MORE ? REDIR_PUSH : 0);
 1062 redirect(cmd->ncmd.redirect, REDIR_PUSH);
1071 saveparam = shellparam; 1063 saveparam = shellparam;
1072 shellparam.malloc = 0; 1064 shellparam.malloc = 0;
1073 shellparam.reset = 1; 1065 shellparam.reset = 1;
1074 shellparam.nparam = argc - 1; 1066 shellparam.nparam = argc - 1;
1075 shellparam.p = argv + 1; 1067 shellparam.p = argv + 1;
1076 shellparam.optnext = NULL; 1068 shellparam.optnext = NULL;
1077 INTOFF; 1069 INTOFF;
1078 savelocalvars = localvars; 1070 savelocalvars = localvars;
1079 localvars = NULL; 1071 localvars = NULL;
1080 reffunc(cmdentry.u.func); 1072 reffunc(cmdentry.u.func);
1081 INTON; 1073 INTON;
1082 if (setjmp(jmploc.loc)) { 1074 if (setjmp(jmploc.loc)) {
1083 if (exception == EXSHELLPROC) { 1075 if (exception == EXSHELLPROC) {
@@ -1116,28 +1108,27 @@ evalcommand(union node *cmd, int flgs, s @@ -1116,28 +1108,27 @@ evalcommand(union node *cmd, int flgs, s
1116 if (++funcnest > 1000) 1108 if (++funcnest > 1000)
1117 error("too many nested function calls"); 1109 error("too many nested function calls");
1118 evaltree(getfuncnode(cmdentry.u.func), flags & EV_TESTED); 1110 evaltree(getfuncnode(cmdentry.u.func), flags & EV_TESTED);
1119 funcnest--; 1111 funcnest--;
1120 INTOFF; 1112 INTOFF;
1121 unreffunc(cmdentry.u.func); 1113 unreffunc(cmdentry.u.func);
1122 poplocalvars(); 1114 poplocalvars();
1123 localvars = savelocalvars; 1115 localvars = savelocalvars;
1124 funclinebase = savefuncline; 1116 funclinebase = savefuncline;
1125 funclineabs = savefuncabs; 1117 funclineabs = savefuncabs;
1126 freeparam(&shellparam); 1118 freeparam(&shellparam);
1127 shellparam = saveparam; 1119 shellparam = saveparam;
1128 handler = savehandler; 1120 handler = savehandler;
1129 if (flags & EV_MORE) 1121 popredir();
1130 popredir(); 
1131 INTON; 1122 INTON;
1132 if (evalskip == SKIPFUNC) { 1123 if (evalskip == SKIPFUNC) {
1133 evalskip = SKIPNONE; 1124 evalskip = SKIPNONE;
1134 skipcount = 0; 1125 skipcount = 0;
1135 } 1126 }
1136 if (flags & EV_EXIT) 1127 if (flags & EV_EXIT)
1137 exitshell(exitstatus); 1128 exitshell(exitstatus);
1138 break; 1129 break;
1139 1130
1140 case CMDBUILTIN: 1131 case CMDBUILTIN:
1141 case CMDSPLBLTIN: 1132 case CMDSPLBLTIN:
1142 VXTRACE(DBG_EVAL, ("builtin command: "), trargs(argv)); 1133 VXTRACE(DBG_EVAL, ("builtin command: "), trargs(argv));
1143 mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH; 1134 mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH;

cvs diff -r1.19 -r1.19.8.1 src/bin/sh/eval.h (expand / switch to unified diff)

--- src/bin/sh/eval.h 2016/05/09 21:03:10 1.19
+++ src/bin/sh/eval.h 2018/08/25 14:22:49 1.19.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: eval.h,v 1.19 2016/05/09 21:03:10 kre Exp $ */ 1/* $NetBSD: eval.h,v 1.19.8.1 2018/08/25 14:22:49 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1991, 1993 4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist. 8 * Kenneth Almquist.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -66,14 +66,13 @@ enum skipstate { @@ -66,14 +66,13 @@ enum skipstate {
66 66
67enum skipstate current_skipstate(void); 67enum skipstate current_skipstate(void);
68void stop_skipping(void); /* reset internal skipping state to SKIPNONE */ 68void stop_skipping(void); /* reset internal skipping state to SKIPNONE */
69 69
70/* 70/*
71 * Only for use by reset() in init.c! 71 * Only for use by reset() in init.c!
72 */ 72 */
73void reset_eval(void); 73void reset_eval(void);
74 74
75/* flags in argument to evaltree */ 75/* flags in argument to evaltree */
76#define EV_EXIT 0x01 /* exit after evaluating tree */ 76#define EV_EXIT 0x01 /* exit after evaluating tree */
77#define EV_TESTED 0x02 /* exit status is checked; ignore -e flag */ 77#define EV_TESTED 0x02 /* exit status is checked; ignore -e flag */
78#define EV_BACKCMD 0x04 /* command executing within back quotes */ 78#define EV_BACKCMD 0x04 /* command executing within back quotes */
79#define EV_MORE 0x08 /* more commands in this sub-shell */ 

cvs diff -r1.70.2.1 -r1.70.2.2 src/bin/sh/main.c (expand / switch to unified diff)

--- src/bin/sh/main.c 2017/07/23 14:58:14 1.70.2.1
+++ src/bin/sh/main.c 2018/08/25 14:22:49 1.70.2.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: main.c,v 1.70.2.1 2017/07/23 14:58:14 snj Exp $ */ 1/* $NetBSD: main.c,v 1.70.2.2 2018/08/25 14:22:49 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1991, 1993 4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist. 8 * Kenneth Almquist.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -32,27 +32,27 @@ @@ -32,27 +32,27 @@
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36#ifndef lint 36#ifndef lint
37__COPYRIGHT("@(#) Copyright (c) 1991, 1993\ 37__COPYRIGHT("@(#) Copyright (c) 1991, 1993\
38 The Regents of the University of California. All rights reserved."); 38 The Regents of the University of California. All rights reserved.");
39#endif /* not lint */ 39#endif /* not lint */
40 40
41#ifndef lint 41#ifndef lint
42#if 0 42#if 0
43static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95"; 43static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95";
44#else 44#else
45__RCSID("$NetBSD: main.c,v 1.70.2.1 2017/07/23 14:58:14 snj Exp $"); 45__RCSID("$NetBSD: main.c,v 1.70.2.2 2018/08/25 14:22:49 martin Exp $");
46#endif 46#endif
47#endif /* not lint */ 47#endif /* not lint */
48 48
49#include <errno.h> 49#include <errno.h>
50#include <stdio.h> 50#include <stdio.h>
51#include <signal.h> 51#include <signal.h>
52#include <sys/stat.h> 52#include <sys/stat.h>
53#include <unistd.h> 53#include <unistd.h>
54#include <stdlib.h> 54#include <stdlib.h>
55#include <locale.h> 55#include <locale.h>
56#include <fcntl.h> 56#include <fcntl.h>
57 57
58 58
@@ -282,27 +282,27 @@ cmdloop(int top) @@ -282,27 +282,27 @@ cmdloop(int top)
282 if (!top || numeof >= 50) 282 if (!top || numeof >= 50)
283 break; 283 break;
284 if (nflag) 284 if (nflag)
285 break; 285 break;
286 if (!stoppedjobs()) { 286 if (!stoppedjobs()) {
287 if (!iflag || !Iflag) 287 if (!iflag || !Iflag)
288 break; 288 break;
289 out2str("\nUse \"exit\" to leave shell.\n"); 289 out2str("\nUse \"exit\" to leave shell.\n");
290 } 290 }
291 numeof++; 291 numeof++;
292 } else if (n != NULL && nflag == 0) { 292 } else if (n != NULL && nflag == 0) {
293 job_warning = (job_warning == 2) ? 1 : 0; 293 job_warning = (job_warning == 2) ? 1 : 0;
294 numeof = 0; 294 numeof = 0;
295 evaltree(n, EV_MORE); 295 evaltree(n, 0);
296 } 296 }
297 popstackmark(&smark); 297 popstackmark(&smark);
298 setstackmark(&smark); 298 setstackmark(&smark);
299 299
300 /* 300 /*
301 * Any SKIP* can occur here! SKIP(FUNC|BREAK|CONT) occur when 301 * Any SKIP* can occur here! SKIP(FUNC|BREAK|CONT) occur when
302 * a dotcmd is in a loop or a function body and appropriate 302 * a dotcmd is in a loop or a function body and appropriate
303 * built-ins occurs in file scope in the sourced file. Values 303 * built-ins occurs in file scope in the sourced file. Values
304 * other than SKIPFILE are reset by the appropriate eval*() 304 * other than SKIPFILE are reset by the appropriate eval*()
305 * that contained the dotcmd() call. 305 * that contained the dotcmd() call.
306 */ 306 */
307 skip = current_skipstate(); 307 skip = current_skipstate();
308 if (skip != SKIPNONE) { 308 if (skip != SKIPNONE) {