C Language                
            Signalhantering
        
        
            
    Sök…
Syntax
- void (* signal (int sig, void (* func) (int))) (int);
parametrar
| Parameter | detaljer | 
|---|---|
| sig | Signalen för att ställa in signalhanteraren till, en av SIGABRT,SIGFPE,SIGILL,SIGTERM,SIGINT,SIGSEGVeller något implementeringsdefinierat värde | 
| func | Signalhanteraren, som är något av följande: SIG_DFL, för standardhanteraren,SIG_IGNatt ignorera signalen, eller en funktionspekare med signaturenvoid foo(int sig);. | 
Anmärkningar
Användningen av signalhanterare med bara garantier från C-standarden sätter olika begränsningar vad som kan eller inte kan göras i den användardefinierade signalhanteraren.
- Om den användardefinierade funktionen återgår under hantering av - SIGSEGV,- SIGFPE,- SIGILLeller någon annan implementeringsdefinerad hårdvaruavbrott, definieras beteendet av C-standarden. Detta beror på att C: s gränssnitt inte ger möjlighet att ändra det felaktiga tillståndet (t.ex. efter en uppdelning med- 0) och därmed när programmet returneras är i exakt samma felaktiga tillstånd än innan hårdvaruavbrottet inträffade.
- Om den användardefinierade funktionen anropades som ett resultat av ett samtal att - aborteller- raise, får signalhanteraren inte anropa- raiseigen.
- Signaler kan anlända i mitten av alla operationer, och därför kan man ofta inte garantera operationens odelbarhet och inte heller fungerar signalhantering med optimering. Därför måste alla ändringar av data i en signalhanterare vara till variabler -  av typen sig_atomic_t(alla versioner) eller ensig_atomic_t(sedan C11, valfritt)
-  som är volatilekvalificerade.
 
-  av typen 
- Andra funktioner från C-standardbiblioteket respekterar vanligtvis inte dessa begränsningar, eftersom de kan ändra variabler i programmets globala tillstånd. C-standarden ger bara garantier för - abort,- _Exit(sedan C99),- quick_exit(sedan C11),- signal(för samma signalnummer) och vissa atomoperationer (sedan C11).
Beteende definieras inte av C-standarden om någon av ovanstående regler bryts. Plattformar kan ha specifika tillägg, men dessa är i allmänhet inte bärbara bortom plattformen.
- Vanligtvis har system sin egen lista över funktioner som är asynkrona signalsäkra , det vill säga C-biblioteksfunktioner som kan användas från en signalhanterare. - printfär- printfbland dessa funktioner.
- Speciellt definierar C-standarden inte så mycket om interaktionen med dess trådgränssnitt (sedan C11) eller någon plattformsspecifika trådbibliotek som POSIX-trådar. Sådana plattformar måste specificera interaktion mellan sådana trådbibliotek med signaler av sig själva. 
Signalhantering med "signal ()"
 Signalnummer kan vara synkrona (som SIGSEGV - segmenteringsfel) när de utlöses av en felaktig funktion i själva programmet eller asynkron (som SIGINT - interaktiv uppmärksamhet) när de startas utanför programmet, t.ex. av en knapptryckning som Cntrl-C . 
 Funktionen signal() är en del av ISO C-standarden och kan användas för att tilldela en funktion för att hantera en specifik signal 
#include <stdio.h>  /* printf() */
#include <stdlib.h> /* abort()  */
#include <signal.h> /* signal() */
void handler_nonportable(int sig)
{
    /* undefined behavior, maybe fine on specific platform */
    printf("Catched: %d\n", sig);
    
    /* abort is safe to call */
    abort();
}
sig_atomic_t volatile finished = 0;
void handler(int sig)
{
    switch (sig) {
    /* hardware interrupts should not return */
    case SIGSEGV:
    case SIGFPE:
    case SIGILL:
      /* quick_exit is safe to call */
      quick_exit(EXIT_FAILURE);
      /* use _Exit in pre-C11 */
      _Exit(EXIT_FAILURE);
    default:
       /* Reset the signal to the default handler, 
          so we will not be called again if things go
          wrong on return. */
      signal(sig, SIG_DFL);
      /* let everybody know that we are finished */
      finished = sig;
      return;
   }
}
int main(void)
{
    /* Catch the SIGSEGV signal, raised on segmentation faults (i.e NULL ptr access */
    if (signal(SIGSEGV, &handler) == SIG_ERR) {
        perror("could not establish handler for SIGSEGV");
        return EXIT_FAILURE;
    }
    /* Catch the SIGTERM signal, termination request */
    if (signal(SIGTERM, &handler) == SIG_ERR) {
        perror("could not establish handler for SIGTERM");
        return EXIT_FAILURE;
    }
    /* Ignore the SIGINT signal, by setting the handler to `SIG_IGN`. */
    signal(SIGINT, SIG_IGN);
    /* Do something that takes some time here, and leaves
       the time to terminate the program from the keyboard. */
    /* Then: */
    if (finished) {
       fprintf(stderr, "we have been terminated by signal %d\n", (int)finished);
        return EXIT_FAILURE;
    }
    /* Try to force a segmentation fault, and raise a SIGSEGV */
    {
      char* ptr = 0;
      *ptr = 0;
    }
    /* This should never be executed */
    return EXIT_SUCCESS;
}
 Att använda signal() sätter viktiga begränsningar vad du får göra i signalhanterarna, se kommentarerna för ytterligare information. 
 POSIX rekommenderar användning av sigaction() istället för signal() grund av dess ospecificerade beteenden och betydande implementeringsvariationer. POSIX definierar också många fler signaler än ISO C-standarden, inklusive SIGUSR1 och SIGUSR2 , som fritt kan användas av programmeraren för alla ändamål.