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 |