From owner-freebsd-hackers Tue Dec 5 07:49:45 1995 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id HAA10538 for hackers-outgoing; Tue, 5 Dec 1995 07:49:45 -0800 Received: from gw.itfs.nsk.su (gw.itfs.nsk.su [193.124.36.33]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id HAA10465 for ; Tue, 5 Dec 1995 07:49:01 -0800 Received: from itfs.UUCP (uucp@localhost) by gw.itfs.nsk.su (8.6.12/8.6.12) with UUCP id UAA17962 for hackers@freebsd.org; Tue, 5 Dec 1995 20:51:35 +0600 Received: by itfs.nsk.su; Tue, 5 Dec 95 20:03:01 +0600 (NSK) Received: (from daemon@localhost) by news.itfs.nsk.su (8.6.8/8.6.6) id TAA15686; Tue, 5 Dec 1995 19:53:34 +0600 From: nnd@itfs.nsk.su (Nickolay N. Dudorov) To: hackers@freebsd.org Subject: (Very) Old bug in /bin/sh (ash ?) Message-ID: Date: Tue, 5 Dec 1995 13:53:27 GMT Sender: owner-hackers@freebsd.org Precedence: bulk On all 'sh'-ells here (SysV.3.2, SunOS 4.1.3 etc) construction: { a; b; c & d; e; } is parsed and evaluated as a list of simple commands and one of them (namely - c) is executed 'in background' or 'asynchronously'. But on the FreeBSD systems (versions from 1.1 to 2.1) it is parsed and evaluated as: { { a; b; c; } & { d; e; } } Is this a BUG or a FEATURE ? It seems to me that it is a bug in 'ash'. Following is a fix for this misbehavior. (This diff -u command was executed in /usr/src/bin/sh directory on 2.1-STABLE sources SUP-ed until yesterday). N.Dudorov ==================================================================== --- parser.c.ORG Tue Dec 5 16:15:52 1995 +++ parser.c Tue Dec 5 18:50:22 1995 @@ -149,30 +149,13 @@ n1 = andor(); for (;;) { switch (readtoken()) { - case TBACKGND: - if (n1->type == NCMD || n1->type == NPIPE) { - n1->ncmd.backgnd = 1; - } else if (n1->type == NREDIR) { - n1->type = NBACKGND; - } else { - n3 = (union node *)stalloc(sizeof (struct nredir)); - n3->type = NBACKGND; - n3->nredir.n = n1; - n3->nredir.redirect = NULL; - n1 = n3; - } - goto tsemi; case TNL: - tokpushback++; + parseheredoc(); + if (nlflag) + return n1; /* fall through */ -tsemi: case TSEMI: - if (readtoken() == TNL) { - parseheredoc(); - if (nlflag) - return n1; - } else { - tokpushback++; - } + case TBACKGND: + case TSEMI: checkkwd = 2; if (tokendlist[peektoken()]) return n1; @@ -212,6 +195,19 @@ } else if (t == TOR) { t = NOR; } else { + if (t == TBACKGND) { + if (n1->type == NCMD || n1->type == NPIPE) { + n1->ncmd.backgnd = 1; + } else if (n1->type == NREDIR) { + n1->type = NBACKGND; + } else { + n3 = (union node *)stalloc(sizeof (struct nredir)); + n3->type = NBACKGND; + n3->nredir.n = n1; + n3->nredir.redirect = NULL; + n1 = n3; + } + } tokpushback++; return n1; }