Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001321 [1003.1(2016/18)/Issue7+TC2] Shell and Utilities Objection Error 2020-01-29 15:36 2020-05-19 11:05
Reporter geoffclare View Status public  
Assigned To
Priority normal Resolution Accepted  
Status Applied  
Name Geoff Clare
Organization The Open Group
User Reference
Section false
Page Number 2778
Line Number 91221
Interp Status ---
Final Accepted Text
Summary 0001321: exit status for false should be 1-125
Description The exit status of the false utility is simply required to be non-zero.
This means applications have no way of distinguishing between a normal
exit of this utility and the special exit statuses, greater than or
equal to 126, used for "not found", "can't be executed" or "terminated
by a signal" conditions.
Desired Action Change:
The false utility shall always exit with a value other than zero.
to:
The false utility shall always exit with a value between 1 and 125, inclusive.
Tags issue8
Attached Files

- Relationships
related to 0001229Applied EXIT_FAILURE should not be allowed to be all non-zero values 

-  Notes
(0004745)
shware_systems (reporter)
2020-01-29 16:17

To go with this, should there be a similar limitation on EXIT_FAILURE, as a CX extension, in <stdlib.h>? Then it could be required false return EXIT_FAILURE, as a symbolic rather than arbitrary value.
(0004746)
geoffclare (manager)
2020-01-29 16:40

The corresponding EXIT_FAILURE change is in bug 0001229.
(0004747)
shware_systems (reporter)
2020-01-29 17:06
edited on: 2020-01-29 17:35

So it is, my bad for forgetting. I'd then prefer the change to be:
  The false utility shall exit with the return value equivalent to EXIT_FAILURE in <stdlib.h>.

(0004748)
kre (reporter)
2020-01-29 18:58

I think this is perhaps not really needed. All that matters for false is
that its exit status not be 0, that's why it is used. Why it isn't 0 is
immaterial, as is which value it uses.

If we happen to get a "command not found" from some shell where false isn't
built in, and the PATH doesn't include it, so what? Whatever script is being
run still runs the same, just perhaps with an extra "command not found"
diagnostic thrown in. If false does exit(127) which looks just the same,
but without the diagnostic, does it matter?

Is there any known script that actually checks the exit status after invoking
false, to determine if there was some exec failure of one kind of another?

If not, perhaps this is simply make work?
(0004749)
stephane (reporter)
2020-01-29 19:50

Re: Note: 0004748

> Is there any known script that actually checks the exit status after invoking
false, to determine if there was some exec failure of one kind of another?

We sometime see wrapper scripts like:

#! /bin/sh -

# some setup code
# ...

# run command passed as arguments:
"$@"; ret=$?

# some cleanup code

if [ "$ret" -gt 128 ] # only way to tell the command may have been killed
                      # with the current API
then
  sig=$(kill -l "$ret")

  trap : "$sig"   # in case the shell is zsh

  trap - "$sig"   # restore default disposition, unfortunately doesn't work
                  # if the signal was ignored on start with POSIX
                  # compliant shells. In zsh, can be worked around by setting
                  # a handler first, hence the previous line.

  kill -s "$sig" "$$" # report the same death by signal to caller if possible
fi
exit "$ret" # also fallback if kill failed to kill us above


More generally, one should avoid to exit with codes above 127 except to report some death by signal.
(0004750)
kre (reporter)
2020-01-29 20:27

I agree in general with what is in Note: 0004749 but do remember that the
subject here is false, not commands in general.

When was the last time you wrote code to test if false was killed by a
signal? When was the last time you ever saw false killed by a signal?

We all know that what false actually does is (nominally) exit(1), and in
reality simply sets the interval variable that becomes $? to 1 - but I'm
not sure there is any particularly good reason for the standard to require that.
(0004751)
stephane (reporter)
2020-01-29 21:12

Re: Note: 0004750

> When was the last time you wrote code to test if false was killed by a
> signal? When was the last time you ever saw false killed by a signal?

You'll note in my example, the command was "$@", so any arbitrary command as invoked by the user.

I often use true or false at the end of my scripts or functions for them to report a true or false exit status. I wouldn't want that false invocation to report "command not found" or "killed by SIGINT".
(0004752)
stephane (reporter)
2020-01-29 21:17

