Provided by: manpages-fr-dev_4.23.1-1_all bug

NOM

       setjmp, sigsetjmp, longjmp, siglongjmp - Effectuer un saut non local

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #include <setjmp.h>

       int setjmp(jmp_buf env);
       int sigsetjmp(sigjmp_buf env, int sauvsigs);

       [[noreturn]] void longjmp(jmp_buf env, int val);
       [[noreturn]] void siglongjmp(sigjmp_buf env, int val);

   Exigences    de    macros    de   test   de   fonctionnalités   pour   la   glibc   (consulter
   feature_test_macros(7)) :

       setjmp() : consultez la section NOTES.

       sigsetjmp():
           _POSIX_C_SOURCE

DESCRIPTION

       Les fonctions décrites dans cette page sont  utilisées  pour  effectuer  des  « sauts  non
       locaux » :  transfert  de  l'exécution  d'une fonction à un emplacement prédéterminé d'une
       autre fonction. La fonction setjmp() établit de façon dynamique l'emplacement vers  lequel
       le   contrôle   sera  transféré  ultérieurement  et  longjmp()  se  charge  de  transférer
       l'exécution.

       La fonction  setjmp()  sauvegarde  diverses  informations  concernant  l'environnement  de
       l'appelant  (typiquement  le  pointeur de pile, le pointeur d'instruction, potentiellement
       les valeurs d'autres registres ainsi que le masque de signaux) dans le tampon env pour son
       utilisation ultérieure par longjmp(). Dans ce cas, setjmp() renvoie 0.

       La  fonction  longjmp()  utilise  les  informations  stockées  dans env pour transférer le
       contrôle à l'endroit où setjmp() fut appelé et restaurer (« rewind ») la pile à  son  état
       lors  de l'appel à setjmp(). De plus, et en fonction de l'implémentation (voir NOTES), les
       valeurs d'autres registres et le masque de signaux du  processus  peuvent  également  être
       restaurées à leur état lors de l'appel à setjmp().

       Après  un  appel  réussi à longjmp(), l'exécution continue comme si setjmp() avait renvoyé
       une deuxième fois. Ce renvoi « factice » peut être distingué d'un vrai  appel  à  setjmp()
       car  il renvoie la valeur contenue dans val. Si le programmeur passe la valeur 0 à val par
       inadvertance, le renvoi « factice » retourne 1 à la place.

   sigsetjmp() et siglongjmp()
       sigsetjmp() et siglongjmp() effectuent également des sauts non locaux mais permettent  une
       gestion prévisible du masque de signaux du processus.

       Si,  et  seulement  si,  l'argument sauvsigs passé à sigsetjmp() est non nul, le masque de
       signaux actuel du processus est sauvegardé dans env et sera rétabli  lorsque  siglongjmp()
       sera invoquée avec ce contexte env.

VALEUR RENVOYÉE

       setjmp() et sigsetjmp() renvoient 0 lorsqu'elles sont appelées directement ; la valeur non
       nulle spécifiée dans val est renvoyée lors du renvoi « factice » qui se produit  après  un
       appel à longjmp() ou siglongjmp().

       Les fonctions longjmp() et siglongjmp() ne renvoient pas.

ATTRIBUTS

       Pour une explication des termes utilisés dans cette section, consulter attributes(7).

       ┌────────────────────────────────────────────────────────┬──────────────────────┬─────────┐
       │InterfaceAttributValeur  │
       ├────────────────────────────────────────────────────────┼──────────────────────┼─────────┤
       │setjmp(), sigsetjmp()                                   │ Sécurité des threads │ MT-Safe │
       ├────────────────────────────────────────────────────────┼──────────────────────┼─────────┤
       │longjmp(), siglongjmp()                                 │ Sécurité des threads │ MT-Safe │
       └────────────────────────────────────────────────────────┴──────────────────────┴─────────┘

STANDARDS

       setjmp()
       longjmp()
              C11, POSIX.1-2008.

       sigsetjmp()
       siglongjmp()
              POSIX.1-2008.

HISTORIQUE

       setjmp()
       longjmp()
              POSIX.1-2001, C89.

       sigsetjmp()
       siglongjmp()
              POSIX.1-2001.

       POSIX  ne  spécifie pas si setjmp() sauve le masque de signaux (pour être ensuite restauré
       lors de longjmp()). Sous System V, ce n'est pas le cas. Sous 4.3BSD, le masque sera  sauvé
       et il y a une fonction _setjmp qui ne fait pas la copie. Le comportement sous Linux dépend
       de la version  de  la  glibc  ainsi  que  de  la  configuration  des  macros  de  test  de
       fonctionnalités. Avant la glib 2.19, setjmp() suit le comportement de System V par défaut,
       mais le comportement BSD est fourni si la macro de test de fonctionnalités _BSD_SOURCE est
       définie et qu’aucune des macros _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _GNU_SOURCE
       ou _SVID_SOURCE n'est définie. Depuis la glibc 2.19, <setjmp.h> n’expose  que  la  version
       System V de setjmp(). Les programmes ayant besoin de la sémantique BSD devraient remplacer
       les appels de setjmp() par des appels de sigsetjmp() avec un argument sauvsigs non nul.

