This is a proof of concept demonstration which makes Ctrl-C behave in a way a lot of people expect concerning non-Cygwin console programs.
What it does actually is it generates CTRL_BREAK_EVENT with Windows Console API GenerateConsoleCtrlEvent on the arrival of SIGINT. And to make this scheme to be functional it is required to specify CREATE_NEW_PROCESS_GROUP when creating new non-Cygwin processes. To my surprise there seem to be no way to generate CTRL_C_EVENT using API. I must also point out that virtually all of the terminal emulators are sneakily keeping hidden Windows Console in the background. Thus several features of the Windows Console is still available to processes running in the cygwin environment. One of such features is this 'process group' and the other one is 'code page' which you manipulate with chcp.com utility. Following is a bunch of random posts, I picked up from this list, talking about the same topic. Ordered by its significance under my judge. These should help you understand (or remind) what it is about. Date: Mon, 04 Dec 2006 06:24:41 -0800 Subject: Re: Ctrl-C and non-cygwin programs http://cygwin.com/ml/cygwin/2006-12/msg00151.html Date: Thu, 20 May 2010 22:50:49 +0000 (UTC) Subject: A workaround for CTRL-C not working on Windows console apps in ptys http://sourceware.org/ml/cygwin/2010-05/msg00524.html Date: Mon, 19 Jan 2009 11:41:51 -0500 Subject: Signal handling in WIN32 console programs http://sourceware.org/ml/cygwin/2009-01/msg00587.html Date: Fri, 24 Aug 2001 17:25:14 -0400 Subject: control-c issue when running VC++ console programs in bash.exe http://cygwin.com/ml/cygwin/2001-08/msg01111.html As you can see this is a haunting problem and the situation hasn't changed a bit over this past decade. At least please let this issue be added to the FAQ. I believe this patch is fairly small and worth giving a field test. Lastly first third of the patch is a workaround of a problem observed with cygwin1.dll of cvs HEAD. To reproduce: 1. Launch a terminal emulator like rxvt or mintty. 2. Execute cmd.exe or more.com from shell prompt. 3. Type in Enter, Ctrl-C, then Enter again. Whole processes including the terminal emulator will just hung up. --- ChangeLog for winsup/cygwin: 2012-03-28 Ein Terakawa <[email protected]> * exceptions.cc: (sigpacket::process) Do not sigflush in response to SIGINT for a non-Cygwin process to work around hung-up. Translate SIGINT into CTRL_BREAK_EVENT for a non-Cygwin process. * spawn.cc: (child_info_spawn::worker) CREATE_NEW_PROCESS_GROUP for each new non-Cygwin process. --- Index: winsup/cygwin/exceptions.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/exceptions.cc,v retrieving revision 1.375 diff -c -p -r1.375 exceptions.cc *** winsup/cygwin/exceptions.cc 12 Feb 2012 22:43:33 -0000 1.375 --- winsup/cygwin/exceptions.cc 28 Mar 2012 14:39:58 -0000 *************** sigpacket::process () *** 1166,1171 **** --- 1166,1174 ---- switch (si.si_signo) { case SIGINT: + if (have_execed) + break; + /* fall through */ case SIGQUIT: case SIGSTOP: case SIGTSTP: *************** sigpacket::process () *** 1252,1257 **** --- 1255,1266 ---- if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU) goto stop; + if (si.si_signo == SIGINT && have_execed) + { + GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, GetProcessId(ch_spawn)); + goto done; + } + goto exit_sig; } Index: winsup/cygwin/spawn.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/spawn.cc,v retrieving revision 1.329 diff -c -p -r1.329 spawn.cc *** winsup/cygwin/spawn.cc 21 Mar 2012 15:54:50 -0000 1.329 --- winsup/cygwin/spawn.cc 28 Mar 2012 14:39:58 -0000 *************** child_info_spawn::worker (const char *pr *** 573,579 **** cygbench ("spawn-worker"); if (!real_path.iscygexec()) ! ::cygheap->fdtab.set_file_pointers_for_exec (); moreinfo->envp = build_env (envp, envblock, moreinfo->envc, real_path.iscygexec ()); --- 573,582 ---- cygbench ("spawn-worker"); if (!real_path.iscygexec()) ! { ! ::cygheap->fdtab.set_file_pointers_for_exec (); ! c_flags |= CREATE_NEW_PROCESS_GROUP; ! } moreinfo->envp = build_env (envp, envblock, moreinfo->envc, real_path.iscygexec ());
