SIGACTION(2)

NOM
sigaction - Examiner et modifier l'action associée à un signal

SYNOPSIS
#include <signal.h>

int sigaction(int signum, const struct sigaction *act,
              struct sigaction *oldact);

DESCRIPTION
L'appel système sigaction() sert à modifier l'action effectuée par un processus à la réception d'un signal spécifique.

signum indique le signal concerné, à l'exception de SIGKILL et SIGSTOP.

Si act est non nul, la nouvelle action pour le signal signum est définie par act. Si oldact est non nul, l'ancienne action est sauvegardée dans oldact.

La structure sigaction est définie par quelque chose comme :

struct sigaction {
    void     (*sa_handler) (int);
    void     (*sa_sigaction) (int, siginfo_t *, void *);
    sigset_t   sa_mask;
    int        sa_flags;
    void     (*sa_restorer) (void);
};

Sur certaines architectures, on emploie une union. Il ne faut donc pas utiliser ou remplir simultanément sa_handler et sa_sigaction.

L'élément sa_restorer est obsolète et ne doit pas être utilisé, POSIX ne mentionne pas de membre sa_restorer.

sa_handler indique l'action affectée au signal signum, et peut être SIG_DFL pour l'action par défaut, SIG_IGN pour ignorer le signal, ou un pointeur sur une fonction de gestion de signaux. Cette fonction reçoit le numéro de signal comme seul argument.

Si SA_SIGINFO est indiqué dans sa_flags, sa_sigaction (plutôt que sa_handler) indique la fonction gestionnaire de signaux pour signum. Cette fonction prend le numéro du signal comme premier argument, un pointeur sur un siginfo_t comme second argument et un pointeur sur un ucontext_t (transtypé en void *) comme troisième argument.

sa_mask fournit un masque de signaux à bloquer pendant l'exécution du gestionnaire. De plus, le signal ayant appelé le gestionnaire est bloqué à moins que l'attribut SA_NODEFER ne soit précisé.