And no, I've never come across a "false" implementation that reported anything other than "1" when terminating normally and I wouldn't object to POSIX requiring it. Something like:

Exits with code 1, and >1 when an error occurred (bad option, stack overflow detection, killed by signal...)
(0004753)
shware_systems (reporter)
2020-01-29 22:23
edited on: 2020-01-29 22:32

Re: 4748

To me it does matter as a portability consideration. As written a simplistic implementation of false could be:
#include <stdlib.h>
main() { return !EXIT_SUCCESS; }

as meeting the requirements, but when masked to 8 bits is the value 255. Requiring { return EXIT_FAILURE; } homogenizes $? with what the standard already provides to indicate non-true as an exit code.

(0004754)
Don Cragun (manager)
2020-01-29 22:39

Re Note: 0004753:

Sorry Mark, but no. The ! operator in C is a logical operator returning 0 or 1. It is not a bitwise operator. According to the C Standard:
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).
(0004755)
shware_systems (reporter)
2020-01-29 22:46
edited on: 2020-01-29 22:47

It was off top of head, sorry. Make it ~EXIT_SUCCESS for the bitwise one, as intended, and I believe argument holds.

(0004756)
stephane (reporter)
2020-01-30 08:17

Re: Note: 0004755

that's not what exit status are. There's not just booleans. Values have or can have meanings. Again, values above 128 should be avoided as they can be interpreted as death by signal by shell scripts; 255 is a special case for xargs (causes xargs cmd to abort when one run of cmd exits with that code).

Also, exiting with values above 255 yields undefined/unspecified results in many things. For instance, I'd expect most xargs implementations still use waidpid(), so that exit(-1) would be taken as exit(255) by them, but that would no longer be the case when they switch to waitid() on those system that preserve the full integer passed to exit() (as POSIX now requires, but not all systems do yet).

expr, test, grep are examples of utilities that return boolean meanings (false/true). They're all required to report "false" as 1 (and 2 or above for errors). It would make a lot of sense if that was the case for the "false" utility as well.
(0004757)
shware_systems (reporter)
2020-01-30 08:51

I agree, but with the current wording ~0 as masked by exit() is a non-zero value that would have to be considered as conforming, even though it could also be a signo 127 too. The point was that some change is warranted, as the de facto intent is "any non-zero unsigned char value not reserved for other purposes by the shell", and EXIT_FAILURE is required to be such a value so may as well be reused.
(0004758)
joerg (reporter)
2020-01-30 10:27
edited on: 2020-01-30 10:29

I am not sure whether this is known, but /usr/bin/false from Solaris uses the exit code 255.

BTW: exit() does not mask the exit code. The only place that masks the exit code is wait(), when you decide to use the outdated wait() interface. But then the exit code is masked in wait() and not in exit(), since waitid() returns the full int.

call this:

main()
{
   exit(~0);
}

and with "echo $/ $?", you get:

-1 255

if you use a shell that already supports the $/ proposal from Don Cragun, that can be tested on bosh.

exit(256) is a problem , as "echo $/ $?" prints:

256 0

(0004759)
joerg (reporter)
2020-01-30 10:37
edited on: 2020-01-30 10:46

Re: Note: 0004749

sleep 10
^C
# echo $/ $?
INT 130

There is a way to distinguish if you use a shell that listens to what we discuss here ;-)


joerg> bla
bla: nicht gefunden
joerg> echo $/ $?
NOTFOUND 127

joerg> ./
./: Ausführen nicht möglich
joerg> echo $/ $?
NOEXEC 126


See Bugs: 0001026 and 0000947

(0004760)
kre (reporter)
2020-01-30 11:45

One last note:

If there was some plan to prescribe that all portable applications must
exit with a status between 0 (indicating success) and 125 (those other 125
values indicating various possible failure modes, as defined for each
application) I would understand the motivation behind the change suggested
here.

I also expect that there would be extreme pushback against any such plan.

Without that, I cannot see how false should be held to a standard that is
not elsewhere required - the arguments for it all relate much more to other
applications that false, which is, in practice, never not found (or not
executable), never interrupted by a signal, and has zero error conditions.

