signal – Panorama des signaux
Linux prend en charge à la fois les signaux POSIX classiques
(« ci-après signaux standard ») et les
signaux POSIX temps réel.
Chaque signal a une
action en vigueur qui détermine le
comportement du processus lorsqu'il reçoit ce signal.
Les éléments de la colonne « Action »
indiquent l'action par défaut pour chaque signal, avec la signification
suivante :
- Term
- Par défaut, terminer le processus.
- Ign
- Par défaut, ignorer le signal.
- Core
- Par défaut, terminer le processus et créer un
fichier d'image mémoire (consultez core(5)).
- Stop
- Par défaut, arrêter le processus.
- Cont
- Par défaut, continuer le processus s'il est
actuellement arrêté.
Un processus peut changer l’action d'un signal avec
sigaction(2)
ou
signal(2) (la deuxième option est moins portable quand un
gestionnaire de signal est défini ; consultez
signal(2)
pour plus de détails). Avec ces appels système, un processus
peut choisir de se comporter de l'une des façons suivantes lorsqu'il
reçoit un signal : effectuer l'action par défaut, ignorer
le signal ou intercepter le signal avec un
gestionnaire de signal,
c'est-à-dire une fonction définie par le programme qui est
invoquée automatiquement lorsque le signal est transmis.
Par défaut, le gestionnaire de signal est appelé sur la pile
normale des processus. Il est possible de prévoir que le gestionnaire
de signal utilise une autre pile ; consultez
sigaltstack(2) pour
une discussion sur comment faire cela et quand cela pourrait être
utile.
L’action d'un signal est un attribut du processus : dans une
application multithreadée, l’action d'un signal particulier est
la même pour tous les threads.
Un enfant créé par
fork(2) hérite d'une copie des
actions des signaux de son parent. Lors d'un
execve(2), les actions des
signaux pris en charge sont remises aux valeurs par défaut ; les
actions des signaux ignorés ne sont pas modifiées.
Les appels système et les fonctions de bibliothèque qui suivent
permettent à l'appelant d'envoyer un signal :
-
raise(3)
- Envoyer un signal au thread appelant.
-
kill(2)
- Envoyer un signal au processus indiqué, à
tous les membres du groupe de processus indiqué ou à tous
les processus du système.
-
pidfd_send_signal(2)
- Envoyer un signal à un processus identifié
par un descripteur de fichier de PID.
-
killpg(3)
- Envoyer un signal à tous les membres du groupe de
processus indiqué.
-
pthread_kill(3)
- Envoyer un signal au thread POSIX indiqué dans le
même processus que l'appelant.
-
tgkill(2)
- Envoyer un signal au thread indiqué à
l'intérieur d'un processus donné (c'est l'appel
système utilisé pour implémenter
pthread_kill(3)).
-
sigqueue(3)
- Envoyer un signal temps réel, avec ses
données jointes, au processus indiqué.
Les appels système suivants suspendent l'exécution du thread
appelant jusqu'à ce qu'un signal soit reçu (ou qu'un signal non
pris en charge termine le processus) :
-
pause(2)
- Suspendre l'exécution jusqu'à ce que
n'importe quel signal soit reçu.
-
sigsuspend(2)
- Changer temporairement le masque de signaux (voir
ci-dessous) et suspendre l'exécution jusqu'à ce qu'un des
signaux non masqué soit reçu.
Au lieu d’intercepter un signal de façon asynchrone avec un
gestionnaire de signal, il est possible de l’accepter de façon
synchrone, c'est-à-dire de bloquer l'exécution jusqu'à ce
que le signal soit distribué. À ce moment, le noyau renvoie des
informations concernant le signal à l'appelant. Il y a deux
façons générales pour faire cela :
- •
-
sigwaitinfo(2), sigtimedwait(2) et
sigwait(3) suspendent l'exécution jusqu'à ce qu'un
des signaux dans l'ensemble indiqué soit distribué. Chacun
de ces appels renvoie des informations concernant le signal
distribué.
- •
-
signalfd(2) renvoie un descripteur de fichier qui
peut être utilisé pour lire les informations concernant les
signaux qui sont distribués à l'appelant. Chaque
read(2) dans ce descripteur de fichier est bloquant jusqu'à
ce que un des signaux de l'ensemble indiqué dans l’appel
signalfd(2) soit distribué à l'appelant. Le tampon
renvoyé par read(2) contient une structure qui décrit
le signal.
Un signal peut être
bloqué, ce qui signifie qu'il ne sera
pas envoyé avant d'être débloqué. Entre le moment
de sa création et celui de son envoi, le signal est dit
en attente.
Chaque thread d'un processus a un
masque de signaux indépendant
qui indique l'ensemble des signaux bloqués par le thread. Un thread
peut modifier son masque de signaux avec
pthread_sigmask(3). Dans une
application traditionnelle à un seul thread,
sigprocmask(2) peut
être utilisée pour modifier le masque de signaux.
Un processus enfant créé avec
fork(2) hérite d'une
copie du masque de signaux de son parent. Le masque de signaux est
conservé au travers d'un
execve(2).
Un signal peut être « orienté
processus » ou « orienté
thread ». Un signal orienté processus est un signal qui
cible (et par conséquent en attente pour) le processus dans son entier.
Il peut l’être parce qu’il a été
généré par le noyau pour des raisons autres qu’une
exception matérielle ou parce qu’il a été
envoyé en utilisant
kill(2) ou
sigqueue(3). Un signal
orienté thread est destiné à un thread particulier. Un
tel signal peut l’être parce qu’il a été
généré en conséquence de l’exécution
d’une instruction spécifique de code machine qui est
déclenchée par une exception matérielle (par exemple,
SIGSEGV pour un accès mémoire non autorisé ou
SIGFPE pour une erreur mathématique) ou parce qu’il
visait un thread particulier en utilisant une interface telle que
tgkill(2) ou
pthread_kill(3).
Un signal orienté processus peut être délivré
à n’importe quel des threads qui n’ont pas
présentement le signal bloqué. Si plus d’un des threads a
le signal non bloqué, alors le noyau choisit un thread arbitraire
auquel délivrer le signal.
Un thread peut obtenir l'ensemble des signaux actuellement en attente en
utilisant
sigpending(2). Cet ensemble est l'union de l’ensemble
des signaux en attente orientés processus et l’ensemble des
signaux en attente pour le thread appelant.
Un enfant créé avec
fork(2) débute avec un ensemble
de signaux en attente vide. L'ensemble de signaux en attente est
conservé au travers d'un
execve(2).
À chaque transition d’une exécution en mode noyau vers une
en mode utilisateur (par exemple, lors du retour d’un appel
système ou l’ordonnancement d’un thread sur le CPU), le
noyau vérifie s’il existe un signal en attente non bloqué
pour lequel le processus a établi un gestionnaire de signal. Si un tel
signal est en attente, les étapes suivantes se
déroulent :
- (1)
- Le noyau réalise les étapes
préparatoires nécessaires pour l’exécution du
gestionnaire de signal :
- (1.1)
- Le signal est supprimé de l’ensemble des
signaux en attente.
- (1.2)
- Si le gestionnaire de signal a été
installé par un appel à sigaction(2) qui est
précisé par l’indicateur SA_ONSTACK et que le
thread a défini une pile de signaux de remplacement (en utilisant
sigaltstack(2)), alors cette pile est installée.
- (1.3)
- Diverses pièces du contexte relatif au signal sont
enregistrées dans une structure spéciale qui est
créée dans la pile. Les informations enregistrées
comprennent :
- •
- le registre de compteur du programme
(c’est-à-dire l’adresse de la prochaine instruction
dans le programme principal qui devrait être exécutée
lors du renvoi du gestionnaire de signal) ;
- •
- l’état du registre spécifique à
l’architecture nécessaire pour reprendre le programme
interrompu ;
- •
- le masque de signaux du thread actuel ;
- •
- les paramètres de la pile de signaux de remplacement
du thread.
- (Si le gestionnaire de signal a été
installé en utilisant l’indicateur SA_SIGINFO de
sigaction(2), alors les informations ci-dessus sont accessibles
à l’aide de l’objet ucontext_t qui est
pointé par le troisième argument du gestionnaire de
signal.)
- (1.4)
- Tout signal précisé dans
act->sa_mask lors de l’enregistrement du gestionnaire
avec sigprocmask(2) est ajouté au masque de signaux du
thread. Le signal à transmettre est aussi ajouté au masque
de signaux à moins que SA_NODEFER ait été
précisé lors de l’enregistrement du gestionnaire. Ces
signaux sont alors bloqués pendant que le gestionnaire
réalise l’exécution.
- (2)
- Le noyau construit une structure pour le gestionnaire de
signal sur la pile. Le noyau règle le compteur du programme pour le
thread pour pointer à la première instruction de la fonction
du gestionnaire de signal et configure l’adresse de retour pour
cette fonction pour pointer vers un élément du code de
l’espace utilisateur connu comme « trampoline de
signal » (décrit dans sigreturn(2)).
- (3)
- Le noyau repasse le contrôle à
l’espace utilisateur où l’exécution commence
au début de la fonction du gestionnaire de signal.
- (4)
- Au renvoi du gestionnaire de signal, le contrôle
passe au trampoline de signal.
- (5)
- Le trampoline de signal appelle sigreturn(2), un
appel système qui utilise les informations dans la structure de la
pile créée à la première étape pour
restaurer le thread dans son état avant que le gestionnaire de
signal ait été appelé. Les paramètres du
masque de signaux du thread et de la pile de signaux de remplacement sont
restaurés dans le cadre de cette procédure. À la fin
de l’appel à sigreturn(2), le noyau transfère
le contrôle à l’espace utilisateur et le thread
recommence l’exécution à partir du point où
elle a été interrompue par le gestionnaire de signal.
Remarquez que si le gestionnaire de signal ne renvoie pas (par exemple, le
contrôle est transféré en dehors du gestionnaire en
utilisant
siglongjmp(3) ou le gestionnaire exécute un nouveau
programme avec
execve(2)), alors l’étape finale
n’est par réalisée. En particulier, dans de tels
scénarios, c’est la responsabilité du programmeur de
restaurer l’état du masque de signaux (en utilisant
sigprocmask(2)) si le déblocage des signaux, qui étaient
bloqués par une entrée dans le gestionnaire de signal, est
désiré. (Notez que
siglongjmp(3) peut ou ne peut pas
restaurer le masque de signaux en fonction de la valeur
savesigs qui
était indiquée dans l’appel correspondant à
sigsetjmp(3).)
Du point de vue du noyau, l’exécution du code du gestionnaire de
signal est exactement la même que celle n’importe quel code de
l’espace utilisateur. C’est-à-dire que le noyau
n’enregistre aucune information spéciale d’état
indiquant que le thread est actuellement en exécution à
l’intérieur d’un gestionnaire de signal. Toutes les
informations d’état nécessaires sont entretenues dans des
registres de l’espace utilisateur et la pile de l’espace
utilisateur. La profondeur à laquelle les gestionnaires de signaux
imbriqués peuvent être invoqués est donc limitée
seulement par la pile de l’espace utilisateur (et une conception
logicielle raisonnable).
Linux prend en charge les signaux standard listés ci-dessous. La seconde
colonne du tableau indique quelle norme (si elle existe) décrit le
signal : « P1990 » indique que le signal
est décrit dans la norme POSIX.1-1990 originelle.
« P2001 » indique que le signal a
été ajouté dans SUSv2 et POSIX.1-2001.
Signal |
Norme |
Action |
Commentaire |
|
|
|
|
SIGABRT |
P1990 |
Core |
Signal d'arrêt d’abort(3) |
SIGALRM |
P1990 |
Term |
Signal de temporisation d’alarm(2) |
SIGBUS |
P2001 |
Core |
Erreur de bus (mauvais accès mémoire) |
SIGCHLD |
P1990 |
Ign |
Enfant arrêté ou terminé |
SIGCLD |
- |
Ign |
Synonyme pour SIGCHLD
|
SIGCONT |
P1990 |
Cont |
Continuer si arrêté |
SIGEMT |
- |
Term |
Interception (trap) d’émulateur |
SIGFPE |
P1990 |
Core |
Exception de virgule flottante |
SIGHUP |
P1990 |
Term |
Déconnexion détectée sur le terminal de |
|
|
|
contrôle ou mort du processus de contrôle |
SIGILL |
P1990 |
Core |
Instruction illégale |
SIGINFO |
- |
|
Synonyme pour SIGPWR
|
SIGINT |
P1990 |
Term |
Interruption depuis le clavier |
SIGIO |
- |
Term |
E/S maintenant possible (4.2BSD) |
SIGIOT |
- |
Core |
Interception IOT – synonyme pour SIGABRT
|
SIGKILL |
P1990 |
Term |
Signal d’arrêt |
SIGLOST |
- |
Term |
Perte de verrou de fichier (inutilisé) |
SIGPIPE |
P1990 |
Term |
Tube brisé : écriture dans un tube sans |
|
|
|
lecteur – voir pipe(7) |
SIGPOLL |
P2001 |
Term |
Événement scrutable (System V) |
|
|
|
– synonyme pour SIGIO
|
SIGPROF |
P2001 |
Term |
Fin d'une temporisation de profilage |
SIGPWR |
- |
Term |
Panne d'alimentation (System V) |
SIGQUIT |
P1990 |
Core |
Quitter depuis le clavier |
SIGSEGV |
P1990 |
Core |
Référence mémoire non valable |
SIGSTKFLT |
- |
Term |
Erreur de pile sur coprocesseur (inutilisé) |
SIGSTOP |
P1990 |
Stop |
Processus d’arrêt |
SIGTSTP |
P1990 |
Stop |
Stop saisi sur le terminal |
SIGSYS |
P2001 |
Core |
Mauvais appel système (SVr4) |
|
|
|
– voir aussi seccomp(2) |
SIGTERM |
P1990 |
Term |
Signal de fin |
SIGTRAP |
P2001 |
Core |
Interception pour trace ou pour point d’arrêt |
SIGTTIN |
P1990 |
Stop |
Entrée du terminal pour processus en arrière-plan |
SIGTTOU |
P1990 |
Stop |
Sortie du terminal pour processus en arrière-plan |
SIGUNUSED |
- |
Core |
Synonyme pour SIGSYS
|
SIGURG |
P2001 |
Ign |
Condition urgente sur un socket (4.2BSD) |
SIGUSR1 |
P1990 |
Term |
Signal utilisateur 1 |
SIGUSR2 |
P1990 |
Term |
Signal utilisateur 2 |
SIGVTALRM |
P2001 |
Term |
Horloge virtuelle d’alarme (4.2BSD) |
SIGXCPU |
P2001 |
Core |
Limite de temps CPU dépassée (4.2BSD) |
|
|
|
Consultez setrlimit(2) |
SIGXFSZ |
P2001 |
Core |
Taille de fichier excessive (4.2BSD) |
|
|
|
Consultez setrlimit(2) |
SIGWINCH |
- |
Ign |
Fenêtre redimensionnée (4.3BSD, Sun) |
Les signaux
SIGKILL et
SIGSTOP ne peuvent être ni
capturés, ni bloqués, ni ignorés.
Jusqu'à Linux 2.2 inclus, l'action par défaut pour
SIGSYS,
SIGXCPU,
SIGXFSZ et (sur les architectures autres
que SPARC ou MIPS)
SIGBUS était de terminer simplement le
processus, sans fichier image mémoire. (Sur certains UNIX, l'action par
défaut pour
SIGXCPU et
SIGXFSZ est de finir le processus
sans fichier image mémoire.) Linux 2.4 se conforme à
POSIX.1-2001 pour ces signaux et termine le processus avec un fichier image
mémoire.
SIGEMT n'est pas spécifié par POSIX.1-2001 mais
apparaît néanmoins sur la plupart des UNIX, avec une action par
défaut typique correspondant à une fin du processus avec fichier
image mémoire.
SIGPWR (non spécifié dans POSIX.1-2001) est typiquement
ignoré sur les autres UNIX où il apparaît.
SIGIO (non spécifié par POSIX.1-2001) est ignoré par
défaut sur plusieurs autres systèmes UNIX.
Si plusieurs signaux standard sont en attente pour un processus, l’ordre
dans lequel les signaux sont distribués n’est pas
précisé.
Les signaux standard ne sont pas mis en file d’attente. Si plusieurs
instances d’un signal standard sont générées
pendant que ce signal est bloqué, alors une seule instance du signal
est marquée comme en attente (et le signal sera distribué une
seule fois une fois débloqué). Dans le cas ou un signal standard
est déjà en attente, la structure
siginfo_t (consultez
sigaction(2)) associée à ce signal n’est pas
écrasée lors de l’arrivée d’instances
suivantes du même signal. Par conséquent, le processus recevra
les informations associées à la première instance du
signal.
La valeur numérique de chaque signal est donnée dans la table
ci-dessous. Comme montrés dans cette table, plusieurs signaux ont des
valeurs numériques différentes sur des architectures
différentes. La première valeur dans chaque ligne indique le
numéro de signal sur x86, ARM et la plupart des autres architectures.
La seconde valeur indique celui pour Alpha et SPARC. La troisième
indique celui de MIPS et la dernière celui de PA-RISC. Un tiret (-)
indique que le signal est absent sur l’architecture correspondante.
Signal |
x86/ARM et la |
Alpha/ |
MIPS |
PA-RISC |
Notes |
|
plupart des arch. |
SPARC |
|
|
|
|
|
|
|
|
|
SIGHUP |
1 |
1 |
1 |
1 |
|
SIGINT |
2 |
2 |
2 |
2 |
|
SIGQUIT |
3 |
3 |
3 |
3 |
|
SIGILL |
4 |
4 |
4 |
4 |
|
SIGTRAP |
5 |
5 |
5 |
5 |
|
SIGABRT |
6 |
6 |
6 |
6 |
|
SIGIOT |
6 |
6 |
6 |
6 |
|
SIGBUS |
7 |
10 |
10 |
10 |
|
SIGEMT |
- |
7 |
7 |
- |
|
SIGFPE |
8 |
8 |
8 |
8 |
|
SIGKILL |
9 |
9 |
9 |
9 |
|
SIGUSR1 |
10 |
30 |
16 |
16 |
|
SIGSEGV |
11 |
11 |
11 |
11 |
|
SIGUSR2 |
12 |
31 |
17 |
17 |
|
SIGPIPE |
13 |
13 |
13 |
13 |
|
SIGALRM |
14 |
14 |
14 |
14 |
|
SIGTERM |
15 |
15 |
15 |
15 |
|
SIGSTKFLT |
16 |
- |
- |
7 |
|
SIGCHLD |
17 |
20 |
18 |
18 |
|
SIGCLD |
- |
- |
18 |
- |
|
SIGCONT |
18 |
19 |
25 |
26 |
|
SIGSTOP |
19 |
17 |
23 |
24 |
|
SIGTSTP |
20 |
18 |
24 |
25 |
|
SIGTTIN |
21 |
21 |
26 |
27 |
|
SIGTTOU |
22 |
22 |
27 |
28 |
|
SIGURG |
23 |
16 |
21 |
29 |
|
SIGXCPU |
24 |
24 |
30 |
12 |
|
SIGXFSZ |
25 |
25 |
31 |
30 |
|
SIGVTALRM |
26 |
26 |
28 |
20 |
|
SIGPROF |
27 |
27 |
29 |
21 |
|
SIGWINCH |
28 |
28 |
20 |
23 |
|
SIGIO |
29 |
23 |
22 |
22 |
|
SIGPOLL |
|
|
|
|
Idem à SIGIO |
SIGPWR |
30 |
29/- |
19 |
19 |
|
SIGINFO |
- |
29/- |
- |
- |
|
SIGLOST |
- |
-/29 |
- |
- |
|
SIGSYS |
31 |
12 |
12 |
31 |
|
SIGUNUSED |
31 |
- |
- |
31 |
|
Il est à noter que :
- •
- si défini, SIGUNUSED est synonyme de
SIGSYS. Depuis la glibc 2.26, SIGUNUSED n’est
plus défini sur toutes les architectures ;
- •
- le signal 29 est SIGINFO/SIGPWR (synonymes
pour la même valeur) sur Alpha mais SIGLOST sur SPARC.
Starting with Linux 2.2, Linux supports real-time signals as originally defined
in the POSIX.1b real-time extensions (and now included in POSIX.1-2001). The
range of supported real-time signals is defined by the macros
SIGRTMIN
and
SIGRTMAX. POSIX.1-2001 requires that an implementation support at
least
_POSIX_RTSIG_MAX (8) real-time signals.
Le noyau Linux gère une gamme de 33 signaux temps réel
différents, numérotés de 32 à 64. Cependant,
l'implémentation des threads POSIX de la glibc utilise en interne deux
(pour l'implémentation NPTL) ou trois (pour l'implémentation
LinuxThreads) signaux temps réel (consultez
pthreads(7)) et
ajuste la valeur de
SIGRTMIN en conséquence (à 34 ou 35).
Comme la gamme de signaux temps réel varie en fonction de
l'implémentation des threads par la glibc (et cette
implémentation peut changer à l'exécution en fonction du
noyau et de la glibc) et que la gamme de signaux temps réel varie bien
sûr également suivant les systèmes UNIX, les programmes
ne devraient
jamais faire référence à des signaux
temps réel en utilisant des numéros codés en dur,
mais devraient toujours à la place utiliser des signaux temps
réel avec la notation
SIGRTMIN+n avec des vérifications
adéquates (lors de l'exécution) que
SIGRTMIN+n ne
dépasse pas
SIGRTMAX.
Contrairement aux signaux standard, les signaux temps réel n'ont pas de
signification prédéfinie : l'ensemble complet de ces
signaux peut être utilisé à des fins spécifiques
à l'application.
L'action par défaut pour un signal temps réel non
géré est de terminer le processus récepteur.
Les signaux temps réel se distinguent de la façon
suivante :
- •
- Plusieurs instances d'un signal temps réel peuvent
être mises en file d’attente. Au contraire, si plusieurs
instances d'un signal standard arrivent alors qu'il est
présentement bloqué, une seule instance sera mise en file
d’attente.
- •
- Si le signal est envoyé en utilisant
sigqueue(3), il peut être accompagné d'une valeur (un
entier ou un pointeur). Si le processus récepteur positionne un
gestionnaire pour ce signal en utilisant l'attribut SA_SIGINFO pour
l'appel sigaction(2), alors il peut accéder à la
valeur transmise dans le champ si_value de la structure
siginfo_t passée en second argument au gestionnaire. De
plus, les champs si_pid et si_uid de cette structure
fournissent le PID et l'UID réel du processus émetteur du
signal.
- •
- Les signaux temps réel sont délivrés
dans un ordre précis. Les divers signaux temps réel du
même type sont délivrés dans l'ordre où ils
ont été émis. Si différents signaux temps
réel sont envoyés au processus, ils sont
délivrés en commençant par le signal de numéro
le moins élevé (c’est-à-dire le signal de plus
fort numéro est celui de priorité la plus faible). Par
contre, si plusieurs signaux standard sont en attente pour un processus,
l'ordre dans lequel ils sont délivrés n'est pas
défini.
Si des signaux standard et des signaux temps réel sont
simultanément en attente pour un processus, POSIX ne précise pas
l'ordre de délivrance. Linux, comme beaucoup d'autres
implémentations, donne priorité aux signaux standard dans ce
cas.
According to POSIX, an implementation should permit at least
_POSIX_SIGQUEUE_MAX (32) real-time signals to be queued to a process.
However, Linux does things differently. Up to and including Linux 2.6.7, Linux
imposes a system-wide limit on the number of queued real-time signals for all
processes. This limit can be viewed and (with privilege) changed via the
/proc/sys/kernel/rtsig-max file. A related file,
/proc/sys/kernel/rtsig-nr, can be used to find out how many real-time
signals are currently queued. In Linux 2.6.8, these
/proc interfaces
were replaced by the
RLIMIT_SIGPENDING resource limit, which specifies
a per-user limit for queued signals; see
setrlimit(2) for further
details.
L’ajout de signaux temps réel nécessite
l’agrandissement de la structure de l’ensemble des signaux (
sigset_t) de 32 à 64 bits. Par conséquent, divers
appels système ont été supplantés par de nouveaux
appels système qui gèrent des ensembles de signaux plus grands.
Les anciens et nouveaux appels système sont les suivants :
Si un gestionnaire de signal est invoqué pendant qu'un appel
système ou une fonction de bibliothèque est bloqué,
alors :
- •
- soit l'appel est automatiquement redémarré
après le renvoi du gestionnaire de signal ;
- •
- soit l'appel échoue avec l'erreur EINTR.
Lequel de ces deux comportements se produira dépend de l'interface et de
si le gestionnaire de signal a été mis en place avec l'attribut
SA_RESTART (consultez
sigaction(2)). Les détails varient
selon les systèmes UNIX ; voici ceux pour Linux.
Si un appel en attente à l'une des interfaces suivantes est interrompu
par un gestionnaire de signal, l'appel sera automatiquement
redémarré après le renvoi du gestionnaire de signal si
l'attribut
SA_RESTART a été indiqué ;
autrement, l'appel échouera avec l'erreur
EINTR :
- •
- Appels read(2), readv(2), write(2),
writev(2) et ioctl(2) sur des périphériques
« lents ». Un périphérique
« lent » est un périphérique
où un appel d'E/S peut bloquer pendant un temps indéfini,
par exemple un terminal, un tube ou un socket. Si un appel d'E/S sur un
périphérique lent a déjà
transféré des données au moment où il est
interrompu par un gestionnaire de signal, l'appel renverra une indication
de succès (normalement, le nombre d'octets
transférés). Remarquez que selon cette définition, un
disque (local) n'est pas un périphérique lent. Les
opérations d’E/S sur les périphériques disque
ne sont pas interrompues par des signaux.
- •
-
open (2), s'il peut bloquer (par exemple, lors de
l'ouverture d'une FIFO ; consultez fifo(7)).
- •
-
wait(2), wait3(2), wait4(2),
waitid(2), et waitpid(2).
- •
- Interfaces de socket : accept(2),
connect(2), recv(2), recvfrom(2), recvmmsg(2),
recvmsg(2), send(2), sendto(2) et sendmsg(2),
à moins qu'une temporisation n'ait été placée
sur le socket (voir ci-dessous).
- •
- Interfaces de blocage de fichier : flock(2)
et les opérations F_SETLKW et F_OFD_SETLKW de
fcntl(2)
- •
- Interfaces de files de messages POSIX :
mq_receive(3), mq_timedreceive(3), mq_send(3) et
mq_timedsend(3).
- •
- Opération FUTEX_WAIT de futex(2)
(depuis Linux 2.6.22 ; auparavant, elle échouait
toujours avec l'erreur EINTR).
- •
-
getrandom(2).
- •
-
pthread_mutex_lock(3), pthread_cond_wait(3)
et autres API apparentées.
- •
-
FUTEX_WAIT_BITSET de futex(2.
- •
- Interfaces de sémaphores POSIX :
sem_wait(3) et sem_timedwait(3) (depuis
Linux 2.6.22 ; auparavant, elles échouaient toujours
avec l'erreur EINTR).
- •
-
read(2) d’un descripteur de fichier
d’inotify(7) (depuis Linux 3.8 ; auparavant,
elle échouait toujours avec l'erreur EINTR).
Les interfaces suivantes ne sont jamais relancées après avoir
été interrompues par un gestionnaire de signal, quelle que soit
l'utilisation de
SA_RESTART ; elles échouent toujours
avec l'erreur
EINTR lorsqu'elles sont interrompues par un gestionnaire
de signal :
- •
- Interfaces de socket
« entrée », quand un délai de
réception ( SO_RCVTIMEO) a été défini
sur le socket en utilisant setsockopt(2) : accept(2),
recv(2), recvfrom(2), recvmmsg(2) (aussi avec un
paramètre timeout non NULL) et recvmsg(2).
- •
- Interfaces de socket
« sortie », quand un délai de
réception ( SO_RCVTIMEO) a été défini
sur le socket en utilisant setsockopt(2) :
connect(2), send(2), sendto(2) et
sendmsg(2).
- •
- Interfaces utilisées pour attendre des
signaux : pause(2), sigsuspend(2),
sigtimedwait(2) et sigwaitinfo(2).
- •
- Interfaces de multiplexage de descripteurs de
fichier : epoll_wait(2), epoll_pwait(2),
poll(2), ppoll(2), select(2) et
pselect(2).
- •
- Interfaces IPC de System V :
msgrcv(2), msgsnd(2), semop(2) et
semtimedop(2).
- •
- Interfaces de sommeil : clock_nanosleep(2),
nanosleep(2) et usleep(3).
- •
-
io_getevents(2).
La fonction
sleep(3) n'est également jamais relancée si
elle est interrompue par un gestionnaire, mais elle renvoie une indication de
succès : le nombre de secondes restantes pour le sommeil.
In certain circumstances, the
seccomp(2) user-space notification feature
can lead to restarting of system calls that would otherwise never be restarted
by
SA_RESTART; for details, see
seccomp_unotify(2).
Sous Linux, même en l'absence de gestionnaire de signal, certaines
interfaces en mode bloquant peuvent échouer avec l'erreur
EINTR
après que le processus a été arrêté par
l'un des signaux d'arrêt et relancé avec le signal
SIGCONT. Ce comportement n'est pas ratifié par POSIX.1 et
n'apparaît pas sur d'autres systèmes.
Les interfaces Linux qui affichent ce comportement sont :
- •
- Interfaces de socket
« entrée », quand un délai de
réception ( SO_RCVTIMEO) a été défini
sur le socket en utilisant setsockopt(2) : accept(2),
recv(2), recvfrom(2), recvmmsg(2) (aussi avec un
paramètre timeout non NULL) et recvmsg(2).
- •
- Les interfaces de socket
« sortie », quand un délai de
réception ( SO_RCVTIMEO) a été défini
sur le socket en utilisant setsockopt(2) :
connect(2), send(2), sendto(2) et sendmsg(2),
si un délai de transmission ( SO_SNDTIMEO) a
été défini.
- •
-
epoll_wait(2), epoll_pwait(2).
- •
-
semop(2), semtimedop(2).
- •
-
sigtimedwait(2), sigwaitinfo(2).
- •
- Linux 3.7 et antérieurs :
read(2) sur un descripteur de fichier inotify(7).
- •
- Linux 2.6.21 et antérieurs :
opération FUTEX_WAIT de futex(2),
sem_timedwait(3), sem_wait(3).
- •
- Linux 2.6.8 et antérieurs :
msgrcv(2), msgsnd(2).
- •
- Linux 2.4 et antérieurs :
nanosleep(2).
POSIX.1, sauf indication contraire.
Pour une discussion sur les fonctions sûres de signal asynchrone,
consultez
signal-safety(7).
Le fichier
/proc/[pid]/task/[tid]/status contient divers champs qui
montrent les signaux qu’un thread bloque (
SigBlk), capture
(
SigCgt) ou ignore (
SigIgn). (L’ensemble des signaux qui
sont capturés ou ignorés sera le même pour tous les
threads d’un processus.) Les autres champs montrent l’ensemble
des signaux en attente qui sont orientés thread (
SigPnd) ainsi
que l’ensemble des signaux qui sont orientés processus dans leur
entier (
ShdPnd). Les champs correspondants dans
/proc/[pid]/status montrent les informations du thread principal.
Consultez
proc(5) pour d’autres détails.
Six signaux existent qui peuvent être délivrés à
cause d’une exception matérielle :
SIGBUS,
SIGEMT,
SIGFPE,
SIGILL,
SIGSEGV et
SIGTRAP.
Lequel de ces signaux est délivré pour n’importe quelle
exception matérielle n’est pas documenté et semble
parfois ne pas être logique.
Par exemple, un accès mémoire non autorisé qui provoque
l’envoi de
SIGSEGV sur une architecture peut provoquer
l’envoi de
SIGBUS sur une autre architecture ou vice versa.
Comme autre exemple, l’utilisation de l’instruction
int de
x86 avec un argument interdit (tout nombre autre que 3 ou 128) provoque
l’envoi de
SIGSEGV même si
SIGILL serait plus
adapté à cause de la façon dont le CPU rapporte
l’opération interdite au noyau.
kill(1),
clone(2),
getrlimit(2),
kill(2),
pidfd_send_signal(2),
restart_syscall(2),
rt_sigqueueinfo(2),
setitimer(2),
setrlimit(2),
sgetmask(2),
sigaction(2),
sigaltstack(2),
signal(2),
signalfd(2),
sigpending(2),
sigprocmask(2),
sigreturn(2),
sigsuspend(2),
sigwaitinfo(2),
abort(3),
bsd_signal(3),
killpg(3),
longjmp(3),
pthread_sigqueue(3),
raise(3),
sigqueue(3),
sigset(3),
sigsetops(3),
sigvec(3),
sigwait(3),
strsignal(3),
swapcontext(3),
sysv_signal(3),
core(5),
proc(5),
nptl(7),
pthreads(7),
sigevent(7)
La traduction française de cette page de manuel a été
créée par Christophe Blaess
<
https://www.blaess.fr/christophe/>, Stéphan Rafin
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]>,
Cédric Boutillier <
[email protected]>,
Frédéric Hantrais <
[email protected]> et Jean-Paul
Guillonneau <
[email protected]>
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 à
[email protected]