2013-05-30 10 views
9

Sto eseguendo il porting di un programma Linux/gcc in Windows e implementato la gestione delle eccezioni comuni per entrambi. Mi chiedevo quale sarebbe l'equivalente del segnale SIGINT per MinGW/gcc.Equivale al segnale "SIGINT" (posix) per la cattura di "CTRL + C" in Windows/MinGW

Ecco come mi occupo sotto Linux:

static void handler(int sig) 
{ 
    // Catch exceptions 
    switch(sig) 
    { 
    case SIGABRT: 
     fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr); 
     break; 
    case SIGFPE: 
     fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n", 
       stderr); 
     break; 
    case SIGILL: 
     fputs("Caught SIGILL: illegal instruction\n", stderr); 
     break; 
    case SIGINT: 
     fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n", 
       stderr); 
     break; 
    case SIGSEGV: 
     fputs("Caught SIGSEGV: segfault\n", stderr); 
     break; 
    case SIGTERM: 
    default: 
     fputs("Caught SIGTERM: a termination request was sent to the program\n", 
       stderr); 
     break; 
    } 

    // Ctrl+C interrupt => No backtrace 
    if (sig != (int)SIGINT) 
    { 
     fprintf(stderr, "Error: signal %d:\n", sig); 
     posix_print_stack_trace(); 
    } 
    exit(sig); 

} 

signal(SIGABRT, handler); 
signal(SIGFPE, handler); 
signal(SIGILL, handler); 
signal(SIGINT, handler); 
signal(SIGSEGV, handler); 
signal(SIGTERM, handler); 

In Windows, questo appare come:

static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo) 
{ 
    switch(ExceptionInfo->ExceptionRecord->ExceptionCode) 
    { 
    case EXCEPTION_ACCESS_VIOLATION: 
     fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); 
     break; 
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 
     fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr); 
     break; 
    case EXCEPTION_BREAKPOINT: 
     fputs("Error: EXCEPTION_BREAKPOINT\n", stderr); 
     break; 

    ... 
    } 
} 

if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) 
{ 
    windows_print_stacktrace(ExceptionInfo->ContextRecord); 
} 

mio problema è che non vedo alcun equivalente di SIGINT nel EXCEPTION_* disponibile per Windows.

Come sarebbe possibile rilevare un'interruzione "CTRL + C" sotto Windows (MinGW/gcc)?

Grazie mille.

+1

È comunque SIGINT, in Microsoft CRT comunque. SIGBREAK per il tasto Ctrl + Break. E no, questo non passa attraverso il callback installato per SetUnhandledException(). Non è non gestito :) SetConsoleCtrlHandler() per dare una sbirciata all'inizio. –

risposta

9

Se si desidera prendere ctrl + c SetConsoleCtrlHandler potrebbe essere quello che stai cercando.

#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 

BOOL WINAPI ConsoleHandler(DWORD); 

int main(int argc, char *argv[]) 
{ 
    if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler,TRUE)) { 
     fprintf(stderr, "Unable to install handler!\n"); 
     return EXIT_FAILURE; 
    } 

    for (;;) 
     ; /* Null body. */ 

    return EXIT_SUCCESS; 
} 

BOOL WINAPI ConsoleHandler(DWORD dwType) 
{ 
    switch(dwType) { 
    case CTRL_C_EVENT: 
     printf("ctrl-c\n"); 
     break; 
    case CTRL_BREAK_EVENT: 
     printf("break\n"); 
     break; 
    default: 
     printf("Some other event\n"); 
    } 
    return TRUE; 
} 
+0

Sembra buono. Ci provo. Grazie. –

+2

Che ha funzionato come un fascino. Saluti. Solo 'CCHandler' potrebbe essere' ConsoleHandler' ... –

+0

Nota che Windows lo chiama da un altro thread invece di gestori di segnale in esecuzione sullo stesso thread. – OCTAGRAM

Problemi correlati