Skip to content

Commit df8884c

Browse files
committed
Merge branch 'ctrl-c'
This is part two of the Ctrl+C story, where part one is git-for-windows/MSYS2-packages@f4fda0f30aa. Part one took care of extending the signal handling in the MSYS2 runtime such that non-MSYS2 processes "receive" a SIGINT by injecting a remote thread that runs kernel32!CtrlRoutine as if GenerateConsoleCtrlHandler() had been called (but in contrast to the latter, only one process is targeted at a time, not every process attached to the same Console) into the process that needs to be interrupted as well as into all of the spawned child processes. Part two now takes care of removing the misguided "kill all spawned children" atexit() handler, and it also installs a ConsoleCtrl handler to run Git's SIGINT handlers, such as the one waiting for the pager to exit. Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 20d8479 + 1cbdbd7 commit df8884c

File tree

1 file changed

+13
-45
lines changed

1 file changed

+13
-45
lines changed

compat/mingw.c

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,39 +1528,6 @@ struct pinfo_t {
15281528
static struct pinfo_t *pinfo = NULL;
15291529
CRITICAL_SECTION pinfo_cs;
15301530

1531-
#ifndef SIGRTMAX
1532-
#define SIGRTMAX 63
1533-
#endif
1534-
1535-
static void kill_child_processes_on_signal(void)
1536-
{
1537-
DWORD status;
1538-
1539-
/*
1540-
* Only continue if the process was terminated by a signal, as
1541-
* indicated by the exit status (128 + sig_no).
1542-
*
1543-
* As we are running in an atexit() handler, the exit code has been
1544-
* set at this stage by the ExitProcess() function already.
1545-
*/
1546-
if (!GetExitCodeProcess(GetCurrentProcess(), &status) ||
1547-
status <= 128 || status > 128 + SIGRTMAX)
1548-
return;
1549-
1550-
EnterCriticalSection(&pinfo_cs);
1551-
1552-
while (pinfo) {
1553-
struct pinfo_t *info = pinfo;
1554-
pinfo = pinfo->next;
1555-
if (exit_process(info->proc, status))
1556-
/* the handle is still valid in case of error */
1557-
CloseHandle(info->proc);
1558-
free(info);
1559-
}
1560-
1561-
LeaveCriticalSection(&pinfo_cs);
1562-
}
1563-
15641531
static int is_msys2_sh(const char *cmd)
15651532
{
15661533
if (cmd && !strcmp(cmd, "sh")) {
@@ -1593,7 +1560,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
15931560
const char *dir, const char *prepend_cmd,
15941561
int fhin, int fhout, int fherr)
15951562
{
1596-
static int atexit_handler_initialized, restrict_handle_inheritance = 1;
1563+
static int restrict_handle_inheritance = 1;
15971564
STARTUPINFOEXW si;
15981565
PROCESS_INFORMATION pi;
15991566
LPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL;
@@ -1609,17 +1576,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
16091576
const char *(*quote_arg)(const char *arg) =
16101577
is_msys2_sh(*argv) ? quote_arg_msys2 : quote_arg_msvc;
16111578

1612-
if (!atexit_handler_initialized) {
1613-
atexit_handler_initialized = 1;
1614-
/*
1615-
* On Windows, there is no POSIX signaling. Instead, we inject
1616-
* a thread calling ExitProcess(128 + sig_no); and that calls
1617-
* the *atexit* handlers. Catch this condition and kill child
1618-
* processes with the same signal.
1619-
*/
1620-
atexit(kill_child_processes_on_signal);
1621-
}
1622-
16231579
do_unset_environment_variables();
16241580

16251581
/* Determine whether or not we are associated to a console */
@@ -3338,6 +3294,14 @@ static void adjust_symlink_flags(void)
33383294

33393295
}
33403296

3297+
static BOOL handle_ctrl_c(DWORD ctrl_type)
3298+
{
3299+
if (ctrl_type != CTRL_C_EVENT)
3300+
return FALSE; /* we did not handle this */
3301+
mingw_raise(SIGINT);
3302+
return TRUE; /* we did handle this */
3303+
}
3304+
33413305
#if defined(_MSC_VER)
33423306

33433307
#ifdef _DEBUG
@@ -3376,6 +3340,8 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
33763340
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
33773341
#endif
33783342

3343+
SetConsoleCtrlHandler(handle_ctrl_c, TRUE);
3344+
33793345
fsync_object_files = 1;
33803346
maybe_redirect_std_handles();
33813347
adjust_symlink_flags();
@@ -3444,6 +3410,8 @@ void mingw_startup(void)
34443410
wchar_t **wenv, **wargv;
34453411
_startupinfo si;
34463412

3413+
SetConsoleCtrlHandler(handle_ctrl_c, TRUE);
3414+
34473415
fsync_object_files = 1;
34483416
maybe_redirect_std_handles();
34493417
adjust_symlink_flags();

0 commit comments

Comments
 (0)