Anonymous | Login | 2024-09-07 14:57 UTC |
Main | My View | View Issues | Change Log | Docs |
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 | 2024-06-11 09:08 | ||
Reporter | geoffclare | View Status | public | ||||
Assigned To | |||||||
Priority | normal | Resolution | Accepted | ||||
Status | Closed | ||||||
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 | ||||||
|
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. |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |