signalfd(2) System Calls Manual signalfd(2) NOM signalfd - Creer un descripteur de fichier pour accepter des signaux BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include int signalfd(int fd, const sigset_t *mask, int flags); DESCRIPTION signalfd() cree un descripteur de fichier qui peut etre utilise pour accepter des signaux a destination de l'appelant. Cela fournit une alternative a l'utilisation d'un gestionnaire de signal ou de sigwaitinfo(2), et a l'avantage que le descripteur de fichier peut etre surveille avec select(2), poll(2) ou epoll(7). Le parametre mask specifie l'ensemble des signaux que l'appelant veut accepter par le descripteur de fichier. Ce parametre est un ensemble de signaux dont le contenu peut etre initialise en utilisant les macros decrites dans sigsetops(3). Normalement, l'ensemble des signaux recus par le descripteur de fichier devrait etre bloque en utilisant sigprocmask(2) pour eviter que les signaux soient pris en charge par les gestionnaires par defaut. Il n'est pas possible de recevoir les signaux SIGKILL ou SIGSTOP par un descripteur de fichier signalfd ; ces signaux sont silencieusement ignores s'ils sont specifies dans mask. Si le parametre fd vaut -1, alors l'appel cree un nouveau descripteur de fichier et y associe le signal defini dans mask. Si fd ne vaut pas -1 alors il doit indiquer un descripteur de fichier signalfd existant valable, et mask est utilise pour remplacer l'ensemble des signaux associes avec ce descripteur. A partir de Linux 2.6.27, les valeurs suivantes peuvent etre incluses avec un OU binaire dans flags pour changer le comportement de signalfd() : SFD_NONBLOCK Placer l'attribut d'etat de fichier O_NONBLOCK sur la description du fichier ouvert referencee par le nouveau descripteur de fichier (consulter open(2)). Utiliser cet attribut economise des appels supplementaires a fcntl(2) pour obtenir le meme resultat. 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 etre utile. Jusqu'a Linux 2.6.26, le parametre flags n'est pas utilise et doit valoir zero. signalfd() renvoie un descripteur de fichier qui gere les operations suivantes : read(2) Si un (ou plus) des signaux specifies dans mask est en attente pour le processus, alors le tampon fourni a read(2) est utilise pour renvoyer une structure (ou plus) de type signalfd_siginfo (voir ci-dessous) qui decrit 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 egale au nombre total d'octets lus. En consequence du read(2), les signaux sont consommes, de telle sorte qu'ils ne seront plus en attente pour le processus (c'est-a-dire qu'ils ne seront plus attrapes par les gestionnaires de signaux, et ne seront plus acceptes par sigwaitinfo(2)). Si aucun des signaux de mask ne sont en attente pour le processus, read(2) bloquera jusqu'a ce qu'un des signaux de mask soit genere pour le processus, ou echouera 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 parametre 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 gere egalement 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 necessaire il doit etre ferme. Quand tous les descripteurs de fichier associes au meme objet signalfd ont ete fermes, les ressources pour cet objet sont liberees par le noyau. La structure signalfd_siginfo Les structures signalfd_siginfo renvoyees par read(2) sur un descripteur de fichier signalfd sont au format suivant : struct signalfd_siginfo { uint32_t ssi_signo; /* Numero de signal */ int32_t ssi_errno; /* Numero d'erreur (pas utilise) */ int32_t ssi_code; /* Code du signal */ uint32_t ssi_pid; /* PID de l'emetteur */ uint32_t ssi_uid; /* UID reel de l'emetteur */ int32_t ssi_fd; /* Descripteur de fichier (SIGIO) */ uint32_t ssi_tid; /* Identifiant de la temporisation du noyau (timers POSIX) */ uint32_t ssi_band; /* Evenement de bande (SIGIO) */ uint32_t ssi_overrun; /* Compte des depassements de la temporisation POSIX */ uint32_t ssi_trapno; /* Numero de trappe ayant cause le signal */ int32_t ssi_status; /* Code de sortie ou signal (SIGCHLD) */ int32_t ssi_int; /* Entier envoye par sigqueue(3) */ uint64_t ssi_ptr /* Pointeur envoye par sigqueue(3) */ uint64_t ssi_utime; /* Temps CPU utilisateur consomme (SIGCHLD) */ uint64_t ssi_stime; /* Temps CPU systeme consomme (SIGCHLD) */ uint64_t ssi_addr; /* Adresse qui a genere le signal (pour les signaux issu du materiel) */ 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'a 128 octets (espace prevu pour des champs supplementaires futurs) */ }; Chacun des champs de cette structure est analogue aux champs de noms similaires d'une structure siginfo_t. La structure siginfo_t est decrite dans sigaction(2). Tous les champs de la structure signalfd_siginfo renvoyee ne seront pas valables pour un signal donne ; l'ensemble des champs valables peut etre determine grace 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 details. Semantique de fork(2) Apres un fork(2), l'enfant herite d'une copie du descripteur de fichier signalfd. Un appel a read(2) sur le descripteur de fichier depuis l'enfant renverra des informations sur les signaux en attente pour l'enfant. Semantique pour passer un descripteur de fichier Comme avec d'autres descripteurs de fichier, ceux de signalfd peuvent etre passes a un autre processus a l'aide d'un socket de domaine UNIX (voir unix(7)). Dans le processus recepteur, un read(2) depuis le descripteur de fichier recu renverra des informations sur les signaux en attente pour ce processus. Semantique de execve(2) Comme tout descripteur de fichier, un descripteur de fichier signalfd reste ouvert au travers d'un execve(2), a moins qu'il ait ete marque comme << close-on-exec >> (consultez fcntl(2)). Tout signal qui etait disponible en lecture avant un execve(2) reste disponible pour le nouveau programme. C'est analogue a la semantique traditionnelle des signaux, pour laquelle un signal bloque qui est en attente reste en attente au travers d'un execve(2). Semantique des threads La semantique des descripteurs de fichier signalfd dans un programme multithreade copie la semantique standard des signaux. En d'autres termes, quand un thread lit un descripteur de fichier signalfd, il lira les signaux qui sont envoyes pour le thread lui-meme ou pour le processus (c'est-a-dire l'ensemble du groupe de threads). Un thread ne sera pas capable de lire les signaux qui sont envoyes aux autres threads du processus. Semantique d'epoll(7) Si un processus ajoute (a l'aide d'epoll_ctl(2)) un descripteur de fichier signalfd a une instance epoll(7), epoll_wait(2) ne renvoie des evenements que pour des signaux envoyes a ce processus. En particulier, si le processus utilise alors fork(2) pour creer son enfant, celui-ci pourra lire (read(2)) des signaux qui lui sont envoyes en utilisant le descripteur de fichier signalfd, mais epoll_wait(2) n'indiquera pas que le descripteur de fichier signalfd est pret. Dans ce scenario, un coutournement possible est qu'apres le fork(2), le processus enfant puisse fermer le descripteur de fichier signalfd dont il herite du parent et puis creer un autre descripteur de fichier signalfd et l'ajouter a l'instance epoll. Autrement, le parent et l'enfant pourraient retarder la creation de leurs descripteurs de fichier signalfd (individuels) et les ajouter a l'instance epoll jusqu'a la fin de l'appel fork(2). VALEUR RENVOYEE S'il reussit, 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 etait 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 anterieures, flags n'est pas nul. EMFILE La limite du nombre de descripteurs de fichiers par processus a ete atteinte. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENODEV Impossible de monter (en interne) le peripherique anonyme d'inoeud. ENOMEM Pas assez de memoire pour creer le descripteur de fichier signalfd. VERSIONS Differences entre bibliotheque C et noyau L'appel systeme Linux sous-jacent necessite un parametre supplementaire, size_t sizemask, qui specifie la taille du parametre mask. La fonction enveloppe signalfd() de la glibc n'a pas ce parametre, puisqu'elle fournit ce parametre a l'appel systeme sous-jacent. Il y a deux appels systeme sous-jacents : signalfd() et signalfd4(), qui est plus recent. Le premier appel systeme n'implemente pas de parametre flags. Le dernier appel systeme implemente les valeurs de flags decrites ci-dessous. A partir de la glibc 2.9, la fonction enveloppe signalfd() utilisera signalfd4() quand il est disponible. STANDARDS Linux. HISTORIQUE signalfd() Linux 2.6.22, glibc 2.8. signalfd4() Linux 2.6.27. NOTES Un processus peut creer plusieurs descripteurs de fichier signalfd. Cela permet d'accepter differents signaux sur differents descripteurs de fichier (et peut etre utile si les descripteurs de fichier sont surveilles en utilisant select(2), poll(2) ou epoll(7) : l'arrivee de differents signaux rendra differents descripteurs de fichier disponibles). Si un signal apparait dans le mask de plusieurs descripteurs de fichier, un signal recu pourra etre lu (une seule fois) depuis n'importe lequel des descripteurs. Les tentatives pour inclure SIGKILL et SIGSTOP dans mask sont ignorees silencieusement. Le masque de signal utilise par le descripteur de fichier signalfd peut etre visualise a l'aide de l'entree de descripteur de fichier correspondante du repertoire /proc/pid/fdinfo du processus. Consultez proc(5) pour de plus amples details. Limites Le mecanisme signalfd ne peut pas etre utilise pour recevoir des signaux generes de maniere synchrone, tel que le signal SIGSEGV issu d'un acces non valable a l'adresse de memoire ou le signal SIGFPE qui provient d'une erreur arithmetique. De tels signaux ne peuvent etre recuperes que par un gestionnaire de signal. Comme decrit ci-dessus, en temps normal, on bloque les signaux qui seront acceptes a l'aide de signalfd(). Si on force un processus enfant a executer un programme d'aide (ce qui ne necessite pas le descripteur de fichier signalfd), alors apres l'appel fork(2), vous voudrez debloquer 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 tete, toutefois, que cela ne sera pas possible dans le cas d'un programme d'aide cree en tache de fond par une fonction de bibliotheque que le programme peut appeler. Dans ce cas-la, il faut se rabattre sur l'utilisation d'un gestionnaire de signal traditionnel qui ecrit sur un descripteur de fichier surveille par select(2), poll(2) ou epoll(7). BOGUES Avant Linux 2.6.25, les champs ssi_ptr et ssi_int n'etaient pas renseignes avec les donnees accompagnant un signal envoye par sigqueue(3). EXEMPLES Le programme ci-dessous accepte les signaux SIGINT et SIGQUIT en utilisant un descripteur de fichier signalfd. Le programme se termine apres avoir accepte le signal SIGQUIT. La session shell suivante montre l'utilisation du programme : $ ./signalfd_demo ^C # Controle-C genere un SIGINT Got SIGINT ^C Got SIGINT ^\ # Controle-\ genere un SIGQUIT Got SIGQUIT $ Source du programme #include #include #include #include #include #include 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 geres selon leur disposition par defaut */ 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("Lecture d'un signal imprevu\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 francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot , Cedric Boutillier , Frederic Hantrais et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 signalfd(2)