plucky (3) longjmp.3.gz

Provided by: manpages-pl-dev_4.25.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(): see HISTORY.

       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.

       The longjmp()  function uses the information saved in env to transfer control back  to  the  point  where
       setjmp()   was called and to restore ("rewind") the stack to its state at the time of the setjmp()  call.
       In addition, and depending on the implementation (see NOTES  and  HISTORY),  the  values  of  some  other
       registers and the process signal mask may be restored to their state at the time of the setjmp()  call.

       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⟩.