On 22/08/2021 01:23, Harald van Dijk wrote:
On 22/08/2021 00:31, Roberto A. Foglietta wrote:
Il giorno sab 21 ago 2021 alle ore 23:33 Harald van Dijk <[email protected] <mailto:[email protected]>> ha scritto:
    I am also somewhat concerned that there may be cases where the global
    variables "doingtrap" and "recursive" are set, but evalstring() exits
    via raise_exception() and they are never cleared, preventing future ERR
    handlers from running. I do not currently have a test case where it
    matters, but am not convinced there are no test cases where it matters.
[...]
Obviously recursive should become a global variable.
When an exception is raised, what is going to happen? Exit?
In case of exit then it is not a problem, IMHO.

That's why I haven't been able to create a test case yet where it goes wrong: in *almost* all cases where an exception is raised, the shell will terminate. The shell won't immediately terminate, EXIT handlers run first, but if that runs in the context of an ERR handler, leaving doingtrap and recursive alone is the right thing to do, as ERR handlers shouldn't run again.

But only almost all cases, not all cases. One exception, and I am not sure if it is the only one, is that the 'command' builtin can catch and handle exceptions that come from errors raised by special built-ins. Normally they cause the shell to terminate, but the 'command' built-in makes such errors non-fatal.

If it is possible for a special built-in within an ERR handler to raise an exception, and for that exception to be caught and handled by an outer 'command' builtin, it should be possible to run more ERR handlers after that.

And I have now managed to construct a test case for exactly that:

  trap ")" ERR
  command eval false
  trap "echo ERR" ERR
  echo still running
  false

This is obviously a perverse example, perhaps someone else can tweak it into something reasonable, but it demonstrates the problem either way.

This prints:

  ash: eval: line 2: syntax error: unexpected ")"
  still running

And then exits with status 1.

This demonstrates that the 'false' command at the end was invoked, and should have resulted in the ERR handler that prints 'ERR' getting invoked as well, but because the earlier ERR handler invocation failed because of the syntax error, and the syntax error was made nonfatal because of the 'command' builtin, the earlier ERR handler invocation was never cleaned up properly. This leaves the shell in a state where no ERR handler can ever run again.
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to