signal(2) System Calls Manual signal(2) NAZWA signal - obsluga sygnalow ANSI C BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); OPIS OSTRZEZENIE: zachowanie signal() rozni sie pomiedzy wersjami Uniksa i roznilo sie rowniez historycznie, pomiedzy roznymi wersjami Linuksa. Prosze go unikac: nalezy korzystac z sigaction(2). Zob. Przenosnosc ponizej. signal() ustawia dyspozycje sygnalu signum na handler, ktore wynosi SIG_IGN, SIG_DFL lub jest adresem funkcji zdefiniowanej przez programiste (,,procedura obslugi sygnalu"). Jesli sygnal signum jest dostarczany do procesu, to dzieje sie jedna z nastepujacych rzeczy: * Jesli dyspozycje ustawiono na SIG_IGN, to sygnal jest ignorowany. * Jesli dyspozycje ustawiono na SIG_DFL, to zachodzi domyslna akcja przypisana sygnalowi (zob. signal(7)). * Jesli dyspozycja jest ustawiona na funkcje, to na poczatku dyspozycja jest resetowana na SIG_DFL, albo sygnal jest blokowany (zob. Przenosnosc ponizej), a nastepnie wywolywany jest handler z argumentem signum. Jesli przywolanie procedury obslugi sygnalu powoduje zablokowanie sygnalu, to sygnal jest odblokowywany po powrocie z procedury obslugi. Sygnaly SIGKILL i SIGSTOP nie moga byc ani przechwycone, ani zignorowane. WARTOSC ZWRACANA signal() zwraca poprzednia wartosc procedury obslugi sygnalu. W przypadku bledu zwraca SIG_ERR i ustawia errno wskazujac blad. BLEDY EINVAL signum jest nieprawidlowy. WERSJE Uzycie sighandler_t jest rozszerzeniem GNU, ktore jest ujawnione, jesli zdefiniowano _GNU_SOURCE; glibc definiuje rowniez (pochodzace z BSD) sig_t, jesli zdefiniowano _BSD_SOURCE (glibc 2.19 i wczesniejsze) lub _DEFAULT_SOURCE (glibc 2.19 i pozniejsze). Bez korzystania z takiego typu, deklaracja signal() jest nieco trudniejsza do odczytania: void ( *signal(int signum, void (*handler)(int)) ) (int); Przenosnosc Jedynym przenosnym uzyciem signal() jest ustawienie dyspozycji sygnalu na SIG_DFL lub SIG_IGN. Semantyka korzystania z signal() do ustanowienia procedury obslugi sygnalu rozni sie miedzy systemami (i POSIX.1 wyraznie zezwala na to zroznicowanie); prosze nie uzywac go do tego celu. Norma POSIX.1 rozwiazala ten chaos zwiazany z przenosnoscia, przez ustanowienie sigaction(2), ktory zapewnia wyrazna kontrole semantyki, gdy przywolywana jest procedura obslugi sygnalu; dlatego nalezy korzystac z tego interfejsu, zamiast z signal(). STANDARDY C11, POSIX.1-2008. HISTORIA C89, POSIX.1-2001. W oryginalnych systemach UNIX, gdy przywolano obsluge sygnalu, ktora ustanowiono za pomoca signal(), dyspozycja sygnalu byla resetowana na SIG_DFL, a system nie blokowal dostarczania kolejnych wystapien sygnalu. Jest to rownowazne wywolaniu sigaction(2) z nastepujacymi znacznikami: sa.sa_flags = SA_RESETHAND | SA_NODEFER; System V rowniez udostepnia te semantyki signal(). Nie bylo to dobre rozwiazanie, poniewaz sygnal mogl byc dostarczony ponownie, przed tym, jak procedura obslugi sygnalu zdazyla sie ponownie zestawic. Co wiecej, szybkie wysylanie tego samego sygnalu, moglo skutkowac rekurencyjnemu przywolywaniu procedury obslugi. BSD poprawilo sytuacje, lecz przy okazji zmienilo niestety rowniez semantyke interfejsu signal(). W BSD, gdy przywolywana jest procedura obslugi sygnalu, dyspozycja sygnalu nie jest resetowana, a kolejne dostarczanie kolejnych wystapien sygnalu jest blokowane podczas wykonywania procedury obslugi. Co wiecej, niektore blokujace wywolania systemowe sa automatycznie restartowane, jesli zostana przerwane przez procedure obslugi sygnalu (zob. signal(7)). Semantyka BSD jest rownowazna wywolaniu sigaction(2) z nastepujacymi znacznikami: sa.sa_flags = SA_RESTART; Sytuacja w Linuksie wyglada nastepujaco: o Wywolanie systemowe signal() jadra udostepnia semantyke Systemu V. o Domyslnie, w glibc 2 i pozniejszych, funkcja opakowujaca signal() nie przywoluje wywolania systemowego jadra. Zamiast tego wywoluje sigaction(2) ze znacznikami zapewniajacymi semantyke BSD. To domyslne zachowanie jest udostepniane, jesli zdefiniowano odpowiednie makro: _BSD_SOURCE w glibc 2.19 i wczesniejszych lub _DEFAULT_SOURCE w glibc 2.19 i pozniejszych (domyslnie makra te sa zdefiniowanie, wiecej szczegolow w podreczniku feature_test_macros(7)). Jesli odpowiednie makro nie jest zdefiniowane, to signal() zapewnia semantyke Systemu V. UWAGI Wplyw signal() na procesy wielowatkowe jest niezdefiniowany. Zgodnie z POSIX, zachowanie procesu po zignorowaniu sygnalu SIGFPE, SIGILL lub SIGSEGV, niewygenerowanego przez kill(2) lub raise(3), jest niezdefiniowane. Dzielenie liczby calkowitej przez zero ma wynik niezdefiniowany. Na niektorych architekturach generuje sygnal SIGFPE (takze dzielenie najmniejszej ujemnej liczby calkowitej przez -1 moze wygenerowac SIGFPE). Ignorowanie go moze prowadzic do nieskonczonej petli. W podreczniku sigaction(2) opisano szczegoly tego, co dzieje sie gdy dyspozycje SIGCHLD ustawiono na SIG_IGN. Podrecznik signal-safety(7) zawiera liste funkcji async-signal-safe, ktore mozna bezpiecznie wywolac z procedury obslugi sygnalu. ZOBACZ TAKZE 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) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Przemek Borys , Andrzej Krzysztofowicz i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.8 2 maja 2024 r. signal(2)