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);
DESCRIPTION¶
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 cela peut être utile.
Dans les versions de 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; /* Événement de bande (SIGIO) */
uint32_t ssi_overrun; /* Compte des dépassements de la temporisation POSIX */
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(3) */
uint64_t ssi_ptr /* Pointeur envoyé par sigqueue(3) */
uint64_t ssi_utime; /* Temps CPU utilisateur consommé (SIGCHLD) */
uint64_t ssi_stime; /* Temps CPU système consommé (SIGCHLD) */
uint64_t ssi_addr; /* Adresse qui a généré le signal
(pour les signaux issu du matériel) */
uint8_t pad[ X]; /* Remplissage jusqu'à 128 octets
(espace prévu pour des champs
supplémentaires futurs) */
};
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.
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.
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'inœud.
- 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.
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(3).
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 gestionnaires 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.44 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¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Julien Cristau et l'équipe francophone de traduction de
Debian (2006-2009).
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> ».