NetBSD Problem Report #56491

From kre@munnari.OZ.AU  Tue Nov  9 15:16:12 2021
Return-Path: <kre@munnari.OZ.AU>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 62C961A9239
	for <gnats-bugs@gnats.NetBSD.org>; Tue,  9 Nov 2021 15:16:12 +0000 (UTC)
Message-Id: <202111091516.1A9FG6qE003112@jinx.noi.kre.to>
Date: Tue, 9 Nov 2021 22:16:06 +0700 (+07)
From: kre@munnari.OZ.AU
To: gnats-bugs@NetBSD.org
Subject: /bin/sh hash command "hash foobar" says foobar not found, and exit(0)
X-Send-Pr-Version: 3.95

>Number:         56491
>Category:       bin
>Synopsis:       /bin/sh hash command "hash foobar" says foobar not found, and exit(0)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kre
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Nov 09 15:20:01 +0000 2021
>Closed-Date:    Tue Nov 16 11:49:56 +0000 2021
>Last-Modified:  Tue Nov 16 11:49:56 +0000 2021
>Originator:     Robert Elz
>Release:        NetBSD 9.99.88
>Organization:
>Environment:
System: NetBSD jinx.noi.kre.to 9.99.88 NetBSD 9.99.88 (1.1-20210916) #60: Thu Sep 16 23:18:32 UTC 2021 root@agate.noi.kre.to:/usr/obj/HEAD/kernels/amd64/JINX amd64
Architecture: x86_64
Machine: amd64
>Description:
	The hash builtin utiliity in /bin/sh when run naming a utility
	to be added to the hash table, and the utility is not found,
	writes an error message to stderr indicating that the utility
	was not found, but goes on to exit(0).

	POSIX (for most standard utilities, including this one) specifies that
	when stderr is used, the utility must not exit(0) (sometimes more
	specific exit status conditions, but never 0 in that case.

	It isn't clear (yet) whether the correct fix is to exit(1) when
	a utility was not found, or to suppress the error message.

	All ksh variants simply ignore "not found" - no error message,
	and the exit status is 0.   All other (known and relevant) shells
	(bash dash, freebsd, yash, zsh, bosh) write an error message,
	and eventually exit(1).

>How-To-Repeat:
	Assuming there is o foobar command in any directory in PATH

		hash foobar
		echo $?

>Fix:
	TBD (either way is a trivial change).

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: bin-bug-people->kre
Responsible-Changed-By: kre@NetBSD.org
Responsible-Changed-When: Tue, 09 Nov 2021 15:21:44 +0000
Responsible-Changed-Why:
Mine.


From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/56491: /bin/sh hash command "hash foobar" says foobar not found, and exit(1)
Date: Sun, 14 Nov 2021 08:41:20 +0700

 For this (see the original PR for the details) I am considering having
 the best of all worlds (since it is so simple - the change is truly trivial).

 That is, make the default be like bash/dash/ ... (everything
 not a ksh variant) which makes "hash foobar" generate an error
 just like now, but will exit 1 instead of 0 if any command to
 be added to the hash table is not found.   That takes adding
 one test to see if the command was found, and making the return
 value be a variable rather than const 0.

 Then add a -e option (no errors) to make it work the ksh way,
 which means suppressing the error message (one arg to the lookup
 routine changes value), and continue to exit(0).

 And since all this is so easy, add a -q (quiet) option which will
 suppress the "not found" error message, but still result in an
 exit(1) in the case that a command named was not found.  This is
 similar to hash command 2>/dev/null except that any other errors would
 still appear on stderr, only the "command not found" would be skipped.

 Then, just because it is so simple, make -e invert the sense of
 whatever -q gets set to, then use just -q to decide whether to suppress
 the error message internally (and -e just for the exit status).
 This makes hash -e do what we want (-q is implicitly set to suppress
 the error), and hash -eq return to what NetBSD "hash" command has been
 doing forever (generate the not found error message (as -q gets inverted
 by -e), but exit(0)).   I don't see this being very useful, but it does
 provide a backwards compat variant, and is cost free.

 The most difficult part of all of this is the man page update - and not to
 document these new options, but, to document the other options that the
 hash command has had for quite a while now, but never got documented.

 Any comments before I commit this?

 kre


From: "Robert Elz" <kre@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/56491 CVS commit: src/bin/sh
Date: Tue, 16 Nov 2021 11:28:29 +0000

 Module Name:	src
 Committed By:	kre
 Date:		Tue Nov 16 11:28:29 UTC 2021

 Modified Files:
 	src/bin/sh: exec.c sh.1

 Log Message:
 PR bin/56491

 Make "hash" exit(!=0) (ie: exit(1)) if it writes an error message to
 stderr as required by POSIX (it was writing "not found" errors, yet
 still doing exit(0)).

 Whether, when doing "hash foobar", and "foobar" is not found as a command
 (not a built-in, not a function, and not found via a PATH search), that
 should be considered an error differs between shells.  All of the ksh
 descendant shells say "no", write no error message in this case, and
 exit(0) if no other errors occur.   Other shells (essentially all) do
 consider it an error, write a message to stderr, and exit(1) when this happens.

 POSIX isn't clear, the bug report:
      https://austingroupbugs.net/view.php?id=1460
 which is not yet resolved, suggests that the outcome will be that
 this is to be unspecified.   Given the diversity, there might be no
 other choice.

 Have a foot in both camps - default to the "other shell" behaviour,
 but add a -e option (no errors ... applies only to these "not found"
 errors) to generate the ksh behaviour.   Without other errors (like an
 unknown option, etc) "hash -e anyname" will always exit(0).

 See the PR for details on how it all works now, or read the updated man page.

 While here, when hash is in its other mode (reporting what is in the
 table) check for I/O errors on stdout, and exit(1) (with an error
 message!) if any occurred.   This does not apply to output generated
 by the -v option when command names are given (that output is incidental).

 In sh.1 document all of this.   Also add documentation for a bunch of
 other options the hash command has had for years, but which were never
 documented.   And while there, clean up some other sections I noticed
 needed improving (either formatting or content or both).


 To generate a diff of this commit:
 cvs rdiff -u -r1.56 -r1.57 src/bin/sh/exec.c
 cvs rdiff -u -r1.236 -r1.237 src/bin/sh/sh.1

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: kre@NetBSD.org
State-Changed-When: Tue, 16 Nov 2021 11:49:56 +0000
State-Changed-Why:
Problem fixed


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.