SIGNALFD
Section : Manuel du programmeur Linux (
2)
Mise à jour de la version anglaise : 8 avril 2008
Index
Menu principal
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 à l'avantage que le descripteur de fichier peut être surveillé avec
select(2),
poll(2)
ou
epoll(7).
L'argument
mask
indique l'ensemble des signaux que l'appelant souhaite accepter
par le descripteur de fichier.
Cet argument est un ensemble de signaux dont le contenu peut être
initialisé en utilisant les macros décrites dans
sigsetops(3).
Normalement, l'ensemble de signaux devant être reçus par le descripteur
de fichier devrait être bloqué avec
sigprocmask(2),
pour éviter que les signaux soient gérés conformément à leurs
dispositions par défaut.
Il n'est pas possible de recevoir les signaux
SIGKILL
ou
SIGSTOP
par un descripteur de fichier signalfd ;
ces signaux sont silencieusement ignorés s'ils sont spécifiés dans
mask.
Si l'argument
fd
vaut -1, l'appel crée un nouveau descripteur de fichier et lui associe
l'ensemble de signaux indiqué dans
mask.
Si
fd
ne vaut pas -1, il doit indiquer un descripteur de fichier existant
et valide, et
mask
est utilisé pour remplacer l'ensemble de signaux associé à ce descripteur.
L'argument
flags
n'est actuellement pas utilisé et doit être indiqué à zéro.
Dans le futur, il pourrait être utilisé pour demander
des fonctionnalités supplémentaires.
signalfd()
renvoie un descripteur de fichier qui accepte les opérations suivantes :
- read(2)
-
Si un ou plusieurs des signaux indiqués dans
mask
est en attente du processus, le tampon fourni à
read(2)
est utilisé pour renvoyer une ou plusieurs structures
signalfd_siginfo
(voir plus loin) qui décrivent les signaux.
L'appel
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.
-
La conséquence d'un
read(2)
est que les signaux sont consommés, ainsi ils ne sont plus en attente
pour le processus (c'est-à-dire qu'ils ne seront pas interceptés par
des gestionnaires de signaux et ne peuvent pas être acceptés avec
sigwaitinfo(2)).
-
Si aucun des signaux de
mask
n'est en attente du processus,
read(2)
soit bloquera jusqu'à ce qu'un des signaux de
mask
soit généré pour le processus, soit échouera avec l'erreur
EAGAIN
si le descripteur de fichier est en mode non bloquant
(via l'utilisation de l'opération
F_SETFL
de
fcntl(2)
pour définir l'attribut
O_NONBLOCK).
- poll(2), select(2) (et similaires)
-
Le descripteur de fichier est accessible en lecture
(l'argument
readfds
de
select(2) ;
l'attribut
POLLIN
de
poll(2))
si un ou plusieurs des signaux de
mask
est en attente pour le processus.
-
Le descripteur de fichier signalfd accepte également les autres API
de multiplexage de descripteurs de fichier :
pselect(2),
ppoll(2)
et
epoll(7).
- close(2)
-
Lorsque le descripteur de fichier n'est plus nécessaire,
il doit être fermé.
Lorsque 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
Le format de la structure
signalfd_siginfo
renvoyée par
read(2)
à partir d'un descripteur de fichier signalfd est le suivant :
struct signalfd_siginfo {
uint32_t ssi_signo; /* Signal number */
int32_t ssi_errno; /* Error number (unused) */
int32_t ssi_code; /* Signal code */
uint32_t ssi_pid; /* PID of sender */
uint32_t ssi_uid; /* Real UID of sender */
int32_t ssi_fd; /* File descriptor (SIGIO) */
uint32_t ssi_tid; /* Kernel timer ID (POSIX timers)
uint32_t ssi_band; /* Band event (SIGIO) */
uint32_t ssi_overrun; /* POSIX timer overrun count */
uint32_t ssi_trapno; /* Unused */
int32_t ssi_status; /* Exit status or signal (SIGCHLD) */
int32_t ssi_int; /* Integer sent by sigqueue(2) */
uint64_t ssi_ptr /* Pointer sent by sigqueue(2) */
uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */
uint64_t ssi_stime; /* System CPU time consumed (SIGCHLD) */
uint64_t ssi_addr; /* Address that generated signal
(for hardware-generated signals) */
uint8_t pad[X]; /* Pad size to 128 bytes (allow for
additional fields in the future) */
};
Chacun des champs de cette structure est analogue
au champ de nom similaire dans la structure
siginfo_t.
La structure
siginfo_t
est décrite dans
sigaction(2).
Tous les champs de la structure
signalfd_siginfo
renvoyée ne sont pas forcément valides pour un signal particulier ;
l'ensemble des champs valides peut être déterminé à partir de la valeur
renvoyée dans le champ
ssi_code.
Ce champ est analogue au champ
si_code
de
siginfo_t ;
voir
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.
Le descripteur de fichier fait référence au même objet de fichier
sous-jacent que le descripteur correspondant dans le parent, et les appels
read(2)
dans le fils renverront les informations à propos des signaux générés
pour le parent (le processus qui a créé l'objet avec
signalfd()).
Sémantique de execve(2)
Tout comme un autre descripteur de fichier,
un descripteur de fichier signalfd reste ouvert à travers un
execve(2),
à moins qu'il n'ait été marqué comme « close-on-exec » (voir
fcntl(2)).
Tout signal qui était disponible en lecture avant l'appel
execve(2)
reste disponible pour le programme nouvellement chargé.
(Ceci est analogue à la sémantique traditionnelle des signaux
où un signal bloqué en attente reste en attente à travers un
execve(2).)
Sémantique des threads
La sémantique des descripteurs de fichier signalfd dans un programme
multithreadé reflète la sémantique standard des signaux.
En d'autres mots, lorsqu'un thread lit dans un descripteur de fichier
signalfd, il lira les signaux dirigés vers le thread lui-même
et les signaux dirigés vers le processus
(c'est-à-dire, le groupe entier des threads)
(Un thread ne pourra pas lire les signaux dirigés vers d'autres threads
du processus).
VALEUR RENVOYÉE
S'il réussit,
signalfd()
renvoie un descripteur de fichier signalfd ;
ce sera soit un nouveau descripteur de fichier (si
fd
valait -1), soit
fd
si
fd
était un descripteur de fichier signalfd valide.
S'il échoue, -1 est renvoyé et
errno
contient le code de l'erreur.
ERREURS
- EBADF
-
Le descripteur de fichier n'est pas un descripteur de fichier valide.
- EINVAL
-
fd
n'est pas un descripteur de fichier signalfd valide ; ou
flags
n'est pas nul.
- EMFILE
-
La limite par processus du nombre total des descripteurs de fichier
ouverts a été atteinte.
- ENFILE
-
La limite du nombre total de fichiers ouverts sur le sytème
a été atteinte.
- ENODEV
-
Impossible de monter le périphérique anonyme d'inœud (interne).
- ENOMEM
-
Il n'y a pas suffisamment de mémoire pour créer un nouveau descripteur
de fichier signalfd.
VERSIONS
signalfd()
est disponible sous Linux depuis le noyau 2.6.22.
Une prise en charge fonctionnelle est fournie dans la glibc
depuis la version 2.8.
CONFORMITÉ
signalfd()
est spécifique à Linux.
NOTES
L'appel système Linux sous-jacent nécessite un argument supplémentaire,
size_t sizemask,
qui indique la taille de l'argument
mask.
La fonction enveloppe
signalfd()
de la glibc n'a pas cet argument puisqu'elle fournit la valeur
nécessaire à l'appel système sous-jacent.
L'argument
flags
est un ajout de la glibc par rapport l'appel système sous-jacent.
Un processus peut créer plusieurs descripteurs de fichier signalfd.
Cela lui permet d'accepter différents signaux sur différents
descripteurs de fichier.
(Cela peut être utile pour la surveillance des descripteurs de fichier avec
select(2),
poll(2)
ou
epoll(7) :
l'arrivée de signaux différents rendra prêts des descripteurs différents.)
Si un signal apparaît dans
mask
pour plus d'un des descripteurs de fichier, les occurences de ce signal
peuvent être lues (une fois) à partir de n'importe lequel des descripteurs.
BOGUES
Dans les noyaux antérieurs au 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 suivant accepte les signaux
SIGINT
et
SIGQUIT
via un descripteur de fichier signalfd.
Le programme se termine après avoir accepté un signal
SIGQUIT.
La session shell suivante montre l'utilisation du programme :
$ ./signalfd_demo
^C # Contrôle-C génère SIGINT
Got SIGINT
^C
Got SIGINT
^\ # Contrôle-\ génère SIGQUIT
Got SIGQUIT
$
#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'ils ne soient plus gérés
par leurs 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)
TRADUCTION
Ce document est une traduction réalisée par Alain Portal
<aportal AT univ-montp2 DOT fr> le 23 avril 2008
et révisée le 4 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 signalfd ».
N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute
erreur dans cette page de manuel.
Index
- NOM
-
- SYNOPSIS
-
- DESCRIPTION
-
- La structure signalfd_siginfo
-
- Sémantique de fork(2)
-
- Sémantique de execve(2)
-
- Sémantique des threads
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- VERSIONS
-
- CONFORMITÉ
-
- NOTES
-
- BOGUES
-
- EXEMPLE
-
- VOIR AUSSI
-
- TRADUCTION
-
Dernière mise à jour : 4 juillet 2008