The following issue has been SUBMITTED. 
====================================================================== 
https://austingroupbugs.net/view.php?id=1602 
====================================================================== 
Reported By:                kre
Assigned To:                
====================================================================== 
Project:                    Issue 8 drafts
Issue ID:                   1602
Category:                   Shell and Utilities
Type:                       Omission
Severity:                   Objection
Priority:                   normal
Status:                     New
Name:                       Robert Elz 
Organization:                
User Reference:              
Section:                    XCU 2.14 exit   XCU 2.14 return 
Page Number:                2369, 2379 
Line Number:                76750, 77069 
Final Accepted Text:         
====================================================================== 
Date Submitted:             2022-08-23 16:33 UTC
Last Modified:              2022-08-23 16:33 UTC
====================================================================== 
Summary:                    No definition of "executed in a trap action"
Description: 
This defect report could also be filed against issue 7 TC2, and
probably earlier versions as well, but the wording has changed
so much in this area that going back to discuss text which has already
been altered seems pointless.   Hence filed against draft 2.1.

The wording of exit, when dealing with the case that no specific
status to use is given, is:

    If n is not specified, the result shall be as if n were specified
    with the current value of the special parameter '?' (see Section
2.5.2),
    except that when exit is executed in a trap action, the value for the
    special parameter '?' that is considered ``current'' shall be the
value
    it had immediately preceding the trap action.

The wording for return is substantially the same, though the effects, and
required interpretation, are different.

So, first to consider exit.   It seems likely (this requires some
guesswork)
that the idea here, is that when an EXIT trap (or others, will come to
those
soon) is executed, if the trap command says just "exit" - which will then
cause the shell to terminate, the status it terminates with should be the 
status that it would have exited with had there been no EXIT trap, and
the shell had simply exited.    That's fine, understandable, and the way
shells have behaved for a long time.

Doing the same for other traps is more likely just a "the way we run the
trap command is like this, so this is what happens" which is also OK,
though for the other traps actually depending upon this for anything is
kind of pointless, as the script writer can never know exactly where the
script will be when the trap needs to be taken, so the exit status would
be more or less random at that point.

That all seems good, but it is only meaningful because of the phrase I
included above (which is not anywhere in the standard), "which will then
cause the shell to terminate".    Consider an alternative use of exit:

cleanup() {
    # various stuff not relevant
    if (cd /somewhere || exit;  # cleanup stuff in /somewhere )
    then  # do some more cleanup stuff
    else  report cleanup failed, manual cleanup required
    fi
}

(Ignore the syntax error caused by the ')' being treated as part of
what is a comment, that comment would really be code in a real script).

and then

    trap 'echo Finishing; cleanup; exit' EXIT

(in which the exit is pointless, but makes for a better discussion).

Now assume that the code in the script, sometime later, does "exit 0"
That sets the status ($?) to 0, and then runs the EDIT trap before the
shell goes away.

There's no real question but that the wording in question applies to
exit that is in the string passed as the arg to the trap command, but
what about the one, executed in a subshell, in the cleanup function.

In that one, we may assume that perhaps the function was written long
ago, when no traps were being used, and the usage was

    cleanup; exit 0

that being a pattern (perhaps with different values for the exit status
throughout).   In that case, it is clear, the exception of being in a
trap action does not apply, there is none, and the exit in cleanup returns
the status of the the failed cd command (we know it failed, or the exit
would not being executed).    But then someone decided that it would be
cleaner to use an EXIT trap, remove all the calls to cleanup (perhaps
there
were some exit's in the code, rarely encountered, which had omitted the
cleanup, and that bug is being fixed).   Now cleanup is being executed in
a trap action.   That's clear.   But is the exit within the subshell
within
cleanup also "executed in a trap action" or only text that is actually in
the
trap action string?   If were were to decide that it is the latter, then
let's assume that instead of just returning, cleanup ended with "exit".
That one, not being in a sub-shell, would cause the shell to terminate.
But with what status, the status from the last command in cleanup() which
is likely what the author of that function intended, or the value of $?
that was current when the EXIT trap was taken?

We don't know, because nothing in the standard (or nothing I can find)
tells us.

For return, things get even messier.   That's because in general, return
is only defined when executed in a function.   Simply executing a random
"return" in a trap string (like was done with exit) is only meaningful if
we caqn guarantee that the trap will only fire while a function is
running.

That's certainly possible to do, but not all that common.   In practice
most 'return's that get executed are to return from a function which has
just been called.

That is
    func_performed=false
    func() {
        if $func_performed; then return; fi
        # perform whatever the function does
        func_performed=true
    }

In that func() will return 0 every time, the return will, as $? at
that point will be 0, because we know that $func_performed must have
been true or the return would not be being executed.

Now imagine that func() is called by some tree of function calls,
perhaps several times in different circumstanced.   The root of that
set of functions iis a function done() (not shown here).

If we were to now do  "trap done INT"

what does that mean to that return in func() - it has no impact at all
on the final value of $? when the trap action completes (that's controlled
by the done() function) and nothing here has any impact at all upon any
function that may have been executing when the trap occurred.   To do
that there would need to be a an explicit "return" in the trap string,
anything in any function that is called applies only to that function.

Is the return in func() now executed in a trap action, and so required to
return whatever status was in $? when the SIGINT trap occurred?   That
might not have been 0, so (depending upon how func() is used inn unshown
code,
might alter the execution flow in unexpected ways --- the commented code
from func() might even have "return N" for some N != 0, with the intent to
alter the flow - but the one shown was not planned to do that.

Again, we cannot answer that question, as the standard does not tell us
what "executed in a trap action" actually means.

Further there have been different interpretations of all of this, it isn't
(any longer anyway) simply a case of "well it is obvious, we just didn't
write
it down" as (some, at least one) shell authors have taken that wording,
and
actually made their shell do (what is really) absurd things, because of it
(when it had previously been sane).

There was a thread on the mailing list

   https://www.mail-archive.com/austin-group-l@opengroup.org/msg06011.html

in which this was briefly discussed, but none of the participants in
that discussion were people able to actually change the wording.

Hence this defect report, to force some attention by those who matter.
Desired Action: 
For exit, it should probably be "an exit command executed while a trap
action
is being performed, which will cause the shell environment executing the
trap action to terminate".

That's closer to what might be workable, but even that isn't perfect.

Given that exit & return need two quite different definitions, the
magic phrase should probably simply be deleted from the standard,
and replaced inline by the appropriate definition.

====================================================================== 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2022-08-23 16:33 kre            New Issue                                    
2022-08-23 16:33 kre            Name                      => Robert Elz      
2022-08-23 16:33 kre            Section                   => XCU 2.14 exit   XCU
2.14 return
2022-08-23 16:33 kre            Page Number               => 2369, 2379      
2022-08-23 16:33 kre            Line Number               => 76750, 77069    
======================================================================


  • [Issue 8 dra... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [Issue ... Austin Group Bug Tracker via austin-group-l at The Open Group

Reply via email to