Date:        Sun, 19 Apr 2020 17:12:42 +0900
    From:        Koichi Murase <myoga.mur...@gmail.com>
    Message-ID:  
<CAFLRLk-iJA+W0VifuzxwT=rthpmu+gaq-vnztsb8df0jga1...@mail.gmail.com>

  | Currently, I do not see any rationale for the behavior (B) or (C).

Before I make any other comments, I should point out that quite a bit
of what is in the shell standard (and the rest of POSIX, and for that
matter, many other standards) isn't there because there's a good reason
for it, but just because the original shells implemented it that way,
often for expediency purposes (the original Bourne shell had to run in
the 64KB address space (code, data, and stack) of a PDP-11).

So that's not really a meaningfull question to ask in this context,
the standard might very well require something totally irrational,
simply because that is how it has been implemented.

If something is implemented a particular way, applications (scripts)
may come to depend upon it, so changing it later can be difficult.

All that aside, I agree that the wording in the standard is ambiguous.

My first reading (my immediate impression) is that your interpretation A
is what is intended, and only a return command executing directly from the
trap action itself, and not one in a function that happens to be called,
should be affected.   (And of course, the former is only specified if the
trap occurs while running a function or dot script).

That is, with code like

        long_func() {
                t=$(trap -p)
                trap 'eval "$T"; return' INT
                while sleep 10
                do
                        printf .
                done
        }

That is, it should not apply in functions called from a trap action,
for them, return should act just like it would in a function called
from any other source.

Note that another intrepretation that you didn't list is that this magic
return applies to return in functions called directly from the trap action
string (which are more likely to be functions written expressly with the
intent of being called this way) but not to functions called indirectly.

Next thing to note is that all of this wording is to be changed in the
next version of the standard - there's no longer any "exit status of the
last command" stuff for return (or exit), rather these are to be specified
to return the value of $? when no arg is given.

When we do that, all we need to do is specify how traps affect $?, which
should be (IMO), on entry, $? is the status of the last command (ie: starting
a trap action changes nothing wrt $? - it holds the same value it would have
had if there were no trap action called, and the next command simply started.

On return from a trap action to the command that would have been executed
next, had no trap action intervened, the exit status should be retained at
the same value it had before the trap action was executed (the trap should
not alter $?).

If a trap action causes the control flow to be altered (that is, by
executing a return/exit/break/continue outside of a context that is local
to the trap action) then the exit status should be whatever the trap
action causes to happen (that of the last command executed there).

But that I believe this is the most appropriate specification does not
mean that is what can go into the standard, that depends upon what the
implementations actually do - and as there seems to be a diversity of
implementations (including as to what is the command before the trap,
when the trap is caused by a kill ... and possibly for async signals as
well - some shells seem to use the status of the command before the kill
command as the relevant one (that would be the status of the last command
executed before the signal arrived), even though the standard is clear that
the trap action cannot be run while a foreground command is running.   Here
the trap cannot run before the kill command starts (it is that which sends
the signal) and assuming it is run in foreground, that means not until
after the kill command completes, which means $? should be the status from 
he kill command.   But some shells seem to run the trap action with $? being
the status of the commane before the kill command (which would be the
value of $? when the signal arrived).

The end result, unless we can get agreement that some implementations are
buggy, and will be fixed (which given the split seems an unlikely outcome)
is likely to simply be that all of this simply becomes unspecified (or
perhaps we could hope, implementation defined) which will mean even more
cases where it becomes more difficult to write portable reliable code.

kre



Reply via email to