NOM
signalfd - Créer un descripteur de fichier pour accepter des signaux
SYNOPSIS
#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t *mask, int flags);
signalfd() crée un descripteur de fichier qui peut être utilisé pour
accepter des signaux à destination de l’appelant. Ceci fournit une
alternative à l’utilisation d’un gestionnaire de signal ou de
sigwaitinfo(2), et a l’avantage que le descripteur de fichier peut être
surveillé avec select(2), poll(2) ou epoll(7).
Le paramètre mask spécifie l’ensemble des signaux que l’appelant veut
accepter par le descripteur de fichier. Ce paramètre est un ensemble de
signaux dont le contenu peut être initialisé en utilisant les macros
décrites dans sigsetops(3). Normalement, l’ensemble des signaux reçus
par le descripteur de fichier devrait être bloqués en utilisant
sigprocmask(2) pour éviter que les signaux soient pris en charge par
les gestionnaires par défaut. Il n’est pas possible de recevoir les
signaux SIGKILL ou SIGSTOP par un descripteur de fichier signalfd ; ces
signaux sont ignorés sans rien dire s’ils sont spécifiés dans mask.
Si le paramètre fd vaut -1, l’appel crée un nouveau descripteur de
fichier et associe l’ensemble des signaux spécifiés dans mask avec ce
descripteur. Si fd ne vaut pas -1, alors il doit indiquer un
descripteur de fichier signalfd existant valable, et mask est utilisé
pour remplacer l’ensemble des signaux associés avec ce descripteur.
À partir de Linux 2.6.27, les valeurs suivantes peuvent être incluses
avec un OU binaire dans flags pour changer le comportement de
signalfd() :
SFD_NONBLOCK Placer l’attribut d’état de fichier O_NONBLOCK sur le
nouveau descripteur de fichier ouvert. Utiliser cet
attribut économise des appels supplémentaires à fcntl(2)
pour obtenir le même résultat.
SFD_CLOEXEC Placer l’attribut « close-on-exec » (FD_CLOEXEC) sur le
nouveau descripteur de fichier. Consultez la description
de l’attribut O_CLOEXEC dans open(2) pour savoir pourquoi
ça peut être utile.
Sous Linux, jusqu’à la version 2.6.26, le paramètre flags n’est pas
utilisé et doit valoir zéro.
signalfd() renvoie un descripteur de fichier qui gère les opérations
suivantes :
read(2)
Si un (ou plus) des signaux spécifiés dans mask est en attente
pour le processus, alors le tampon fourni à read(2) est utilisé
pour renvoyer une structure (ou plus) de type signalfd_siginfo
(voir ci-dessous) qui décrit les signaux. read(2) renvoie les
informations pour tous les signaux qui sont en attente et qui
tiennent dans le tampon fourni. Le tampon doit avoir une taille
d’au moins sizeof(struct signalfd_siginfo) octets. La valeur de
retour de read(2) est égale au nombre total d’octets lus.
En conséquence du read(2), les signaux sont consommés, de telle
sorte qu’ils ne seront plus en attente pour le processus
(c’est-à-dire qu’ils ne seront plus attrapés par les
gestionnaires de signaux, et ne seront plus acceptés par
sigwaitinfo(2)).
Si aucun des signaux de mask ne sont en attente pour le
processus, read(2) sera bloquera jusqu’à ce qu’un des signaux de
mask soit généré pour le processus, ou échouera avec l’erreur
EAGAIN si le descripteur de fichier est en mode non bloquant.
poll(2), select(2) (et similaires)
Le descripteur de fichier est lisible (le paramètre readfds de
select(2) ; l’attribut POLLIN de poll(2)) si un signal ou plus
de mask est en attente pour le processus.
Le descripteur de fichier signalfd gère également les autres
interfaces de multiplexage de descripteurs de fichier :
pselect(2), ppoll(2) et epoll(7).
close(2)
Quand le descripteur de fichier n’est plus nécessaire il doit
être fermé. Quand tous les descripteurs de fichier associés au
même objet signalfd ont été fermés, les ressources pour cet
objet sont libérées par le noyau.
La structure signalfd_siginfo
Les structures signalfd_siginfo renvoyées par read(2) sur une
descripteur de fichier signalfd sont au format suivant :
struct signalfd_siginfo {
uint32_t ssi_signo; /* Numéro de signal */
int32_t ssi_errno; /* Numéro d’erreur (pas utilisé) */
int32_t ssi_code; /* Code du signal */
uint32_t ssi_pid; /* PID de l’émetteur */
uint32_t ssi_uid; /* UID réel de l’émetteur */
int32_t ssi_fd; /* Descripteur de fichier (SIGIO) */
uint32_t ssi_tid; /* Identifiant de la temporisation
du noyau (timers POSIX)
uint32_t ssi_band; /* Band event (SIGIO) */
uint32_t ssi_overrun; /* POSIX timer overrun count */
uint32_t ssi_trapno; /* Numéro de trappe ayant causé le signal */
int32_t ssi_status; /* Code de sortie ou signal (SIGCHLD) */
int32_t ssi_int; /* Entier envoyé par sigqueue(2) */
uint64_t ssi_ptr /* Pointeur envoyé par sigqueue(2) */
uint64_t ssi_utime; /* Temps CPU utilisateur consommé (SIGCHLD) */
uint64_t ssi_stime; /* Temps CPU système consommé (SIGCHLD) */
uint64_t ssi_addr; /* Address that generated signal
(for hardware-generated signals) */
uint8_t pad[X]; /* Remplissage jusqu’à 128 octets
(espace prévu pour des champs
supplémentaires futures) */
};
Chacun des champs de cette structure est analogue aux champs de noms
similaires d’une structure siginfo_t. La structure siginfo_t est
décrite dans sigaction(2). Tous les champs de la structure
signalfd_siginfo renvoyée ne seront pas valable pour un signal donné ;
l’ensemble des champs valables peut être déterminé grâce au champ
ssi_code de la valeur de retour. Ce champ est analogue au champ si_code
de siginfo_t ; consultez sigaction(2) pour plus de détails.
Sémantique de fork(2)
Après un fork(2), le fils hérite d’une copie du descripteur de fichier
signalfd. Un appel à read(2) sur le descripteur de fichier depuis le
fils en attente pour le fils.
Sémantique de execve(2)
Comme tout descripteur de fichier, un descripteur de fichier signalfd
reste ouvert au travers d’un execve(2), à moins qu’il ait été marqué
comme « close-on-exec » (consultez fcntl(2)). Tout signal qui était
disponible en lecture avant un execve(2) reste disponible pour le
nouveau programme. (C’est analogue à la sémantique traditionnelle des
signaux, pour laquelle un signal bloqué qui est en attente reste en
attente au travers d’un execve(2))
Sémantique des threads
La sémantique des descripteurs de fichier signalfd dans un programme
multithreadé copie la sémantique standard des signaux. En d’autres
mots, quand un thread lit un descripteur de fichier signalfd, il lira
les signaux qui sont envoyés pour le thread lui-même ou pour le
processus (c’est-à-dire l’ensemble du group de threads). (Un thread ne
sera pas capable de lire les signaux qui sont envoyés aux autres
threads du processus)
VALEUR RENVOYÉE
S’il réussit, signalfd() renvoie un descripteur de fichier signalfd ;
il s’agit soit d’un nouveau descripteur de fichier (si fd valait -1),
ou fd si fd était un descripteur de fichier signalfd valable. En cas
d’erreur, il renvoie -1 et errno contient le code d’erreur.
ERREURS
EBADF Le descripteur de fichier fd n’est pas un descripteur de fichier
valable.
EINVAL fd n’est pas un descripteur de fichier signalfd valable.
EINVAL flags n’est pas correct ; ou, pour les versions de Linux 2.6.26
ou ultérieures, flags n’est pas nul.
EMFILE La limite du nombre total de descripteurs de fichier ouverts par
processus a été atteinte.
ENFILE La limite du nombre total de fichiers ouverts sur le système a
été atteinte.
ENODEV Impossible de monter (en interne) le périphérique anonyme
d’inoeud.
ENOMEM Pas assez de mémoire pour créer le descripteur de fichier
signalfd.
VERSIONS
signalfd() est disponible sous Linux depuis le noyau 2.6.22. La glibc
le gère depuis la version 2.8. L’appel système signalfd4() (voir NOTES)
est disponible sous Linux depuis le noyau 2.6.27.
CONFORMITÉ
signalfd() et signalfd4() sont spécifiques à Linux.
NOTES
L’appel système Linux sous-jacent nécessite un paramètre
supplémentaire, size_t sizemask, qui spécifie la taille du paramètre
mask. La fonction enveloppe signalfd() de la glibc n’a pas ce
paramètre, puisqu’elle fournit ce paramètre à l’appel système
sous-jacent.
Un processus peut créer plusieurs descripteurs de fichier signalfd.
Ceci permet d’accepter différents signaux sur différents descripteurs
de fichier (et peut être utile si les descripteurs de fichier sont
surveillés en utilisant select(2), poll(2) ou epoll(7) : l’arrivée de
différents signaux rendra différents descripteurs de fichier
disponibles). Si un signal apparaît dans le mask de plusieurs
descripteurs de fichier, un signal reçu pourra être lu (une seule fois)
depuis n’importe lequel des descripteurs.
Appels système Linux sous-jacents
Il y a deux appels système sous-jacent : signalfd() et signalfd4(), qui
est plus récent. Le premier appel système n’implémente pas de paramètre
flags. Le dernier appel système implémente les valeurs de flags
décrites ci-dessous. À partir de la glibc 2.9, la fonction enveloppe
signalfd() utilisera signalfd4() quand il est disponible.
BOGUES
Dans les noyaux antérieurs à 2.6.25, les champs ssi_ptr et ssi_int
n’étaient pas renseignés avec les données accompagnant un signal envoyé
par sigqueue(2).
EXEMPLE
Le programme ci-dessous accèpte les signaux SIGINT et SIGQUIT en
utilisant un descripteur de fichier signalfd. Le programme se termine
après avoir accepté le signal SIGQUIT. La session shell suivante montre
l’utilisation du programme :
$ ./signalfd_demo
^C # Contrôle-C génère un SIGINT
Got SIGINT
^C
Got SIGINT
^\ # Contrôle-\ génère un SIGQUIT
Got SIGQUIT
$
Source du programme
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
ssize_t s;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
/* Bloquer les signaux pour qu’il ne soit plus géré
par les gestionnaire par défaut */
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
handle_error("sigprocmask");
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
handle_error("signalfd");
for (;;) {
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
handle_error("read");
if (fdsi.ssi_signo == SIGINT) {
printf("Got SIGINT\n");
} else if (fdsi.ssi_signo == SIGQUIT) {
printf("Got SIGQUIT\n");
exit(EXIT_SUCCESS);
} else {
printf("Read unexpected signal\n");
}
}
}
VOIR AUSSI
eventfd(2), poll(2), read(2), select(2), sigaction(2), sigprocmask(2),
sigwaitinfo(2), timerfd_create(2), sigsetops(3), sigwait(3), epoll(7),
signal(7)
COLOPHON
Cette page fait partie de la publication 3.23 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent être trouvées à l’adresse
http://www.kernel.org/doc/man-pages/.
TRADUCTION
Cette page de manuel a été traduite et est maintenue par Julien Cristau
<julien.cristau@ens-lyon.org> et l’équipe francophone de traduction de
Debian.
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document
en utilisant la commande « man -L C <section> <page_de_man> ».