Skip to content

[busybox] alias should probably disable interrupts #140

Closed
@avih

Description

@avih

While using my own cmd.exe wrapper to $COMSPEC (as a workaround for the autotools cmd //c ... issue), I noticed that ctrl-c interrupts the wrapper but not the wrapped cmd.exe, which results in the wrapper exiting while $COMSPEC keeps running (at least when launching cmd.exe in interactive mode).

This is bad, because the calling process which invoked the wrapper thinks it's done, while in fact the wrapee keeps running.

A ctrl-c event is dispatched to all the processes attached to the current console, and not only to the current "foreground" process.

I don't have an explicit test case for any of the existing aliases in w64dk (either to busybox.exe or the other utils), but I'm pretty sure it can happen.

One case comes to mind which doesn't necessarily exit immediately on ctrl-c is make (specifically if using mingw32-make.exe which is an alias), at which case the alias can exit while make is still running, which is bad, for instance because its output prints while ash is back at the prompt (if invoked from an interactive sh).

Another such case could be interactive (busybox) sh.

Symptoms of such case is "shell limbo" where, after ctrl-c terminated the alias but not the wrapee, key presses go both to the wrapee and to the shell, but in a weird way and neither is functional until something kills the wrapee manually from elsewhere.

I don't know for a fact that the w64dk [busybox] alias suffer from this, but I think it does because I don't identify at the code any measures to handle this case.

To solve it, in my cmd.exe wrapper I initially used SetConsoleCtrlHandler(NULL, TRUE) which is dcumented as:

If the HandlerRoutine parameter is NULL, a TRUE value causes the calling process to ignore CTRL+C input, and a FALSE value restores normal processing of CTRL+C input. This attribute of ignoring or processing CTRL+C is inherited by child processes.

However, this has two bad issues:

  1. As documented, it's inheritable, which means that the wrapee would not be interruptible with ctrl-c unless tey explicitly set a handler of their own - which many apps don't do (but cmd.exe specifically apparently does).
  2. It only handles ctrl-c, but not other signals, like ctrl-break (on some KB ctrl-pause), so ctrl-break also exits the wrapper but not the wrapee (at least with cmd.exe wrapper).

The solution, apparently is to use an actual handler instead of NULL, similar to this:

BOOL WINAPI sighandler(DWORD dwCtrlType)
{
    return TRUE;
}

In my tests this indeed disables ctrl-c and ctrl-break from killing the wrapper, while not affecting the wrapee. I.e. the wrapee by default is still interruptible normally.

Consequently, the wrapper exits if and only if the wrapee exits, after WaitForSingleObjects and using an explicit exit.

This specific handler ignores all control events, which include, in addition to ctrl-c and ctrl-break, also close-window, logoff (of some unspecified user), and shutdown (supposedly only to services).

I think that's OK, because according to the docs, after CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, or CTRL_SHUTDOWN_EVENT, the process would be killed regardless if the handler returned TRUE or FALSE, so it's only an opportunity for cleanup before returning.

FYI.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions