Cygwin: pty: Fix Ctrl-C handling further for non-cygwin apps.

- The recent commit: "Cygwin: pty: Fix Ctrl-C handling for non-cygwin
  apps in background." causes the problem that cmd.exe is terminated
  by Ctrl-C even if it is running in pseudo console. This patch fixes
  the issue.
This commit is contained in:
Takashi Yano 2021-12-13 19:25:22 +09:00
parent 90788821b7
commit 8d8724ee1b
3 changed files with 40 additions and 1 deletions

View File

@ -2251,7 +2251,41 @@ fhandler_pty_master::write (const void *ptr, size_t len)
if ((ti.c_lflag & ISIG) && memchr (buf, '\003', nlen))
{
get_ttyp ()->kill_pgrp (SIGINT);
/* If the process is started with CREATE_NEW_PROCESS_GROUP
flag, Ctrl-C will not be sent to that process. Therefore,
send Ctrl-break event to that process here. */
DWORD wpid = 0;
winpids pids ((DWORD) 0);
for (unsigned i = 0; i < pids.npids; i++)
{
_pinfo *p = pids[i];
if (p->ctty == get_ttyp ()->ntty
&& p->pgid == get_ttyp ()->getpgid ()
&& (p->process_state & PID_NEW_PG))
{
wpid = p->dwProcessId;
break;
}
}
pinfo pinfo_resume = pinfo (myself->ppid);
DWORD resume_pid;
if (pinfo_resume)
resume_pid = pinfo_resume->dwProcessId;
else
resume_pid = get_console_process_id (myself->dwProcessId, false);
if (wpid && resume_pid)
{
WaitForSingleObject (pcon_mutex, INFINITE);
FreeConsole ();
AttachConsole (wpid);
/* CTRL_C_EVENT does not work for the process started with
CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT
instead. */
GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, wpid);
FreeConsole ();
AttachConsole (resume_pid);
ReleaseMutex (pcon_mutex);
}
if (!(ti.c_lflag & NOFLSH))
get_ttyp ()->discard_input = true;
}

View File

@ -274,6 +274,8 @@ enum
PID_NEW = 0x01000, /* Available. */
PID_ALLPIDS = 0x02000, /* used by pinfo scanner */
PID_PROCINFO = 0x08000, /* caller just asks for process info */
PID_NEW_PG = 0x10000, /* Process created with
CREATE_NEW_PROCESS_GROUOP flag */
PID_EXITED = 0x40000000, /* Free entry. */
PID_REAPED = 0x80000000 /* Reaped */
};

View File

@ -575,6 +575,9 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
c_flags |= CREATE_NEW_PROCESS_GROUP;
refresh_cygheap ();
if (c_flags & CREATE_NEW_PROCESS_GROUP)
myself->process_state |= PID_NEW_PG;
if (mode == _P_DETACH)
/* all set */;
else if (mode != _P_OVERLAY || !my_wr_proc_pipe)