That is the standard false from XCU section 4. (Things like /bin/false
or whatever, might be different, but those are not what this would apply to).

In this way false is different from egrep/test/expr/... in that those have
a need to report more than one "failed" condition (for egrep, pattern not
found, or syntax error in pattern. or failed to open a named file). False
doesn't need any of that.

A non-zero (or if you insist, a non-zero when only the low 8 bits are
considered) exit code is all that matters for it.

But my original point was that this looked like make-work ... there's nothing
inherently wrong (whatever Solaris implementations do) with requiring false
to exit with status 1. There's just no need for it. In the past day or
so we have already expended far more time and effort on this than can
possibly be justified by any result that could be achieved.
(0004761)
stephane (reporter)
2020-01-30 15:35

Re: Note: 0004758
> I am not sure whether this is known, but /usr/bin/false from Solaris uses the exit code 255

Indeed, I hadn't checked standalone false utilities except GNU false (which processes options as allowed by POSIX, to check what happened if you passed an unknown option).

And indeed on Solaris:

$ echo a b | xargs -n1 csh -c 'echo $1:q; false'
a
xargs: Command could not continue processing data


While on all other OSes I've tried (GNU, NetBSD, FreeBSD):

$ echo a b | xargs -n1 csh -c 'echo $1:q; false'
a
b


I guess I should stop using "false" in portable scripts to report a false" status, or redefine it as:

false() { return 1; }


To avoid that potential issue if we can't guarantee false will return with a non-problematic exit code.

- Issue History
Date Modified Username Field Change
2020-01-29 15:36 geoffclare New Issue
2020-01-29 15:36 geoffclare Name => Geoff Clare
2020-01-29 15:36 geoffclare Organization => The Open Group
2020-01-29 15:36 geoffclare Section => false
2020-01-29 15:36 geoffclare Page Number => 2778
2020-01-29 15:36 geoffclare Line Number => 91221
2020-01-29 15:36 geoffclare Interp Status => ---
2020-01-29 16:17 shware_systems Note Added: 0004745
2020-01-29 16:40 geoffclare Note Added: 0004746
2020-01-29 16:40 geoffclare Relationship added related to 0001229
2020-01-29 17:06 shware_systems Note Added: 0004747
2020-01-29 17:35 shware_systems Note Edited: 0004747
2020-01-29 18:58 kre Note Added: 0004748
2020-01-29 19:50 stephane Note Added: 0004749
2020-01-29 20:27 kre Note Added: 0004750
2020-01-29 21:12 stephane Note Added: 0004751
2020-01-29 21:17 stephane Note Added: 0004752
2020-01-29 22:23 shware_systems Note Added: 0004753
2020-01-29 22:32 shware_systems Note Edited: 0004753
2020-01-29 22:39 Don Cragun Note Added: 0004754
2020-01-29 22:46 shware_systems Note Added: 0004755
2020-01-29 22:47 shware_systems Note Edited: 0004755
2020-01-30 08:17 stephane Note Added: 0004756
2020-01-30 08:51 shware_systems Note Added: 0004757
2020-01-30 10:27 joerg Note Added: 0004758
2020-01-30 10:28 joerg Note Edited: 0004758
2020-01-30 10:29 joerg Note Edited: 0004758
2020-01-30 10:37 joerg Note Added: 0004759
2020-01-30 10:38 joerg Note Edited: 0004759
2020-01-30 10:39 joerg Note Edited: 0004759
2020-01-30 10:43 joerg Note Edited: 0004759
2020-01-30 10:46 joerg Note Edited: 0004759
2020-01-30 10:46 joerg Note Edited: 0004759
2020-01-30 10:46 joerg Note Edited: 0004759
2020-01-30 10:46 joerg Note Edited: 0004759
2020-01-30 11:45 kre Note Added: 0004760
2020-01-30 15:35 stephane Note Added: 0004761
2020-04-30 16:34 Don Cragun Status New => Resolved
2020-04-30 16:34 Don Cragun Resolution Open => Accepted
2020-04-30 16:34 Don Cragun Tag Attached: issue8
2020-05-19 11:05 geoffclare Status Resolved => Applied


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker