signal(2)

NAZWA
signal - obsługa sygnałów ANSI C

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

SKŁADNIA
#include <signal.h>

typedef typeof(void (int))  *sighandler_t;

sighandler_t signal(int signum, sighandler_t handler);

OPIS
OSTRZEŻENIE: zachowanie signal() różni się pomiędzy wersjami Uniksa i różniło się również historycznie, pomiędzy różnymi wersjami Linuksa. Proszę go unikać: należy korzystać z sigaction(2). Zob. Przenośność poniżej.

signal() ustawia dyspozycję sygnału signum na handler, które wynosi SIG_IGN, SIG_DFL lub jest adresem funkcji zdefiniowanej przez programistę („procedura obsługi sygnału”).

Jeśli sygnał signum jest dostarczany do procesu, to dzieje się jedna z następujących rzeczy:

*   Jeśli dyspozycję ustawiono na SIG_IGN, to sygnał jest ignorowany.

*   Jeśli dyspozycję ustawiono na SIG_DFL, to zachodzi domyślna akcja przypisana sygnałowi (zob. signal(7)).

*   Jeśli dyspozycja jest ustawiona na funkcję, to na początku dyspozycja jest resetowana na SIG_DFL, albo sygnał jest blokowany (zob. Przenośność poniżej), a następnie wywoływany jest handler z argumentem signum. Jeśli przywołanie procedury obsługi sygnału powoduje zablokowanie sygnału, to sygnał jest odblokowywany po powrocie z procedury obsługi.

Sygnały SIGKILL i SIGSTOP nie mogą być ani przechwycone, ani zignorowane.

WARTOŚĆ ZWRACANA
signal() zwraca poprzednią wartość procedury obsługi sygnału. W przypadku błędu zwraca SIG_ERR i ustawia errno wskazując błąd.

BŁĘDY

EINVAL
    signum jest nieprawidłowy.

WERSJE
Użycie sighandler_t jest rozszerzeniem GNU, które jest ujawnione, jeśli zdefiniowano _GNU_SOURCE; glibc definiuje również (pochodzące z BSD) sig_t, jeśli zdefiniowano _BSD_SOURCE (glibc 2.19 i wcześniejsze) lub _DEFAULT_SOURCE (glibc 2.19 i późniejsze). Standardowa definicja signal() wygląda tak:

    typeof(void (int)) *signal(int signum, typeof(void (int)) *handler);

  Przenośność
Jedynym przenośnym użyciem signal() jest ustawienie dyspozycji sygnału na SIG_DFL lub SIG_IGN. Semantyka korzystania z signal() do ustanowienia procedury obsługi sygnału różni się między systemami (i POSIX.1 wyraźnie zezwala na to zróżnicowanie); proszę nie używać go do tego celu.

Norma POSIX.1 rozwiązała ten chaos związany z przenośnością, przez ustanowienie sigaction(2), który zapewnia wyraźną kontrolę semantyki, gdy przywoływana jest procedura obsługi sygnału; dlatego należy korzystać z tego interfejsu, zamiast z signal().

STANDARDY
C11, POSIX.1-2024.

HISTORIA
C89, POSIX.1-2001.

W oryginalnych systemach UNIX, gdy przywołano obsługę sygnału, którą ustanowiono za pomocą signal(), dyspozycja sygnału była resetowana na SIG_DFL, a system nie blokował dostarczania kolejnych wystąpień sygnału. Jest to równoważne wywołaniu sigaction(2) z następującymi znacznikami:

    sa.sa_flags = SA_RESETHAND | SA_NODEFER;

System V również udostępnia te semantyki signal(). Nie było to dobre rozwiązanie, ponieważ sygnał mógł być dostarczony ponownie, przed tym, jak procedura obsługi sygnału zdążyła się ponownie zestawić. Co więcej, szybkie wysyłanie tego samego sygnału, mogło skutkować rekurencyjnemu przywoływaniu procedury obsługi.

BSD poprawiło sytuację, lecz przy okazji zmieniło niestety również semantykę interfejsu signal(). W BSD, gdy przywoływana jest procedura obsługi sygnału, dyspozycja sygnału nie jest resetowana, a kolejne dostarczanie kolejnych wystąpień sygnału jest blokowane podczas wykonywania procedury obsługi. Co więcej, niektóre blokujące wywołania systemowe są automatycznie restartowane, jeśli zostaną przerwane przez procedurę obsługi sygnału (zob. signal(7)). Semantyka BSD jest równoważna wywołaniu sigaction(2) z następującymi znacznikami:

    sa.sa_flags = SA_RESTART;

Sytuacja w Linuksie wygląda następująco:

•   Wywołanie systemowe signal() jądra udostępnia semantykę Systemu V.

•   Domyślnie, w glibc 2 i późniejszych, funkcja opakowująca signal() nie przywołuje wywołania systemowego jądra. Zamiast tego wywołuje sigaction(2) ze znacznikami zapewniającymi semantykę BSD. To domyślne zachowanie jest udostępniane, jeśli zdefiniowano odpowiednie makro: _BSD_SOURCE w glibc 2.19 i wcześniejszych lub _DEFAULT_SOURCE w glibc 2.19 i późniejszych (domyślnie makra te są zdefiniowanie, więcej szczegółów w podręczniku feature_test_macros(7)). Jeśli odpowiednie makro nie jest zdefiniowane, to signal() zapewnia semantykę Systemu V.

UWAGI
Wpływ signal() na procesy wielowątkowe jest niezdefiniowany.

Zgodnie z POSIX, zachowanie procesu po zignorowaniu sygnału SIGFPE, SIGILL lub SIGSEGV, niewygenerowanego przez kill(2) lub raise(3), jest niezdefiniowane. Dzielenie liczby całkowitej przez zero ma wynik niezdefiniowany. Na niektórych architekturach generuje sygnał SIGFPE (także dzielenie najmniejszej ujemnej liczby całkowitej przez -1 może wygenerować SIGFPE). Ignorowanie go może prowadzić do nieskończonej pętli.

W podręczniku sigaction(2) opisano szczegóły tego, co dzieje się gdy dyspozycję SIGCHLD ustawiono na SIG_IGN.

Podręcznik signal-safety(7) zawiera listę funkcji async-signal-safe, które można bezpiecznie wywołać z procedury obsługi sygnału.

ZOBACZ TAKŻE
kill(1), alarm(2), kill(2), pause(2), sigaction(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), bsd_signal(3), killpg(3), raise(3), siginterrupt(3), sigqueue(3), sigsetops(3), sigvec(3), sysv_signal(3), signal(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 (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.