Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have created a small server program that encrypts text using a named pipe:

#define UNICODE
#define WIN32_WINNT 0x0500
#include <stdio.h>
#include <windows.h>
#include <signal.h>



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?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

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 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.

share|improve this answer
    
Thanks for your suggestions. –  Searock Feb 18 '11 at 5:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.