sa_flags spécifie un ensemble d'attributs qui modifient le comportement du signal. Il est formé par un OU binaire « | ») entre les options suivantes :

    SA_NOCLDSTOP
        Si signum vaut SIGCHLD, ne pas recevoir les signaux de notification d'arrêt d'un processus fils (quand le fils reçoit un signal SIGSTOP, SIGTSTP, SIGTTIN ou SIGTTOU) ou reprendre (c'est-à-dire, il reçoit SIGCONT) (voir wait(2)). Cet attribut n'a de sens que lors de la mise en place d'un gestionnaire pour SIGCHLD.

    SA_NOCLDWAIT (Depuis Linux 2.6)
        Si signum vaut SIGCHLD, ne pas transformer les fils en zombies lorqu'ils se terminent. Voir aussi waitpid(2). Cet attribut n'a de sens que lors de la mise en place d'un gestionnaire pour SIGCHLD, ou lors de la configuration de la disposition de signal de SIG_DFL. Si l'attribut SA_NOCLDWAIT est défini lors de la mise en place d'un gestionnaire pour SIGCHLD, POSIX.1 ne spécifie pas si le signal SIGCHLD est généré lorsqu'un processus fils se termine. Sous Linux, un signal SIGCHLD est généré dans ce cas ; sur d'autres implémentations, il ne l'est pas.

    SA_RESETHAND
        Rétablir l'action à son comportement par défaut une fois que le gestionnaire a été appelé. Cet attribut n'a de sens que lors de la mise en place d'un gestionnaire de signal. SA_ONESHOT est un synonyme non standard obsolète pour cet attribut.

    SA_ONSTACK
        Appeler le gestionnaire avec une pile différente fournie par sigaltstack(2). Si cette pile est indisponible, on utilisera la pile par défaut. Cet attribut n'a de sens que lors de la mise en place d'un gestionnaire de signal.

    SA_RESTART
        Fournir un comportement compatible avec la sémantique BSD en redémarrant automatiquement les appels système lents interrompus par l'arrivée du signal. Cet attribut n'a de sens que lors de la mise en place d'un gestionnaire de signal. Voir signal(7) pour une discussion sur le redémarrage d'un appel système.

    SA_NODEFER
        Ne pas empêcher un signal d'être reçu depuis l'intérieur de son propre gestionnaire. Cet attribut n'a de sens que lors de la mise en place d'un gestionnaire de signal. SA_NOMASK est un synonyme non standard obsolète pour cet attribut.

    SA_SIGINFO (Depuis Linux 2.2)
        Le gestionnaire de signal recevra trois arguments, et non plus un seul. Dans ce cas, il faut utiliser le membre sa_sigaction et non pas sa_handler. Cet attribut n'a de sens que lors de la mise en place d'un gestionnaire de signal.

Le paramètre siginfo_t de la routine sa_sigaction est une structure contenant les éléments suivants :

siginfo_t {
    int     si_signo;       /* Numéro de signal         */
    int     si_errno;       /* Numéro d'erreur          */
    int     si_code;        /* Code du signal           */
    pid_t   si_pid;         /* PID de l'émetteur        */
    uid_t   si_uid;         /* UID réel de l'émetteur   */
    int     si_status;      /* Valeur de sortie         */
    clock_t si_utime;       /* Temps utilisateur écoulé */
    clock_t si_stime;       /* Temps système écoulé     */
    sigval_t si_value;      /* Valeur de signal         */
    int     si_int;         /* Signal POSIX.1b          */
    void   *si_ptr;         /* Signal POSIX.1b          */
    void   *si_addr;        /* Emplacement d'erreur     */
    int     si_band;        /* Band event               */
    int     si_fd;          /* Descripteur de fichier   */
}
Les champs si_signo, si_errno et si_code sont définis pour tous les signaux (si_errno n'est pas utilisé sous Linux). Le reste de la structure peut être une union, et il ne faut donc tenir compte que des champs qui sont significatifs pour le signal reçu :

*   Les signaux POSIX.1b et SIGCHLD remplissent les champs si_pid et si_uid.

*   SIGCHLD remplit également si_status, si_utime et si_stime.

*   si_int et si_ptr sont fournis par l'émetteur d'un signal POSIX.1b. Voir sigqueue(2) pour plus de détails.

*   SIGILL, SIGFPE, SIGSEGV et SIGBUS remplissent si_addr avec l'adresse de l'erreur. SIGPOLL remplit si_band et si_fd.

si_code est une valeur (pas un masque de bits) indiquant la raison pour laquelle le signal a été émis. La liste suivante indique les valeurs que peut prendre si_code pour n'importe quel signal, avec la raison pour laquelle le signal a été généré.

    SI_USER
        kill(2) ou raise(3)

    SI_KERNEL
        Envoyé par le noyau.

    SI_QUEUE
        sigqueue(2)

    SI_TIMER
        Fin d'une temporisation POSIX

    SI_MESGQ
        Changement d'état d'une file de message POSIX (depuis Linux 2.6.6) ; voir mq_notify(3)

    SI_ASYNCIO
        Fin d'une AIO

    SI_SIGIO
        SIGIO empilé

    SI_TKILL
        tkill(2) ou tgkill(2) (depuis Linux 2.4.19)

Les valeurs suivantes peuvent être placées dans si_code pour un signal SIGILL :

    ILL_ILLOPC
        opcode illégal

    ILL_ILLOPN
        opérande illégal

    ILL_ILLADR
        mode d'adressage illégal

    ILL_ILLTRP
        trappe illégale

    ILL_PRVOPC
        opcode privilégié

    ILL_PRVREG
        registre privilégié

    ILL_COPROC
        erreur de coprocesseur

    ILL_BADSTK
        erreur interne de pile

Les valeurs suivantes peuvent être placées dans si_code pour un signal SIGFPE :

    FPE_INTDIV
        division entière par zéro

    FPE_INTOVF
        débordement entier

    FPE_FLTDIV
        division réelle par zéro

    FPE_FLTOVF
        débordement réel

    FPE_FLTUND
        débordement inférieur réel

    FPE_FLTRES
        résultat réel inexact

    FPE_FLTINV
        opération réelle invalide

    FPE_FLTSUB
        indice hors intervalle

Les valeurs suivantes peuvent être placées dans si_code pour un signal SIGSEGV :

    SEGV_MAPERR
        adresse sans objet

    SEGV_ACCERR
        permissions invalides pour l'objet

Les valeurs suivantes peuvent être placées dans si_code pour un signal SIGBUS :

    BUS_ADRALN
        alignement d'adresse invalide

    BUS_ADRERR
        adresse physique inexistante

    BUS_OBJERR
        erreur matérielle spécifique

Les valeurs suivantes peuvent être placées dans si_code pour un signal SIGTRAP :

    TRAP_BRKPT
        point d'arrêt du processus

    TRAP_TRACE
        suivi d'exécution du processus

Les valeurs suivantes peuvent être placées dans si_code pour un signal SIGCHLD :

    CLD_EXITED
        fils terminé normalement

    CLD_KILLED
        fils tué par un signal

    CLD_DUMPED
        fils terminé anormalement

    CLD_TRAPPED
        fils en cours de suivi

    CLD_STOPPED
        fils arrêté

    CLD_CONTINUED
        fils arrêté a redémarré (depuis Linux 2.6.9)

Les valeurs suivantes peuvent être placées dans si_code pour un signal SIGPOLL :

    POLL_IN
        données disponibles en entrée

    POLL_OUT
        tampons de sortie libres

    POLL_MSG
        message disponible en entrée

    POLL_ERR
        erreur d'entrées-sorties

    POLL_PRI
        entrée haute priorité disponible

    POLL_HUP
        périphérique débranché

VALEUR RENVOYÉE
sigaction() renvoie 0 s'il réussit et -1 s'il échoue.

ERREURS

EFAULT
    act ou oldact pointent en-dehors de l'espace d'adressage accessible.

EINVAL
    Un signal invalide est indiqué. Ceci se produit également si l'on tente de modifier l'action associée aux signaux SIGKILL et SIGSTOP, qui ne peuvent pas être interceptés ou ignorés.

CONFORMITÉ
POSIX.1-2001, SVr4.

NOTES

Selon POSIX, le comportement d'un processus est indéfini après qu'il ait ignoré un signal SIGFPE, SIGILL ou SIGSEGV
 qui n'avait pas été engendré par une fonction kill(2) ou raise(3). La division entière par zéro a un résultat indéfini. Sur certaines architectures, cela déclenchera un signal SIGFPE. (De même, diviser l'entier le plus négatif par -1 peut déclencher SIGFPE). Ignorer ce signal peut mener à des boucles sans fin.

POSIX.1-1990 interdisait d'ignorer SIGCHLD avec SIG_IGN. POSIX.1-2001 l'autorise, ignorer SIGCHLD permet donc d'éviter la création de zombies (voir wait(2)). Cependant, les comportements historiques de BSD et System V sur l'ignorance de SIGCHLD diffèrent, aussi, la seule méthode entièrement portable pour s'assurer que les fils qui se terminent ne deviennent pas des zombies est d'intercepter le signal SIGCHLD et d'appeler wait(2) ou de faire quelque chose de similaire.

POSIX.1-1990 ne documentait que SA_NOCLDSTOP. POSIX.1-2001 a ajouté SA_NOCLDWAIT, SA_RESETHAND, SA_NODEFER et SA_SIGINFO. L'utilisation de ces dernières valeurs dans sa_flags peut être moins portable dans les applications destinées à d'anciennes implémentations Unix.

L'option SA_RESETHAND est compatible avec l'option SVr4 du même nom.

L'option SA_NODEFER est compatible avec l'option SVr4 du même nom pour les noyaux 1.3.9 et ultérieurs. Pour les noyaux plus anciens, Linux autorisera la réception de tous les signaux et pas seulement celui qui vient de se déclencher (écrasant effectivement sa_mask ).

sigaction() peut être appelé avec un second argument nul pour obtenir le gestionnaire de signaux actuel. On peut aussi vérifier si un signal est valide sur la machine actuelle en l'appelant avec les deuxième et troisième arguments nuls.

Il n'est pas possible de bloquer SIGKILL ou SIGSTOP (en les indiquant dans sa_mask). Les tentatives pour le faire seront silencieusement ignorées.

Voir sigsetops(3) pour les détails concernant les ensembles de signaux.

Voir signal(7) pour une liste des fonctions sûres pour les signaux asynchrones qui peuvent être appelées par un gestionnaire de signaux.

  Non documenté
Avant l'introduction de l'attribut SA_SIGINFO, il était déjà possible d'obtenir des informations supplémentaires dans le gestionnaire de signal sa_handler, en lui ajoutant un argument de type struct sigcontext. On peut retrouver ceci dans les sources du noyau. Ce mécanisme est désormais obsolète.

BOGUES
Dans les noyaux jusqu'au 2.6.13 inclus, indiquer SA_NODEFER dans sa_flags empêchait non seulement le signal reçu d'être masqué pendant l'exécution du gestionnaire mais également les signaux indiqués dans sa_mask. Ce bogue a été corrigé dans le noyau 2.6.14.

EXEMPLE
Voir mprotect(2).

VOIR AUSSI
kill(1), kill(2), killpg(2), pause(2), sigaltstack(2), signal(2), signalfd(2), sigpending(2), sigprocmask(2), sigqueue(2), sigsuspend(2), wait(2), raise(3), siginterrupt(3), sigsetops(3), sigvec(3), core(5), signal(7)

TRADUCTION

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 14 octobre 1996 et révisée le 17 juillet 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 sigaction ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.