patterncMinor
Handling SIGINT signal for a server program
Viewed 0 times
handlingsignalprogramsigintforserver
Problem
I have created a small server program that encrypts text using a named pipe:
In this code I have created a
Is this a correct way to handle signals?
#define UNICODE
#define WIN32_WINNT 0x0500
#include
#include
#include
HANDLE hPipe;
DWORD WINAPI ServerProc(LPVOID lpVoid)
{
hPipe = CreateNamedPipe(L"\\\\.\\pipe\\testpipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |PIPE_WAIT, 1, 256, 256, 0, NULL);
if(!hPipe)
return wprintf(L"ERROR : Cannot create pipe.\n");
while(ConnectNamedPipe(hPipe, NULL))
{
WCHAR szText[80] = {0};
DWORD dwSize;
INT i;
ReadFile(hPipe, szText, 158, &dwSize, NULL);
for(i = 0; i < dwSize; i++)
szText[i] ^= '#';
WriteFile(hPipe, szText, 158, &dwSize, NULL);
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
}
CloseHandle(hPipe);
return 0;
}
void SignalHandler(int signal)
{
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
printf("Application closing...\n");
exit(0);
}
int wmain(void)
{
HANDLE hThread;
signal(SIGINT, SignalHandler);
hThread = CreateThread(NULL, 0, ServerProc, NULL, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}In this code I have created a
hPipe handle as global because my program thread and the signal handler both need the handle.Is this a correct way to handle signals?
Solution
It depends on what you want the server to do when an interrupt is sent.
If you really want the program to stop when it is sent an interrupt, even though it is a service (Windows) or daemon (Unix), then what you did works. If, however, the program was run with settings to ignore interrupts, your code overrides that. The canonical sequence for setting a signal handler (for signal number
If the program was ignoring the signal, it continues to do so. Otherwise, it sets its own handler to handle the signal.
On Unix, you usually use SIGTERM to do a controlled stop of a program, and for daemons, you typically use SIGHUP to indicate that the daemon should revisit its configuration.
Also, in the POSIX world, it is generally recommended to use
If your program needed to continue after receiving the signal, you would have to reset the signal handler in the signal handler - and there's a small window of vulnerability which means that if two signals are sent fast enough, the program stops despite your handler. Using
If you really want the program to stop when it is sent an interrupt, even though it is a service (Windows) or daemon (Unix), then what you did works. If, however, the program was run with settings to ignore interrupts, your code overrides that. The canonical sequence for setting a signal handler (for signal number
signum) is:if (signal(signum, SIG_IGN) != SIG_IGN)
signal(signum, sighandler);If the program was ignoring the signal, it continues to do so. Otherwise, it sets its own handler to handle the signal.
On Unix, you usually use SIGTERM to do a controlled stop of a program, and for daemons, you typically use SIGHUP to indicate that the daemon should revisit its configuration.
Also, in the POSIX world, it is generally recommended to use
sigaction() rather than signal() because it gives different and better guarantees about what happens.If your program needed to continue after receiving the signal, you would have to reset the signal handler in the signal handler - and there's a small window of vulnerability which means that if two signals are sent fast enough, the program stops despite your handler. Using
sigaction() avoids this timing vulnerability.Code Snippets
if (signal(signum, SIG_IGN) != SIG_IGN)
signal(signum, sighandler);Context
StackExchange Code Review Q#823, answer score: 4
Revisions (0)
No revisions yet.