Provided by: manpages-pl-dev_4.27.0-1_all bug

NAZWA

       setjmp, sigsetjmp, longjmp, siglongjmp - przeprowadza nielokalne goto

BIBLIOTEKA

       Standardowa biblioteka C (libc, -lc)

SKŁADNIA

       #include <setjmp.h>

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

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

   Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

       setjmp(): patrz HISTORIA.

       sigsetjmp():
           _POSIX_C_SOURCE

OPIS

       Funkcje  opisane  w  niniejszym  podręczniku  służą  do  wykonywania  „nielokalnych  goto”: przeniesienia
       wykonania z jednej funkcji,  do  określonego  wcześniej  położenia  w  innej  funkcji.  Funkcja  setjmp()
       dynamicznie  określa  cel,  do  którego  zostanie  następnie  przeniesiona kontrola, a longjmp() dokonuje
       przeniesienia wykonania.

       Funkcja setjmp() zapisuje różne informacje o środowisku wywołującego  (zwykle  wskaźnik  stosu,  wskaźnik
       instrukcji,  ewentualnie  wartości  innych  rejestrów oraz maskę sygnałów) w buforze env, do późniejszego
       użytku przez longjmp(). W tym przypadku, setjmp() zwraca 0.

       Funkcja longjmp() używa informacji zapisanych w env do ponownego przeniesienia  kontroli  do  miejsca,  z
       którego  wywołano  setjmp()  i  przywrócenia  („przewinięcia  wstecz”)  stosu,  do  jego stanu w momencie
       wywołania setjmp(). Dodatkowo, w zależności od implementacji (zob. UWAGI i HISTORIA), wartości niektórych
       innych rejestrów i maska sygnałów procesu mogą być przywrócone do ich stanu z chwili wywołania setjmp().

       Po pomyślnym longjmp(), wykonanie kontynuuje, jak gdyby  setjmp()  powróciło  drugi  raz.  Ten  „udawany”
       powrót  można  rozróżnić  od  prawdziwego  wywołania  setjmp(),  ponieważ „udawany” powrót zwraca wartość
       przekazaną w val. Jeśli programista omyłkowo poda w val wartość 0, to „udawany” powrót zwróci w zamian 1.

   sigsetjmp() i siglongjmp()
       sigsetjmp() i siglongjmp() również wykonują nielokalne goto, lecz zapewniają przewidywalną obsługę  maski
       sygnałów procesu.

       Wtedy,  i  tylko  wtedy,  gdy  argument  savesigs  przekazany  do sigsetjmp jest niezerowy, bieżąca maska
       sygnałów procesu jest zachowywana w env i zostanie odtworzona przez późniejsze wykonanie  siglongjmp()  z
       tym samym env.

WARTOŚĆ ZWRACANA

       Przy bezpośrednim wywołaniu, setjmp() i sigsetjmp() zwracają 0; przy „udawanym” powrocie, który następuje
       po longjmp() lub siglongjmp(), zwracana jest wartość niezerowa przekazana w val.

       Funkcje longjmp() i siglongjmp() nie powracają.

ATRYBUTY

       Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).
       ┌──────────────────────────────────────────────────────────────┬────────────────────────┬───────────────┐
       │ InterfejsAtrybutWartość       │
       ├──────────────────────────────────────────────────────────────┼────────────────────────┼───────────────┤
       │ setjmp(), sigsetjmp()                                        │ Bezpieczeństwo wątkowe │ MT-bezpieczne │
       ├──────────────────────────────────────────────────────────────┼────────────────────────┼───────────────┤
       │ longjmp(), siglongjmp()                                      │ Bezpieczeństwo wątkowe │ MT-bezpieczne │
       └──────────────────────────────────────────────────────────────┴────────────────────────┴───────────────┘

STANDARDY

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

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

HISTORIA

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

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

       POSIX  nie  określa,  czy  setjmp()  zapisze  maskę  sygnałów (do późniejszego jej przywrócenia w trakcie
       longjmp()). W Systemie V nie ma to miejsca. W 4.3BSD tak się dzieje, występuje również funkcja _setjmp(),
       która tego nie robi. Zachowanie w Linuksie zależy od wersji glibc i ustawienia  makra  sprawdzania  cech.
       Przed  glibc  2.19,  setjmp() naśladuje domyślnie zachowanie Systemu V, a zachowanie BSD jest zapewniane,
       jeśli  makro  sprawdzania  cech  _BSD_SOURCE  jest  jawnie  zdefiniowane,  a  żadne   z:   _POSIX_SOURCE,
       _POSIX_C_SOURCE,  _XOPEN_SOURCE,  _GNU_SOURCE,  ani  _SVID_SOURCE  nie  jest zdefiniowane. Od glibc 2.19,
       <setjmp.h> ujawnia jedynie wersję  Systemu  V  setjmp().  Programy  potrzebujące  semantyki  BSD  powinny
       zastąpić wywołania do setjmp(), wywołaniami sigsetjmp() z niezerwoym argumentem savesigs.

