From owner-svn-src-all@freebsd.org Thu Jan 7 20:48:26 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3FFA0A669BD; Thu, 7 Jan 2016 20:48:26 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 119341454; Thu, 7 Jan 2016 20:48:25 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u07KmPL4038270; Thu, 7 Jan 2016 20:48:25 GMT (envelope-from jilles@FreeBSD.org) Received: (from jilles@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u07KmOqI038267; Thu, 7 Jan 2016 20:48:24 GMT (envelope-from jilles@FreeBSD.org) Message-Id: <201601072048.u07KmOqI038267@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jilles set sender to jilles@FreeBSD.org using -f From: Jilles Tjoelker Date: Thu, 7 Jan 2016 20:48:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r293359 - in head/bin/sh: . tests/builtins X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Jan 2016 20:48:26 -0000 Author: jilles Date: Thu Jan 7 20:48:24 2016 New Revision: 293359 URL: https://svnweb.freebsd.org/changeset/base/293359 Log: sh: Ensure OPTIND=1 in subshell without forking does not affect outer env. Command substitutions containing a single simple command and here-document expansion are performed in a subshell environment, but may not fork. Any modified state of the shell environment should be restored afterward. The state that OPTIND=1 had been done was not saved and restored here. Note that the other parts of shellparam need not be saved and restored, since they are not modified in these situations (a fork is done before such modifications). Added: head/bin/sh/tests/builtins/getopts10.0 (contents, props changed) Modified: head/bin/sh/eval.c head/bin/sh/tests/builtins/Makefile Modified: head/bin/sh/eval.c ============================================================================== --- head/bin/sh/eval.c Thu Jan 7 20:43:45 2016 (r293358) +++ head/bin/sh/eval.c Thu Jan 7 20:48:24 2016 (r293359) @@ -496,10 +496,12 @@ exphere(union node *redir, struct arglis struct jmploc *savehandler; struct localvar *savelocalvars; int need_longjmp = 0; + unsigned char saveoptreset; redir->nhere.expdoc = ""; savelocalvars = localvars; localvars = NULL; + saveoptreset = shellparam.reset; forcelocal++; savehandler = handler; if (setjmp(jmploc.loc)) @@ -514,6 +516,7 @@ exphere(union node *redir, struct arglis forcelocal--; poplocalvars(); localvars = savelocalvars; + shellparam.reset = saveoptreset; if (need_longjmp) longjmp(handler->loc, 1); INTON; @@ -647,6 +650,7 @@ evalbackcmd(union node *n, struct backcm struct jmploc jmploc; struct jmploc *savehandler; struct localvar *savelocalvars; + unsigned char saveoptreset; result->fd = -1; result->buf = NULL; @@ -661,6 +665,7 @@ evalbackcmd(union node *n, struct backcm if (is_valid_fast_cmdsubst(n)) { savelocalvars = localvars; localvars = NULL; + saveoptreset = shellparam.reset; forcelocal++; savehandler = handler; if (setjmp(jmploc.loc)) { @@ -671,6 +676,7 @@ evalbackcmd(union node *n, struct backcm forcelocal--; poplocalvars(); localvars = savelocalvars; + shellparam.reset = saveoptreset; longjmp(handler->loc, 1); } } else { @@ -681,6 +687,7 @@ evalbackcmd(union node *n, struct backcm forcelocal--; poplocalvars(); localvars = savelocalvars; + shellparam.reset = saveoptreset; } else { if (pipe(pip) < 0) error("Pipe call failed: %s", strerror(errno)); Modified: head/bin/sh/tests/builtins/Makefile ============================================================================== --- head/bin/sh/tests/builtins/Makefile Thu Jan 7 20:43:45 2016 (r293358) +++ head/bin/sh/tests/builtins/Makefile Thu Jan 7 20:48:24 2016 (r293359) @@ -95,6 +95,7 @@ FILES+= getopts6.0 FILES+= getopts7.0 FILES+= getopts8.0 getopts8.0.stdout FILES+= getopts9.0 getopts9.0.stdout +FILES+= getopts10.0 FILES+= hash1.0 hash1.0.stdout FILES+= hash2.0 hash2.0.stdout FILES+= hash3.0 hash3.0.stdout Added: head/bin/sh/tests/builtins/getopts10.0 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/bin/sh/tests/builtins/getopts10.0 Thu Jan 7 20:48:24 2016 (r293359) @@ -0,0 +1,11 @@ +# $FreeBSD$ + +set -- -x arg +opt=not +getopts x opt +r1=$? OPTIND1=$OPTIND opt1=$opt +: $(: $((OPTIND = 1))) +getopts x opt +r2=$? OPTIND2=$OPTIND +[ "$r1" = 0 ] && [ "$OPTIND1" = 2 ] && [ "$opt1" = x ] && [ "$r2" != 0 ] && + [ "$OPTIND2" = 2 ]