sigreturn, rt_sigreturn - Revenir d'un gestionnaire de signaux et nettoyer la
pile
Bibliothèque C standard (
libc,
-lc)
int sigreturn(...);
Si le noyau Linux détermine qu'un signal non bloqué est en attente
d'un processus, au prochain retour en mode utilisateur de ce processus (par
exemple au retour d'un appel système ou quand le processus est
réordonnancé sur le processeur), il créera un nouvel
emplacement dans la pile de l'espace utilisateur où il enregistrera des
morceaux de contexte de processus (mot sur l'état du processeur,
registres, masque de signal et paramètres de la pile du signal).
Le noyau s'arrange aussi pour que, lors du retour à l'espace utilisateur,
le gestionnaire de signal soit appelé et pour qu'au retour du
gestionnaire, le contrôle soit redonné à un bout de code
de l'espace utilisateur appelé généralement le
« trampoline de signal ». En retour, ce code
appelle
sigreturn().
Cet appel à
sigreturn() défait tout ce qui a
été fait — modifier le masque de signaux du processus,
commutation des piles (consultez
sigaltstack(2)) — de
façon à invoquer le gestionnaire de signal. L'utilisation des
informations précédemment sauvegardées dans la pile de
l'espace utilisateur
sigreturn() restaure le masque de signal du
processus, commute les piles et restaure le contexte du processus (drappeaux
et registres du processeur, notamment le pointeur de la pile et les
instructions du pointeur), de sorte que le processus reprenne son
exécution au point où il a été interrompu par le
signal.
sigreturn() ne renvoit jamais.
De nombreux systèmes de type UNIX ont un appel système
sigreturn() ou presque équivalent. Cependant, cet appel n'est
pas spécifié dans POSIX et les détails de son
comportement varient en fonction des systèmes.
sigreturn() n'existe que pour permettre l'implémentation de
gestionnaires de signal. Il ne devrait
jamais être appelé
directement (en effet, une simple enveloppe
sigreturn() de la
bibliothèque GNU C renvoie simplement
-1 et
errno est
positionné sur
ENOSYS). Les détails des paramètres
(s'il y en a) passés à
sigreturn() varient selon
l'architecture (sur certaines architectures telles que x86-64,
sigreturn() ne prend aucun paramètre puisque toutes les
informations dont il a besoin sont disponibles dans la pile
créée précédemment par le noyau dans la pile de
l'espace utilisateur).
Autrefois, les systèmes UNIX mettaient le code du trampoline de signal
dans la pile utilisateur. De nos jours, les pages de la pile utilisateur sont
protégées pour interdire l'exécution d'un code. Ainsi,
sur les systèmes Linux contemporains, selon l'architecture, le code du
trampoline de signal réside soit dans le
vdso(7), soit dans la
bibliothèque C. Dans ce dernier cas, la fonction enveloppe
sigaction(2) de la bibliothèque C informe le noyau de
l'emplacement du code du trampoline en mettant son adresse dans le champ
sa_restorer de la structure
sigaction et il positonne le drapeau
SA_RESTORER dans le champ
sa_flags.
Les informations du contexte du processus sauvegardées vont dans la
structure
ucontext_t (consultez
<sys/ucontext.h>). Cette
structure est visible à l'intérieur du gestionnaire de signal
comme le troisième paramètre d'un gestionnaire mis en place
à l'aide de
sigaction(2) avec le drapeau
SA_SIGINFO.
Sur d'autres systèmes UNIX, l'opération de trampoline du signal
diffère quelque peu. En particulier, sur certains systèmes
où il y a une transition vers le retour à l'espace utilisateur,
le noyau donne le contrôle au trampoline (plutôt qu'au
gestionnaire de signal) et le code du trampoline appelle le gestionnaire de
signal (puis appelle
sigreturn() après le renvoi du gestionnaire
de signal).
L'appel système Linux d'origine s'appelait
sigreturn(). Toutefois,
avec l'arrivée des signaux en temps réel dans Linux 2.2,
un nouvel appel système,
rt_sigreturn(), a été
ajouté pour prendre en charge un type
sigset_t élargi. La
bibliothèque GNU C nous cache ces détails en appelant de
manière transparente
rt_sigreturn() quand le noyau le fournit.
kill(2),
restart_syscall(2),
sigaltstack(2),
signal(2),
getcontext(3),
signal(7),
vdso(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-Philippe
MENGUAL <
[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]