From owner-freebsd-bugs@FreeBSD.ORG Sat Jun 13 21:20:04 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6F8EC106564A for ; Sat, 13 Jun 2009 21:20:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 5466E8FC1A for ; Sat, 13 Jun 2009 21:20:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n5DLK41b053649 for ; Sat, 13 Jun 2009 21:20:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n5DLK4sT053648; Sat, 13 Jun 2009 21:20:04 GMT (envelope-from gnats) Date: Sat, 13 Jun 2009 21:20:04 GMT Message-Id: <200906132120.n5DLK4sT053648@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: dfilter@FreeBSD.ORG (dfilter service) Cc: Subject: Re: bin/113860: commit references a PR X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: dfilter service List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Jun 2009 21:20:04 -0000 The following reply was made to PR bin/113860; it has been noted by GNATS. From: dfilter@FreeBSD.ORG (dfilter service) To: bug-followup@FreeBSD.org Cc: Subject: Re: bin/113860: commit references a PR Date: Sat, 13 Jun 2009 21:17:56 +0000 (UTC) Author: jilles Date: Sat Jun 13 21:17:45 2009 New Revision: 194128 URL: http://svn.freebsd.org/changeset/base/194128 Log: Avoid leaving unnecessary waiting shells in many forms of sh -c COMMAND. This change only affects strings passed to -c, when the -s option is not used. The approach is to check if there may be additional data in the string after parsing each command. If there is none, use the EV_EXIT flag so that a fork may be omitted in specific cases. If there are empty lines after the command, the check will not see the end and forks will not be omitted. The same thing seems to happen in bash. Example: sh -c 'ps lT' No longer shows a shell process waiting for ps to finish. PR: bin/113860 Reviewed by: stefanf Approved by: ed (mentor) Modified: head/bin/sh/eval.c head/bin/sh/eval.h head/bin/sh/input.c head/bin/sh/input.h head/bin/sh/main.c Modified: head/bin/sh/eval.c ============================================================================== --- head/bin/sh/eval.c Sat Jun 13 21:10:41 2009 (r194127) +++ head/bin/sh/eval.c Sat Jun 13 21:17:45 2009 (r194128) @@ -74,11 +74,6 @@ __FBSDID("$FreeBSD$"); #endif -/* flags in argument to evaltree */ -#define EV_EXIT 01 /* exit after evaluating tree */ -#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ -#define EV_BACKCMD 04 /* command executing within back quotes */ - MKINIT int evalskip; /* set if we are skipping commands */ STATIC int skipcount; /* number of levels to skip */ MKINIT int loopnest; /* current loop nesting level */ @@ -163,20 +158,28 @@ evalstring(char *s, int flags) { union node *n; struct stackmark smark; + int flags_exit; + flags_exit = flags & EV_EXIT; + flags &= ~EV_EXIT; setstackmark(&smark); setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { - if (n != NULL) - evaltree(n, flags); + if (n != NULL) { + if (flags_exit && preadateof()) + evaltree(n, flags | EV_EXIT); + else + evaltree(n, flags); + } popstackmark(&smark); } popfile(); popstackmark(&smark); + if (flags_exit) + exitshell(exitstatus); } - /* * Evaluate a parse tree. The value is left in the global variable * exitstatus. Modified: head/bin/sh/eval.h ============================================================================== --- head/bin/sh/eval.h Sat Jun 13 21:10:41 2009 (r194127) +++ head/bin/sh/eval.h Sat Jun 13 21:17:45 2009 (r194128) @@ -45,6 +45,11 @@ struct backcmd { /* result of evalbackc struct job *jp; /* job structure for command */ }; +/* flags in argument to evaltree/evalstring */ +#define EV_EXIT 01 /* exit after evaluating tree */ +#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ +#define EV_BACKCMD 04 /* command executing within back quotes */ + int evalcmd(int, char **); void evalstring(char *, int); union node; /* BLETCH for ansi C */ Modified: head/bin/sh/input.c ============================================================================== --- head/bin/sh/input.c Sat Jun 13 21:10:41 2009 (r194127) +++ head/bin/sh/input.c Sat Jun 13 21:17:45 2009 (r194128) @@ -321,6 +321,23 @@ check: } /* + * Returns if we are certain we are at EOF. Does not cause any more input + * to be read from the outside world. + */ + +int +preadateof(void) +{ + if (parsenleft > 0) + return 0; + if (parsefile->strpush) + return 0; + if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) + return 1; + return 0; +} + +/* * Undo the last call to pgetc. Only one character may be pushed back. * PEOF may be pushed back. */ Modified: head/bin/sh/input.h ============================================================================== --- head/bin/sh/input.h Sat Jun 13 21:10:41 2009 (r194127) +++ head/bin/sh/input.h Sat Jun 13 21:17:45 2009 (r194128) @@ -48,6 +48,7 @@ extern int init_editline; /* 0 == not se char *pfgets(char *, int); int pgetc(void); int preadbuffer(void); +int preadateof(void); void pungetc(void); void pushstring(char *, int, void *); void popstring(void); Modified: head/bin/sh/main.c ============================================================================== --- head/bin/sh/main.c Sat Jun 13 21:10:41 2009 (r194127) +++ head/bin/sh/main.c Sat Jun 13 21:17:45 2009 (r194128) @@ -178,7 +178,7 @@ state2: state3: state = 4; if (minusc) { - evalstring(minusc, 0); + evalstring(minusc, sflag ? 0 : EV_EXIT); } if (sflag || minusc == NULL) { state4: /* XXX ??? - why isn't this before the "if" statement */ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"