Provided by: manpages-pl-dev_4.23.1-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 UWAGI.

       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), 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

       Autorami  polskiego  tłumaczenia  niniejszej  strony   podręcznika   są:   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
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  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⟩.