Control-C (CTRL+C) key combinations sends special signal to console processes, when a console window has the keyboard focus. By default Control-C (also Control-Break) signal is treated not as keyboard input but aborts all console processes attached to this console. In GUI applications Control-C is treated differently and usually is used to copy highlighted text or image to clipboard.
However console application may intercepts Control-C signal to process it differently than process interruption.
The first example shows how to capture Control-C signal in C++ Linux code. When application is started without argument the special Control-C processing is off. It application has at least on argument Control-C signal is captured and processed by CustomCtrlC function. The source code:
#include <stdio.h> #include <signal.h> void CustomCtrlC(int nSignal); int main(int n, char ** s) { if(n>1) { // Custom ctrl-c processing printf("Custom Ctrl-C processing\n"); signal(SIGINT, &CustomCtrlC); } printf("Press ENTER key to exit\n"); char chr = getchar(); printf("ENTER key was pressed\n"); return 0; } void CustomCtrlC(int nSignal) { printf("Signal with code %d received\n", nSignal); }
Results:
# ./signal Press ENTER key to exit ^C # ./signal argument Custom Ctrl-C processing Press ENTER key to exit ^CSignal with code 2 received ^CSignal with code 2 received ^CSignal with code 2 received ENTER key was pressed |
C# example:
using System; using System.Runtime.InteropServices; namespace signal { class Program { public delegate bool HandlerRoutine(CtrlTypes CtrlType); static HandlerRoutine handler; [DllImport("kernel32.dll", SetLastError = true)] static extern bool SetConsoleCtrlHandler(HandlerRoutine handler, bool add); [DllImport("kernel32.dll", SetLastError = true)] static extern int GetLastError(); public enum CtrlTypes { CTRL_C_EVENT = 0, CTRL_BREAK_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT = 5, CTRL_SHUTDOWN_EVENT } static void Main(string[] args) { if (args.Length > 0) { Console.WriteLine("Custom Ctrl-C processing"); handler = new HandlerRoutine(ConsoleCtrlC); if (!SetConsoleCtrlHandler(handler, true)) { Console.WriteLine("SetConsoleCtrlHandle ret value: " + GetLastError().ToString(), ""); } } Console.WriteLine("Press ENTER to exit"); ConsoleKeyInfo keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, false); while (ConsoleKey.Enter != keyInfo.Key) { keyInfo = Console.ReadKey(); } Console.WriteLine("Exited"); } private static bool ConsoleCtrlC(CtrlTypes ctrlType) { Console.WriteLine("ConsoleCtrlC ctrType: {0}", ctrlType); switch (ctrlType) { case CtrlTypes.CTRL_C_EVENT: case CtrlTypes.CTRL_BREAK_EVENT: // disable ctrl/c and ctrl/break break; } return true; } } }
Result (Start with argument to turn on custom Control-C processing):
D:\Projects\signal\signal\bin\Debug\net5.0>signal.exe Press ENTER to exit ^C D:\Projects\signal\signal\bin\Debug\net5.0>signal.exe Press ENTER to exit qwerty^C D:\Projects\signal\signal\bin\Debug\net5.0>signal.exe 1 Custom Ctrl-C processing Press ENTER to exit ConsoleCtrlC ctrType: CTRL_C_EVENT ConsoleCtrlC ctrType: CTRL_C_EVENT ConsoleCtrlC ctrType: CTRL_C_EVENT ConsoleCtrlC ctrType: CTRL_C_EVENT ConsoleCtrlC ctrType: CTRL_C_EVENT Exited |