signalfd
Section: System Calls (2)
Updated: 5 février 2023
Index
Return to Main Contents
NOM
signalfd - Créer un descripteur de fichier pour accepter des signaux
BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)
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. Cela 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é 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
silencieusement ignorés s'ils sont spécifiés dans mask.
Si le paramètre fd vaut -1, alors l'appel crée un nouveau descripteur
de fichier et y associe le signal défini dans mask. 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 la description du
fichier ouvert référencée par le nouveau descripteur de fichier (consulter
open(2)). 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.
Jusqu'à Linux 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) 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 similaire)
-
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 un
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) */
uint16_t ssi_addr_lsb; /* Le bit le plus faible de l'adresse
(SIGBUS ; depuis Linux 2.6.37) */
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 valables 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), l'enfant hérite d'une copie du descripteur de fichier
signalfd. Un appel à read(2) sur le descripteur de fichier depuis
l'enfant renverra des informations sur les signaux en attente pour l'enfant.
Sémantique pour passer un descripteur de fichier
Comme avec d'autres descripteurs de fichier, ceux de signalfd peuvent être
passés à un autre processus à l'aide d'un socket de domaine UNIX (voir
unix(7)). Dans le processus récepteur, un read(2) depuis le
descripteur de fichier reçu renverra des informations sur les signaux en
attente pour ce processus.
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 termes,
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 groupe de threads). Un thread ne sera pas capable de lire les
signaux qui sont envoyés aux autres threads du processus.
Sémantique d'epoll(7)
Si un processus ajoute (à l'aide d'epoll_ctl(2)) un descripteur de
fichier signalfd à une instance epoll(7), epoll_wait(2) ne renvoie des
événements que pour des signaux envoyés à ce processus. En particulier, si
le processus utilise alors fork(2) pour créer son enfant, celui-ci pourra
lire (read(2)) des signaux qui lui sont envoyés en utilisant le
descripteur de fichier signalfd, mais epoll_wait(2) n'indiquera pas
que le descripteur de fichier signalfd est prêt. Dans ce scénario, un
coutournement possible est qu'après le fork(2), le processus enfant
puisse fermer le descripteur de fichier signalfd dont il hérite du parent et
puis créer un autre descripteur de fichier signalfd et l'ajouter à
l'instance epoll. Autrement, le parent et l'enfant pourraient retarder la
création de leurs descripteurs de fichier signalfd (individuels) et les
ajouter à l'instance epoll jusqu'à la fin de l'appel fork(2).
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
antérieures, flags n'est pas nul.
- EMFILE
-
La limite du nombre de descripteurs de fichiers par processus a été
atteinte.
- ENFILE
-
La limite du nombre total de fichiers ouverts pour le système entier 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 depuis Linux 2.6.22. Une prise en charge
fonctionnelle est founie depuis la glibc 2.8. L'appel système signalfd4()
(voir NOTES) est disponible depuis Linux 2.6.27.
STANDARDS
signalfd() et signalfd4() sont spécifiques à Linux.
NOTES
Un processus peut créer plusieurs descripteurs de fichier signalfd. Cela
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.
Les tentatives pour inclure SIGKILL et SIGSTOP dans mask sont
ignorées silencieusement.
Le masque de signal utilisé par le descripteur de fichier signalfd peut être
visualisé à l'aide de l'entrée de descripteur de fichier correspondante du
répertoire /proc/pid/fdinfo du processus. Consultez proc(5) pour de
plus amples détails.
Limites
Le mécanisme signalfd ne peut pas être utilisé pour recevoir des signaux
générés de manière synchrone, tel que le signal SIGSEGV issu d'un accès
non valable à l'adresse de mémoire ou le signal SIGFPE qui provient d'une
erreur arithmétique. De tels signaux ne peuvent être récupérés que par un
gestionnaire de signal.
Comme décrit ci-dessus, en temps normal, on bloque les signaux qui seront
acceptés à l'aide de signalfd(). Si on force un processus enfant à
exécuter un programme d'aide (ce qui ne nécessite pas le descripteur de
fichier signalfd), alors après l'appel fork(2), vous voudrez débloquer
ces signaux, en principe, avant d'appeler execve(2), pour que le
programme d'aide puisse voir les signaux auxquels il s'attend.Gardez en
tête, toutefois, que cela ne sera pas possible dans le cas d'un programme
d'aide créé en tâche de fond par une fonction de bibliothèque que le
programme peut appeler. Dans ce cas-là, il faut se rabattre sur
l'utilisation d'un gestionnaire de signal traditionnel qui écrit sur un
descripteur de fichier surveillé par select(2), poll(2) ou
epoll(7).
différences entre bibliothèque C et noyau
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.
Il y a deux appels système sous-jacents : 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
Avant Linux 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).
EXEMPLES
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
haC # Contrôle-C génère un SIGINT
Got SIGINT
haC
Got SIGINT
ha\ # Contrôle-\ génère un SIGQUIT
Got SIGQUIT
$
Source du programme
#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/signalfd.h>
#include <unistd.h>
int
main(void)
{
int sfd;
ssize_t s;
sigset_t mask;
struct signalfd_siginfo fdsi;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
/* Bloquer les signaux pour qu'ils ne soient plus gérés
par les dispositifs par défaut */
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
err(EXIT_FAILURE, "sigprocmask");
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
err(EXIT_FAILURE, "signalfd");
for (;;) {
s = read(sfd, &fdsi, sizeof(fdsi));
if (s != sizeof(fdsi))
err(EXIT_FAILURE, "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
La traduction française de cette page de manuel a été créée par
Christophe Blaess <https://www.blaess.fr/christophe/>,
Stéphan Rafin <stephan.rafin@laposte.net>,
Thierry Vignaud <tvignaud@mandriva.com>,
François Micaux,
Alain Portal <aportal@univ-montp2.fr>,
Jean-Philippe Guérard <fevrier@tigreraye.org>,
Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>,
Julien Cristau <jcristau@debian.org>,
Thomas Huriaux <thomas.huriaux@gmail.com>,
Nicolas François <nicolas.francois@centraliens.net>,
Florentin Duneau <fduneau@gmail.com>,
Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,
Denis Barbier <barbier@debian.org>,
David Prévot <david@tilapin.org>,
Cédric Boutillier <cedric.boutillier@gmail.com>,
Frédéric Hantrais <fhantrais@gmail.com>
et
Jean-Philippe MENGUAL <jpmengual@debian.org>
Cette traduction est une documentation libre ; veuillez vous reporter à la
GNU General Public License version 3
concernant les conditions de copie et
de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message à
Index
- NOM
-
- BIBLIOTHÈQUE
-
- SYNOPSIS
-
- DESCRIPTION
-
- La structure signalfd_siginfo
-
- Sémantique de fork(2)
-
- Sémantique pour passer un descripteur de fichier
-
- Sémantique de execve(2)
-
- Sémantique des threads
-
- Sémantique d'epoll(7)
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- VERSIONS
-
- STANDARDS
-
- NOTES
-
- Limites
-
- différences entre bibliothèque C et noyau
-
- BOGUES
-
- EXEMPLES
-
- Source du programme
-
- VOIR AUSSI
-
- TRADUCTION
-
This document was created by
man2html,
using the manual pages.
Time: 04:53:59 GMT, May 18, 2024