NOTES

       setjmp() et longjmp()  peuvent  être  utiles  pour  gérer  des  erreurs  dans  des  appels
       profondément imbriqués ou pour permettre à un gestionnaire de signal de passer le contrôle
       à un point précis du programme, plutôt que de renvoyer là où le gestionnaire a  interrompu
       le  programme principal. Dans ce dernier cas, si vous désirez sauvegarder et restaurer les
       masques de signaux de manière portable, utilisez sigsetjmp()  et  siglongjmp().  Consultez
       également la sous-section sur la lisibilité des programmes ci-dessous.

AVERTISSEMENTS

       Le  compilateur  peut  optimiser  certaines variables dans des registres et longjmp() peut
       restaurer les valeurs d'autres registres en plus des pointeurs de pile  et  d'instruction.
       Par  conséquent,  les  valeurs  de  variables automatiques ne sont pas spécifiées après un
       appel à longjmp() si elles satisfont à tous les critères suivants :

       -  elles sont locales à la fonction qui a effectué l'appel correspondant à setjmp() ;

       -  leur valeur est changée entre les appels à setjmp() et longjmp() ;

       -  elles ne sont pas déclarées comme volatile.

       Ces remarques s'appliquent aussi à siglongjmp().

   Sauts non locaux et lisibilité des programmes
       Bien que la déclaration C traditionnelle « goto »  puisse  être  exploitée,  elle  a  pour
       bénéfice  que  les  repères  lexicaux (la déclaration de saut ainsi que l'étiquette cible)
       permettent au programmeur de percevoir de façon claire le flux de contrôle. Les sauts  non
       locaux  ne  fournissent pas de tels repères : plusieurs appels à setjmp() peuvent utiliser
       la même variable jmp_buf de telle sorte que son contenu change au cours du déroulement  de
       l'application.  Par  conséquent, le programmeur peut être astreint à une lecture détaillée
       du code afin de déterminer la cible  dynamique  d'un  appel  longjmp()  particulier  (pour
       rendre  la  tâche du programmeur plus simple, chaque appel à setjmp() devrait utiliser une
       variable jmp_buf unique).

       De façon encore plus compliquée, les appels à setjmp() et longjmp() peuvent même  provenir
       de modules de code source différents.

       En résumé, les sauts non locaux peuvent rendre les programmes plus difficiles à comprendre
       et à maintenir, et une alternative devrait être utilisée lorsque c'est possible.

   Comportement indéfini
       Si la fonction qui a appelé setjmp() renvoie avant  que  longjmp()  ne  soit  appelée,  le
       comportement  n'est  pas défini. Une sorte de chaos plus ou moins subtil en résulterait de
       façon certaine.

       Si, dans un programme à plusieurs fils d'exécution, un appel à longjmp() utilise un tampon
       env   initialisé  préalablement  par  setjmp()  dans  un  fil  d'exécution  différent,  le
       comportement n'est pas défini.

       Le Technical Corrigendum 2 de POSIX.1-2008 ajoute longjmp() et siglongjmp() à la liste des
       fonctions  sûres  vis-à-vis  des signaux asynchrones. Cependant, la norme recommande de ne
       pas utiliser ces fonctions dans un gestionnaire de signal et indique ensuite  que  si  ces
       fonctions  sont  appelées depuis un gestionnaire de signal qui a interrompu un appel à une
       fonction non sûre vis-à-vis des signaux asynchrones (ou  similaire  tels  que  les  étapes
       équivalentes  à  exit(3)  se  produisant  après  un  renvoi de l'appel initial main()), le
       comportement n'est pas défini si le programme fait par la suite un appel  à  une  fonction
       non  sûre  vis-à-vis  des signaux asynchrones. La seule façon d'éviter ce comportement non
       défini est de s'assurer de la chose suivante :

       -  Après un saut non local depuis un gestionnaire de signal, le programme n'appelle pas de
          fonction  non  sûre  vis-à-vis des signaux asynchrones et ne renvoie pas depuis l'appel
          initial à main().

       -  Chaque signal dont le gestionnaire effectue un saut non local doit être bloqué lors  de
          chaque  appel  à  une  fonction  non  sûre  vis-à-vis des signaux asynchrones et aucune
          fonction non sûre vis-à-vis des signaux  asynchrones  n'est  appelée  après  un  renvoi
          depuis l'appel initial à main().

VOIR AUSSI

       signal(7), signal-safety(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>   et   Grégoire   Scano
       <gregoire.scano@malloc.fr>

       Cette  traduction  est  une  documentation libre ; veuillez vous reporter à la GNU General
       Public  License  version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   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 à ⟨debian-l10n-french@lists.debian.org⟩.