setjmp(3) Library Functions Manual setjmp(3) NOM setjmp, sigsetjmp, longjmp, siglongjmp - Effectuer un saut non local BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include 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 fonctionnalites pour la glibc (consulter feature_test_macros(7)) : setjmp() : consultez la section NOTES. sigsetjmp(): _POSIX_C_SOURCE DESCRIPTION Les fonctions decrites dans cette page sont utilisees pour effectuer des << sauts non locaux >> : transfert de l'execution d'une fonction a un emplacement predetermine d'une autre fonction. La fonction setjmp() etablit de facon dynamique l'emplacement vers lequel le controle sera transfere ulterieurement et longjmp() se charge de transferer l'execution. 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 ulterieure par longjmp(). Dans ce cas, setjmp() renvoie 0. La fonction longjmp() utilise les informations stockees dans env pour transferer le controle a l'endroit ou setjmp() fut appele et restaurer (<< rewind >>) la pile a son etat lors de l'appel a setjmp(). De plus, et en fonction de l'implementation (voir NOTES), les valeurs d'autres registres et le masque de signaux du processus peuvent egalement etre restaurees a leur etat lors de l'appel a setjmp(). Apres un appel reussi a longjmp(), l'execution continue comme si setjmp() avait renvoye une deuxieme fois. Ce renvoi << factice >> peut etre distingue d'un vrai appel a setjmp() car il renvoie la valeur contenue dans val. Si le programmeur passe la valeur 0 a val par inadvertance, le renvoi << factice >> retourne 1 a la place. sigsetjmp() et siglongjmp() sigsetjmp() et siglongjmp() effectuent egalement des sauts non locaux mais permettent une gestion previsible du masque de signaux du processus. Si, et seulement si, l'argument sauvsigs passe a sigsetjmp() est non nul, le masque de signaux actuel du processus est sauvegarde dans env et sera retabli lorsque siglongjmp() sera invoquee avec ce contexte env. VALEUR RENVOYEE setjmp() et sigsetjmp() renvoient 0 lorsqu'elles sont appelees directement ; la valeur non nulle specifiee dans val est renvoyee lors du renvoi << factice >> qui se produit apres un appel a longjmp() ou siglongjmp(). Les fonctions longjmp() et siglongjmp() ne renvoient pas. ATTRIBUTS Pour une explication des termes utilises dans cette section, consulter attributes(7). +---------------------------------+--------------------------+---------+ |Interface | Attribut | Valeur | +---------------------------------+--------------------------+---------+ |setjmp(), sigsetjmp() | Securite des threads | MT-Safe | +---------------------------------+--------------------------+---------+ |longjmp(), siglongjmp() | Securite 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 specifie pas si setjmp() sauve le masque de signaux (pour etre ensuite restaure lors de longjmp()). Sous System V, ce n'est pas le cas. Sous 4.3BSD, le masque sera sauve et il y a une fonction _setjmp qui ne fait pas la copie. Le comportement sous Linux depend de la version de la glibc ainsi que de la configuration des macros de test de fonctionnalites. Avant la glib 2.19, setjmp() suit le comportement de System V par defaut, mais le comportement BSD est fourni si la macro de test de fonctionnalites _BSD_SOURCE est definie et qu'aucune des macros _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _GNU_SOURCE ou _SVID_SOURCE n'est definie. Depuis la glibc 2.19, n'expose que la version System V de setjmp(). Les programmes ayant besoin de la semantique BSD devraient remplacer les appels de setjmp() par des appels de sigsetjmp() avec un argument sauvsigs non nul. NOTES setjmp() et longjmp() peuvent etre utiles pour gerer des erreurs dans des appels profondement imbriques ou pour permettre a un gestionnaire de signal de passer le controle a un point precis du programme, plutot que de renvoyer la ou le gestionnaire a interrompu le programme principal. Dans ce dernier cas, si vous desirez sauvegarder et restaurer les masques de signaux de maniere portable, utilisez sigsetjmp() et siglongjmp(). Consultez egalement la sous-section sur la lisibilite des programmes ci-dessous. CAVEATS 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 consequent, les valeurs de variables automatiques ne sont pas specifiees apres un appel a longjmp() si elles satisfont a tous les criteres suivants : - elles sont locales a la fonction qui a effectue l'appel correspondant a setjmp() ; - leur valeur est changee entre les appels a setjmp() et longjmp() ; - elles ne sont pas declarees comme volatile. Ces remarques s'appliquent aussi a siglongjmp(). Sauts non locaux et lisibilite des programmes Bien que la declaration C traditionnelle << goto >> puisse etre exploitee, elle a pour benefice que les reperes lexicaux (la declaration de saut ainsi que l'etiquette cible) permettent au programmeur de percevoir de facon claire le flux de controle. Les sauts non locaux ne fournissent pas de tels reperes : plusieurs appels a setjmp() peuvent utiliser la meme variable jmp_buf de telle sorte que son contenu change au cours du deroulement de l'application. Par consequent, le programmeur peut etre astreint a une lecture detaillee du code afin de determiner la cible dynamique d'un appel longjmp() particulier (pour rendre la tache du programmeur plus simple, chaque appel a setjmp() devrait utiliser une variable jmp_buf unique). De facon encore plus compliquee, les appels a setjmp() et longjmp() peuvent meme provenir de modules de code source differents. En resume, les sauts non locaux peuvent rendre les programmes plus difficiles a comprendre et a maintenir, et une alternative devrait etre utilisee lorsque c'est possible. Undefined Behavior Si la fonction qui a appele setjmp() renvoie avant que longjmp() ne soit appelee, le comportement n'est pas defini. Une sorte de chaos plus ou moins subtil en resulterait de facon certaine. Si, dans un programme a plusieurs fils d'execution, un appel a longjmp() utilise un tampon env initialise prealablement par setjmp() dans un fil d'execution different, le comportement n'est pas defini. Le Technical Corrigendum 2 de POSIX.1-2008 ajoute longjmp() et siglongjmp() a la liste des fonctions sures vis-a-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 appelees depuis un gestionnaire de signal qui a interrompu un appel a une fonction non sure vis-a-vis des signaux asynchrones (ou similaire tels que les etapes equivalentes a exit(3) se produisant apres un renvoi de l'appel initial main()), le comportement n'est pas defini si le programme fait par la suite un appel a une fonction non sure vis-a-vis des signaux asynchrones. La seule facon d'eviter ce comportement non defini est de s'assurer de la chose suivante : - Apres un saut non local depuis un gestionnaire de signal, le programme n'appelle pas de fonction non sure vis-a-vis des signaux asynchrones et ne renvoie pas depuis l'appel initial a main(). - Chaque signal dont le gestionnaire effectue un saut non local doit etre bloque lors de chaque appel a une fonction non sure vis-a-vis des signaux asynchrones et aucune fonction non sure vis-a-vis des signaux asynchrones n'est appelee apres un renvoi depuis l'appel initial a main(). VOIR AUSSI signal(7), signal-safety(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 et Gregoire Scano 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 setjmp(3)