UWAGI

       setjmp()  i longjmp() mogą być przydatne do radzenia sobie z błędami w głęboko zagnieżdżonych wywołaniach
       funkcji albo do umożliwienia procedurze obsługi sygnału do przekazania  kontroli  do  określonego  punktu
       programu, zamiast do powracania do punktu, gdzie procedura obsługi przerwała główny program. W tym drugim
       przypadku,  jeśli  chce  się  zachować i przywrócić maski sygnałów w sposób przenośny, należy korzystać z
       sigsetjmp() i siglongjmp(). Zob. też opis na temat czytelności programu poniżej.

ZASTRZEŻENIA

       Kompilator może dokonać optymalizacji zmiennych do rejestrów, a longjmp() może przywrócić wartości innych
       rejestrów oprócz wskaźnika stosu i licznika programu. Co za tym idzie, wartości automatycznych  zmiennych
       są nieokreślone po wywołaniu longjmp(), jeśli zostaną spełnione wszystkie poniższe kryteria:

       •  są lokalne w stosunku do funkcji, która wykonała odpowiednie wywołanie setjmp();

       •  ich wartości są zmienione pomiędzy wywołaniami do setjmp() i longjmp(); i

       •  nie są zadeklarowane jako volatile (ulotne).

       Te same uwagi stosują się do siglongjmp().

   Nielokalne goto i czytelność programu
       Choć  może  być  nadużywane,  tradycyjne  wyrażenie  „goto”  języka  C korzysta przynajmniej ze wskazówek
       leksykalnych (wyrażenie goto  i  docelowa  etykieta),  co  pozwala  programiście  łatwo  wyczuć  przepływ
       kontroli.  Nielokalne  goto nie zapewniają takich wskazówek, tej samej zmiennej jmp_buf może używać wiele
       wywołań setjmp(), tak więc zawartość zmiennej może się zmieniać w trakcie istnienia aplikacji. Co za  tym
       idzie,  programista  może  być  zmuszony do szczegółowej analizy kodu, aby określić dynamiczny cel danego
       wywołania longjmp() (aby ułatwić życie programiście, każde  wywołanie  setjmp()  powinno  mieć  unikatową
       zmienną jmp_buf).

       Dodatkową trudność stanowi fakt, że wywołania setjmp() i longjmp() nie muszą być nawet w tym samym module
       kodu źródłowego.

       Podsumowując,  nielokalne goto powodują, że programy są trudne do zrozumienia i utrzymywania, zatem jeśli
       jest to możliwe, należy używać innych rozwiązań.

   Niezdefiniowane zachowanie
       Jeśli funkcja, która wywołała setjmp()  powróci  przed  wywołaniem  longjmp(),  zachodzi  niezdefiniowane
       zachowanie. Na pewno wystąpi, mniejszy lub większy, chaos.

       Jeśli  w programie wielowątkowym, wywołanie longjmp() użyje bufora env, który był zainicjowany wywołaniem
       setjmp() w innym wątku, zachowanie jest niezdefiniowanie.

       POSIX.1-2008 Technical Corrigendum 2 dodaje longjmp() i siglongjmp() do listy funkcji  async-signal-safe.
       Jednak  standard  zaleca unikania korzystania z tych funkcji z procedur obsługi sygnału wskazując, że gdy
       funkcje  te  są  wywoływane  z  procedury  obsługi  sygnału,  który   przerwał   wywołanie   do   funkcji
       non-async-signal-safe  (lub odpowiednika, np. ekwiwalentne kroki do exit(3), które zachodzą przy powrocie
       z pierwotnego wywołania do  main()),  zachowanie  jest  niezdefiniowane,  gdy  program  wykona  następnie
       wywołanie do funkcji non-async-signal-safe. Jedynym sposobem uniknięcia niezdefiniowanego zachowania jest
       zapewnienie jednego z poniższych:

       •  Po  długim  skoku  z  pierwotnej  procedury  obsługi  sygnału,  program  nie  wywołuje żadnych funkcji
          non-async-signal-safe i nie powraca z pierwotnego wywołania do main().

       •  Wszelkie sygnały, których procedury obsługi wykonują długi skok, muszą być blokowane w trakcie każdego
          wywołania do funkcji non-async-signal-safe i żadna funkcja non-async-signal-safe nie może być wywołana
          po powrocie z pierwotnego wywołania do main().

ZOBACZ TAKŻE

       signal(7), signal-safety(7)

TŁUMACZENIE

       Tłumaczenie niniejszej strony podręcznika: Przemek Borys  <pborys@dione.ids.pl>,  Andrzej  Krzysztofowicz
       <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>

       Niniejsze  tłumaczenie  jest  wolną  dokumentacją.  Bliższe informacje o warunkach licencji można uzyskać
       zapoznając  się  z  GNU General Public License w wersji 3  lub  nowszej.   Nie   przyjmuje   się   ŻADNEJ
       ODPOWIEDZIALNOŚCI.

       Błędy  w  tłumaczeniu  strony  podręcznika  prosimy  zgłaszać  na  adres  listy  dyskusyjnej manpages-pl-
       list@lists.sourceforge.net.

Linux man-pages 6.9.1                          16 czerwca 2024 r.                                      setjmp(3)