sigaction(2) System Calls Manual sigaction(2) NAZWA sigaction, rt_sigaction - bada i zmienia akcje sygnalu BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int sigaction(int signum, const struct sigaction *_Nullable restrict act, struct sigaction *_Nullable restrict oldact); Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)): sigaction(): _POSIX_C_SOURCE siginfo_t: _POSIX_C_SOURCE >= 199309L OPIS Wywolanie systemowe sigaction() jest uzywane do zmieniania akcji, ktora wykonuje proces po odebraniu okreslonego sygnalu (wprowadzenie do sygnalow mozna znalezc w podreczniku signals(7)). signum okresla sygnal i moze byc dowolnym prawidlowym sygnalem poza SIGKILL i SIGSTOP. Jesli act nie jest NULL-em, to nowa akcja dla sygnalu signum jest brana z act. Jesli oldact tez jest rozny od NULL, to poprzednia akcja jest w nim zachowywana. Struktura sigaction jest zdefiniowana jako: struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; Na niektorych architekturach czesc tej struktury moze byc unia: nie nalezy ustawiac jednoczesnie pol sa_handler oraz sa_sigaction. Pole sa_restorer nie jest przeznaczone do bezposredniego stosowania (POSIX nie okresla pola sa_restorer). Wiecej informacji o przeznaczeniu tego pola mozna znalezc w podreczniku sigreturn(2). sa_handler okresla akcje, jaka ma byc powiazana z signum i moze byc to jedna z: o SIG_DFL aby uzyskac domyslna akcje. o SIG_IGN aby ignorowac ten sygnal. o Wskaznik do funkcji obslugujacej sygnal. Funkcja ta ma tylko jeden argument, w ktorym bedzie przekazany numer sygnalu. Jesli w sa_flags poda sie SA_SIGINFO, to sa_sigaction (zamiast sa_handler) bedzie okreslalo funkcje obslugi sygnalu signum. Funkcja ta ma trzy argumenty, opisane ponizej. sa_mask okresla maske sygnalow, ktore powinny byc blokowane (tj. dodane do maski sygnalow watku, z ktorego sygnal zostal wywolany) podczas wywolywania funkcji obslugi sygnalow. Dodatkowo, sygnal, ktory wywolal te funkcje obslugi bedzie zablokowany, chyba ze uzyto znacznika SA_NODEFER. sa_flags podaje zbior znacznikow, ktore modyfikuja zachowanie procesu obslugi sygnalow. Jest to zbior wartosci polaczonych bitowym OR: SA_NOCLDSTOP Jesli signum jest rowne SIGCHLD, to nie sa odbierane powiadomienia o zatrzymaniu procesu potomnego (np. gdy potomek otrzyma jeden z SIGSTOP, SIGTSTP, SIGTTIN lub SIGTTOU) ani o jego wznowieniu (np. po otrzymaniu SIGCONT) (patrz wait(2)). Znacznik ten ma znaczenie tylko w przypadku ustawiania funkcji obslugi sygnalu SIGCHLD. SA_NOCLDWAIT (od Linuksa 2.6) Jesli signum jest rowny SIGCHLD, to potomkowie po swoim zakonczeniu nie zostana przeksztalceni w zombie. Patrz takze waitpid(2). Znacznik ma znaczenie tylko dla ustanawiania funkcji obslugujacej sygnal SIGCHLD lub podczas ustawiania tego sygnalu na SIG_DLF. Jesli znacznik SA_NOCLDWAIT jest ustawiony podczas ustanawiania funkcji obslugujacej sygnal SIGCHLD, to POSIX.1 nie okresla, czy sygnal SIGCHLD jest generowany po zakonczeniu procesu potomnego. Pod Linuksem sygnal SIGCHLD jest w takim przypadku generowany; niektore inne systemy go nie generuja. SA_NODEFER Nie dodaje sygnalu do maski sygnalow watku, gdy wykonywana jest funkcja obslugi sygnalu, chyba ze w act.sa_mask podano sygnal. Kolejne wystapienie sygnalu moze zatem byc dostarczone do watku, w czasie wykonywania funkcji obslugi sygnalu. Znacznik ten ma znaczenie tylko w przypadku ustanawiania funkcji obslugi sygnalu. SA_NOMASK jest przestarzalym, niestandardowym synonimem tego znacznika. SA_ONSTACK Wywoluje funkcje obslugi sygnalu, uzywajac alternatywnego stosu ustawionego przez sigaltstack(2). Jezeli ten alternatywny stos nie jest dostepny, zostanie uzyty stos domyslny. Znacznik ten ma znaczenie tylko w przypadku ustanawiania funkcji obslugi sygnalu. SA_RESETHAND Odtwarza akcje sygnalowa do stanu domyslnego po wejsciu funkcji obslugi sygnalu. Znacznik ten ma znaczenie tylko w przypadku ustanawiania funkcji obslugi sygnalu. SA_ONESHOT jest przestarzalym, niestandardowym synonimem tego znacznika. SA_RESTART Dostarcza zachowania kompatybilnego z semantyka sygnalowa BSD, czyniac pewne wywolania systemowe odtwarzalnymi przez sygnaly. Znacznik ten ma znaczenie podczas ustanawiania procedury obslugi sygnalu. Informacje na temat odtwarzania wywolan systemowych mozna znalezc w podreczniku signal(7). SA_RESTORER Nie jest przeznaczone do bezposredniego stosowania. Znacznik ten jest uzywany przez biblioteki C do wskazania, ze pole sa_restorer zawiera adres ,,trampoliny sygnalu". Wiecej szczegolow w podreczniku sigreturn(2). SA_SIGINFO (od Linuksa 2.2) Funkcja obslugi sygnalow pobiera trzy argumenty, a nie jeden. W tym przypadku zamiast ustawiac sa_handler nalezy ustawic sa_sigaction. Znacznik ten ma znaczenie tylko w przypadku ustanawiania funkcji obslugi sygnalu. SA_UNSUPPORTED (od Linuksa 5.11) Uzywany do dynamicznego sprawdzania obslugiwanych bitow znacznikow. Jesli proba zarejestrowania procedury obslugi -- z tym znacznikiem ustawionym w act->sa_flags wraz z innymi znacznikami, ktore moga byc nieobslugiwane przez jadro -- powiedzie sie, a najblizsze wywolanie sigaction(), ktore poda ten sam numer sygnalu z argumentem oldact innym niz NULL spowoduje wyczyszczenie SA_UNSUPPORTED z oldact->sa_flags, to oldact->sa_flags mozna uzyc jako mapy bitowej znacznikow wskazujacej, ktore z potencjalnie nieobslugiwanych znacznikow sa w rzeczywistosci obslugiwane. Wiecej informacji znajduje sie w rozdziale ,,Dynamiczne sprawdzanie obslugiwanych bitow znacznikow" ponizej. SA_EXPOSE_TAGBITS (od Linuksa 5.11) Przy dostarczaniu sygnalu, zestaw bitow znacznikow charakterystycznych dla architektury jest zwykle czyszczony z pola si_addr siginfo_t. Jesli ten znacznik jest ustawiony, podzbior bitow znacznikow charakterystycznych dla architektury zostanie zachowany w si_addr. Programy, ktore musza byc kompatybilne z wersjami Linuksa starszymi niz 5.11, musza uzyc SA_UNSUPPORTED aby sprawdzic dostepnosc obslugi tego znacznika. Argument siginfo_t do procedury obslugi SA_SIGINFO Gdy w act.sa_flags poda sie znacznik SA_SIGINFO, to adres procedury obslugi sygnalu jest przekazywany za pomoca pola act.sa_sigaction. Ta procedura obslugi przyjmuje trzy argumenty jak ponizej: void handler(int sig, siginfo_t *info, void *ucontext) { ... } Te trzy argumenty to: sig Numer sygnalu powodujacego przywolanie procedury obslugi. info Wskaznik do siginfo_t, ktory jest struktura zawierajaca dalsze informacje o sygnale, jak to opisano ponizej. ucontext Jest to wskaznik do struktury ucontext_t rzutowany na void *. Struktura, na ktora wskazuje to pole zawiera informacje o kontekscie sygnalu, ktore zostaly zachowanie w stosie w przestrzeni uzytkownika przez jadro; wiecej szczegolow w podreczniku sigreturn(2). Dalsze informacje o strukturze ucontext_t mozna odszukac w podrecznikach getcontext(3) i signal(7). Funkcja obslugi nie czyni zwykle zadnego uzytku z trzeciego argumentu. Typ danych siginfo_t jest struktura zawierajaca nastepujace pola: siginfo_t { int si_signo; /* Numer sygnalu */ int si_errno; /* Wartosc zmiennej errno */ int si_code; /* Kod sygnalu */ int si_trapno; /* Numer pulapki, ktore spowodowala sprzetowe wygenerowanie sygnalu (nieuzywane na wiekszosci architektur) */ pid_t si_pid; /* ID procesu wysylajacego */ uid_t si_uid; /* Rzeczywiste ID uzytk. procesu wysylajacego */ int si_status; /* Kod lub sygnal zakonczenia */ clock_t si_utime; /* Czas uzyty w przestrzeni uzytkownika */ clock_t si_stime; /* Czas uzyty przez system operacyjny */ union sigval si_value; /* Wartosc sygnalu */ int si_int; /* Sygnal POSIX.1b */ void *si_ptr; /* Sygnal POSIX.1b */ int si_overrun; /* Licznik przekr. czasom.; czasom POSIX.1b */ int si_timerid; /* ID czasomierza; czasom. POSIX.1b */ void *si_addr; /* Adres pamieci powodujacy blad */ long si_band; /* Grupa zdarzenia (byl int w glibc 2.3.2 i wczesniejszych) */ int si_fd; /* Deskryptor pliku */ short si_addr_lsb; /* Najmniej znaczacy bit adresu (od Linuksa 2.6.32) */ void *si_lower; /* Kres dolny przy wystapieniu naruszenia adresu (od Linuksa 3.19) */ void *si_upper; /* Kres gorny przy wystapieniu naruszenia adresu (od Linuksa 3.19) */ int si_pkey; /* Klucz zabezpieczajacy na PTE bedacy powodem bledu (od Linuksa 4.6) */ void *si_call_addr;/* Adres instrukcji wywolania systemowego (od Linuksa 3.5) */ int si_syscall; /* Liczba probowanych wywolan systemowych (od Linuksa 3.5) */ unsigned int si_arch; /* Architektura probowanego wywol. systemowego (od Linuksa 3.5) */ } si_signo, si_errno i si_code sa zdefiniowane dla wszystkich sygnalow. (Generalnie si_errno nie jest uzywane pod Linuksem). Pozostale pola struktury moga byc unia; powinno sie odczytywac tylko pola istotne dla danego sygnalu. o Sygnaly wyslane przez kill(2) i sigqueue(3) maja wypelnione pola si_pid oraz si_uid. Dodatkowo sygnaly wyslane przez sigqueue(3) maja w polach si_int i si_ptr ustawione wartosci podane przez nadawce sygnalu; szczegoly opisano w sigqueue(3). o Sygnaly wyslane przez czasomierze POSIX.1b (od Linuksa 2.6) maja uzupelnione pola si_overrun i si_timerid. Pole si_timerid zawiera wewnetrzny identyfikator uzywany przez jadro do identyfikacji czasomierza; nie jest to ten sam identyfikator, ktory zwraca timer_create(2). Pole si_overrun zawiera informacje o tym, ile razy czasomierz sie przepelnil -- jest to ta sama informacja, ktora zwraca timer_getoverrun(2). Pola te sa niestandardowymi rozszerzeniami Linuksa. o Sygnaly wyslane w celu notyfikacji kolejki komunikatow (patrz opis SIGEV_SIGNAL in mq_notify(3)) maja pola si_int/si_ptr wypelnione wartosciami sigev_value przekazanymi do mq_notify(3); ponadto si_pid zawiera identyfikator procesu wysylajacego sygnal, a si_uid rzeczywisty identyfikator uzytkownika - nadawcy sygnalu. o SIGCHLD ustawia pola si_pid, si_uid, si_status, si_utime i si_stime, dostarczajac informacji o procesie potomnym. Pole si_pid jest identyfikatorem potomka, si_uid jest rzeczywistym identyfikatorem uzytkownika procesu potomnego. Pole si_status zawiera kod zakonczenia potomka (jesli si_code jest rowne CLD_EXITED) lub numer sygnalu, ktory spowodowal zmiane stanu. Pola si_utime i si_stime zawieraja czasy spedzone przez potomka w przestrzeniach uzytkownika i systemowej; w przeciwienstwie do getrusage(2) i times(2), pola te nie zawieraja czasow oczekiwania na potomkow. Do Linuksa 2.6 oraz od Linuksa 2.6.27, pola zawieraja czas CPU w jednostkach sysconf(_SC_CLK_TCK). W Linuksie 2.6 przed Linuksem 2.6.27 z powodu bledu uzywane byly (konfigurowalne) jednostki jiffy (patrz time(7)). o SIGILL, SIGFPE, SIGSEGV, SIGBUS oraz SIGTRAP wypelniaja pole si_addr, ustawiajac w nim adres bledu. Na niektorych architekturach sygnaly wypelniaja takze pole si_trapno. Niektore bledy pochodne SIGBUS, w szczegolnosci BUS_MCEERR_AO i BUS_MCEERR_AR ustawiaja takze si_addr_lsb. Pole to oznacza najmniej znaczacy bit adresu, zatem i rozmiary uszkodzen. Na przyklad jesli cala strona zostala uszkodzona, si_addr_lsb zawierac bedzie log2(sysconf(_SC_PAGESIZE)). Gdy jako odpowiedz na zdarzenie ptrace(2) (PTRACE_EVENT_foo) zostanie dostarczony SIGTRAP, pole si_addr nie jest wypelnione, natomiast pola si_pid i si_uid sa wypelnione identyfikatorami odpowiednio procesu i uzytkownika odpowiedzialnego za dostarczenie pulapki. W przypadku seccomp(2) jako dostarczenie zdarzenia pokazany zostanie zrzut. BUS_MCERR_* i si_addr_lsb sa rozszerzeniami specyficznymi dla Linuksa. SEGV_BNDERR bedacy podbledem SIGSEGV wypelnia pola si_lower i si_upper. SEGV_PKUERR bedacy podbledem SIGSEGV wypelnia pole si_pkey. o SIGIO/SIGPOLL (te dwie nazwy sa synonimami pod Linuksem) wypelnia pola si_band i si_fd. Zdarzenie si_band jest maska bitowa zawierajaca te same wartosci, ktore poll(2) umieszcza w polu revents. Pole si_fd oznacza deskryptor pliku, na ktorym wystapilo dane zdarzenie wejscia/wyjscia; wiecej szczegolow w opisie F_SETSIG w podreczniku fcntl(2). o SIGSYS, generowany (od Linuksa 3.5) gdy filtr seccomp zwroci SECCOMP_RET_TRAP, wypelnia pola si_call_addr, si_syscall, si_arch, si_errno i inne, zgodnie z opisem z seccomp(2). Pole si_code Pole si_code, wewnatrz argumentu siginfo_t, ktore jest przekazywane do procedury obslugi sygnalu SA_SIGINFO, jest wartoscia (a nie maska bitowa) okreslajaca powod wyslania sygnalu. Dla zdarzenia ptrace(2), pole si_code bedzie zawierac SIGTRAP i miec zdarzenie ptrace w najwyzszym bajcie: (SIGTRAP | PTRACE_EVENT_foo << 8). Dla zdarzen innych niz ptrace(2), wartosci jakie moga wystapic w si_code sa opisane w pozostalej czesci niniejszego rozdzialu. Od glibc 2.20, definicje wiekszosci z tych symboli sa pozyskiwane z za pomoca definicji makr testowania cech (przed wlaczeniem jakiegokolwiek pliku naglowkowego), jak ponizej: o _XOPEN_SOURCE z wartoscia 500 lub wieksza; o _XOPEN_SOURCE i _XOPEN_SOURCE_EXTENDED; albo o _POSIX_C_SOURCE z wartoscia 200809L lub wieksza. Dla stalych TRAP_*, definicje symboli sa zapewnione jedynie w dwoch pierwszych przypadkach. Przed glibc 2.20, nie bylo konieczne ustawianie makr, do pozyskania tych symboli. W przypadku zwyklego sygnalu, ponizej zestawiono wartosci, ktore moga wystepowac w si_code dowolnego sygnalu razem z powodami, dla ktorych sygnal byl wygenerowany. SI_USER kill(2). SI_KERNEL Wysylany przez jadro. SI_QUEUE sigqueue(3). SI_TIMER Wygasl czasomierz POSIX lub setitimer(2) lub alarm(2). SI_MESGQ (od Linuksa 2.6.6) Zmiana stanu kolejki komunikatow POSIX; patrz mq_notify(3) SI_ASYNCIO Ukonczenie asynchronicznej operacji wejscia/wyjscia. SI_SIGIO Kolejkowany SIGIO (tylko do Linuksa 2.2; od Linuksa 2.4 SIGIO/SIGPOLL wypelniaja si_code, tak jak to opisano ponizej). SI_TKILL (od Linuksa 2.4.19) tkill(2) lub tgkill(2) Nastepujace wartosci moga zostac umieszczone w si_code sygnalu SIGILL: ILL_ILLOPC Niedozwolony kod operacji. ILL_ILLOPN Niedozwolony operand. ILL_ILLADR Niedozwolony tryb adresowania. ILL_ILLTRP Niedozwolona pulapka. ILL_PRVOPC Uprzywilejowany kod operacji. ILL_PRVREG Uprzywilejowany rejestr. ILL_COPROC Blad koprocesora. ILL_BADSTK Wewnetrzny blad stosu. Nastepujace wartosci moga zostac umieszczone w si_code sygnalu SIGFPE: FPE_INTDIV Dzielenie wartosci calkowitej przez zero. FPE_INTOVF Przepelnienie liczby calkowitej. FPE_FLTDIV Dzielenie wartosci zmiennoprzecinkowej przez zero. FPE_FLTOVF Przekroczenie zakresu operacji zmiennoprzecinkowej. FPE_FLTUND Przekroczenie (w dol) zakresu operacji zmiennoprzecinkowej. FPE_FLTRES Niedokladny wynik operacji zmiennoprzecinkowej. FPE_FLTINV Niepoprawna operacja zmiennoprzecinkowa. FPE_FLTSUB Dolny indeks poza zakresem. Nastepujace wartosci moga zostac umieszczone w si_code sygnalu SIGSEGV: SEGV_MAPERR Adres niemapowany do obiektu. SEGV_ACCERR Niepoprawne uprawnienia mapowanego obiektu. SEGV_BNDERR (od Linuksa 3.19) Niepowodzenie sprawdzenia przypisania adresu. SEGV_PKUERR (od Linuksa 4.6) Dostep zostal odmowiony przez klucze zabezpieczen pamieci. Zob. pkeys(7). Klucz zabezpieczen, jaki zastosowano do tego dostepu jest dostepny za pomoca si_pkey. Nastepujace wartosci moga zostac umieszczone w si_code sygnalu SIGBUS: BUS_ADRALN Niepoprawne wyrownanie adresu. BUS_ADRERR Nieistniejacy adres fizyczny. BUS_OBJERR Blad sprzetowy specyficzny dla obiektu. BUS_MCEERR_AR (od Linuksa 2.6.32) Sprzetowy blad pamieci podczas sprawdzania komputera; wymagane podjecie akcji. BUS_MCEERR_AO (od Linuksa 2.6.32) Wykryto sprzetowy blad pamieci w procesie; opcjonalne podjecie akcji. Nastepujace wartosci moga zostac umieszczone w si_code sygnalu SIGTRAP: TRAP_BRKPT Punkt wstrzymania procesu. TRAP_TRACE Sledzony proces zlapany. TRAP_BRANCH (od Linuksa 2.4, tylko IA64) Sledzone rozgalezienie procesu zlapane. TRAP_HWBKPT (od Linuksa 2.4, tylko IA64) Pulapka sprzetowa. Nastepujace wartosci moga zostac umieszczone w si_code sygnalu SIGCHLD: CLD_EXITED Proces potomny sie zakonczyl. CLD_KILLED Proces potomny zostal zabity. CLD_DUMPED Potomek zakonczyl sie w nieprawidlowy sposob. CLD_TRAPPED Sledzony potomek zostal zlapany. CLD_STOPPED Proces potomny zostal zatrzymany. CLD_CONTINUED (od Linuksa 2.6.9) Zatrzymany proces potomny zostal wznowiony. Nastepujace wartosci moga zostac umieszczone w si_code sygnalu SIGIO/SIGPOLL: POLL_IN Dostepne dane na wejsciu. POLL_OUT Dostepne bufory wyjscia. POLL_MSG Dostepna wiadomosc na wejsciu. POLL_ERR Blad wejscia/wyjscia. POLL_PRI Dostepne wejscie o wysokim priorytecie. POLL_HUP Urzadzenie odlaczone. Nastepujaca wartosc moze zostac umieszczona w si_code sygnalu SIGSYS: SYS_SECCOMP (od Linuksa 3.5) Wyzwolone przez regule filtra seccomp(2). Dynamiczne sprawdzanie obslugiwanych bitow znacznikow Wywolanie sigaction() w Linuksie akceptuje nieznane bity ustawione w act->sa_flags nie zglaszajac bledu. Zachowanie jadra, od Linuksa 5.11 jest takie, ze drugie sigaction() wyczysci nieznane bity z oldact->sa_flags. Jednak historycznie, drugie wywolanie zwykle pozostawialo te bity ustawione w oldact->sa_flags. Oznacza to, ze nie da sie wykryc obslugi nowych znacznikow jedynie sprawdzajac znacznik w sa_flags, lecz konieczne jest sprawdzenie, czy SA_UNSUPPORTED zostalo wyczyszczone, przed poleganiem na zawartosci sa_flags. Poniewaz zachowania procedury obslugi sygnalu nie mozna zagwarantowac, jesli nie dokonano sprawdzenia, powinno sie albo blokowac dany sygnal podczas rejestrowania procedury obslugi i wykonac w takim przypadku sprawdzenie, albo -- tam, gdzie nie jest to mozliwe, np. gdy sygnal jest asynchroniczny -- wywolac sigaction() po raz drugi z samej procedury obslugi sygnalu. W jadrach nieobslugujacych danego znacznika, jadro zachowa sie tak, jakby znacznik ten nie byl ustawiony, nawet jesli znacznik byl ustawiony w act->sa_flags. Znacznikow SA_NOCLDSTOP, SA_NOCLDWAIT, SA_SIGINFO, SA_ONSTACK, SA_RESTART, SA_NODEFER, SA_RESETHAND i, jesli jest zdefiniowany na danej architekturze, SA_RESTORER nie da sie wiarygodnie sprawdzic za pomoca opisywanego mechanizmu, poniewaz zostaly one wprowadzone przez Linuksem 5.11. Zwykle jednak, programy moga przyjac, ze znaczniki te sa obslugiwane, poniewaz wszystkie byly obslugiwane juz od Linuksa 2.6, wydanego w roku 2003. W rozdziale PRZYKLADY ponizej, zademonstrowano korzystanie z SA_UNSUPPORTED. WARTOSC ZWRACANA sigaction() w przypadku powodzenia zwraca 0. W razie wystapienia bledu zwracane jest -1 i ustawiana jest zmienna errno wskazujac na blad. BLEDY EFAULT act lub oldact wskazuja na pamiec poza przestrzenia adresowa procesu. EINVAL Podano nieprawidlowy sygnal. Bedzie to tez generowane w przypadku proby zmienienia akcji dla sygnalow SIGKILL lub SIGSTOP, ktore nie moga byc przechwycone lub zignorowane. WERSJE Roznice biblioteki C/jadra Funkcja opakowujaca glibc dla sigaction() daje blad (EINVAL) przy probie zmiany dyspozycji dwoch sygnalow czasu rzeczywistego uzywanych wewnetrznie przez implementacje watkowa NPTL. Wiecej szczegolow w podreczniku nptl(7). Na architekturach, na ktorych trampolina sygnalu jest zawarta w bibliotece C, funkcja opakowujace sigaction() z glibc, umieszcza adres kodu trampoliny w polu act.sa_restorer i ustawia znacznik SA_RESTORER w polu act.sa_flags. Zob. sigreturn(2). Oryginalne linuksowe wywolanie systemowe nazywalo sie sigaction(). Jednak po pojawieniu sie sygnalow czasu rzeczywistego w Linuksie 2.2, 32-bitowy typ sigset_t o stalym rozmiarze obslugiwany przez to wywolanie przestal dobrze sluzyc swemu zadaniu. Z tego powodu, w celu obslugi powiekszonego typu sigset_t dodano nowe wywolanie systemowe rt_sigaction(). Nowe wywolanie przyjmuje czwarty argument size_t sigsetsize, ktory okresla rozmiar w bajtach zestawu sygnalow w act.sa_mask i oldact.sa_mask. Argument ten obecnie musi miec wartosc sizeof(sigset_t) (albo nastapi blad EINVAL). Opakowanie glibc sigaction() ukrywa te detale przed nami, po cichu wywolujac rt_sigaction() jesli udostepnia je jadro. STANDARDY POSIX.1-2008. HISTORIA POSIX.1-2001, SVr4. POSIX.1-1990 zabranial ustawiania akcji dla SIGCHLD na SIG_IGN. POSIX.1-2001 i pozniejsze pozwalaja na to, tak ze mozna uzyc ignorowania SIGCHLD, zeby zapobiec tworzeniu procesow zombie (patrz wait(2)). Niemniej jednak, historyczne zachowanie systemow BSD i System V w zakresie ignorowania SIGCHLD jest inne, tak wiec jedyna calkowicie przenosna metoda zapewnienia, ze potomek po zakonczeniu nie zostanie procesem zombie jest przechwytywanie sygnalu SIGCHLD i wywolanie funkcji wait(2) lub podobnej. POSIX.1-1990 okreslal tylko SA_NOCLDSTOP. W POSIX.1-2001 dodano SA_NOCLDWAIT, SA_NODEFER, SA_ONSTACK, SA_RESETHAND, SA_RESTART i SA_SIGINFO jako rozszerzenia XSI. POSIX.1-2008 przeniosl SA_NODEFER, SA_RESETHAND, SA_RESTART i SA_SIGINFO do glownej normy. Uzywanie tych nowych wartosci sa_flags moze byc mniej przenosne w aplikacjach przewidzianych do uzycia w starszych implementacjach Uniksa. Znacznik SA_RESETHAND jest kompatybilny ze znacznikiem w SVr4 o tej samej nazwie. Znacznik SA_NODEFER jest kompatybilny z podobnym znacznikiem z SVr4 dla Linuksa 1.3.9 i nowszych. Na starszych jadrach implementacja Linuksa pozwalala na otrzymanie dowolnego sygnalu, nie tylko tego instalowanego (w praktyce przeslaniajac ustawienie sa_mask). UWAGI Potomek utworzony przez fork(2) dziedziczy kopie ustawien sygnalow od swojego rodzica. Podczas wywolania execve(2) przywracane sa wartosci domyslne ustawien, z wyjatkiem ustawienia ignorowania sygnalu, ktore nie jest zmieniane. 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. sigaction() moze byc wywolywany z drugim argumentem o wartosci NULL, powodujac w ten sposob zapytanie o biezaca procedure obslugi sygnalu. Moze go tez uzyc do sprawdzenia, czy dany sygnal jest prawidlowy na obecnej maszynie. W tym celu nalezy zarowno drugi, jak i trzeci argument ustawic na NULL. Nie mozna zablokowac sygnalow SIGKILL lub SIGSTOP (przez podanie ich w sa_mask). Proby takie zostana zignorowane. Zobacz sigsetops(3) dla szczegolow o operacjach na zbiorach sygnalow. Liste funkcji, ktore sa async-signal-safe i mozna je bezpiecznie wywolac w procedurze obslugi sygnalu, mozna znalezc w podreczniku signal-safety(7). POSIX gwarantuje jedynie SI_TIMER w przypadku sygnalow utworzonych za pomoca timer_create(2). Implementacje moga go dostarczac rowniez w przypadku innych typow czasomierzy. Zachowanie Linuksa odpowiada NetBSD. Nieudokumentowane Przed wprowadzeniem SA_SIGINFO rowniez bylo mozliwe otrzymanie pewnych dodatkowych informacji o sygnale. Dzialo sie to poprzez uzycie procedury obslugi sygnalu sa_handler z drugim argumentem, bedacym typu struct sigcontext, ktory jest taka sama struktura jak ta przekazywana w polu uc_mcontext struktury ucontext, przekazywanym (wskaznikiem) w trzecim argumencie procedury obslugi sa_sigaction. Szczegoly mozna znalezc w odpowiednich zrodlach jadra Linux. To uzycie jest obecnie przestarzale. USTERKI Przy dostarczaniu sygnalu wynikajacego z wyjatku sprzetowego z procedura obslugi SA_SIGINFO, jadro nie zawsze zapewnia sensowne wartosci dla wszystkich pol siginfo_t, ktore sa istotne dla tego sygnalu. Na przyklad, gdy instrukcja x86 int jest wywolywana z niedozwolonym argumentem (liczba inna niz 3 lub 128), dostarczany jest sygnal SIGSEGV, lecz siginfo_t przekazywane do procedury obslugi sygnalu ma wszystkie swe pola poza si_signo i si_code ustawione na zero, nawet gdy inne pola powinny byc ustawione (np. si_addr powinno byc niezerowe dla wszystkich sygnalow SIGSEGV). Do Linuksa 2.6.13 wlacznie, podanie SA_NODEFER w sa_flags zapobiegalo maskowaniu nie tylko dostarczonego sygnalu podczas wykonywania procedury obslugi sygnalu, ale takze sygnalow okreslonych w sa_mask. Ten blad zostal poprawiony w Linuksie 2.6.14. PRZYKLADY Patrz mprotect(2). Sprawdzanie obslugiwanych znacznikow Ponizszy przykladowy program wychodzi ze statusem EXIT_SUCCESS gdy sprawdzi, ze SA_EXPOSE_TAGBITS jest obslugiwany albo EXIT_FAILURE w przeciwnym przypadku. #include #include #include #include static void handler(int signo, siginfo_t *info, void *context) { struct sigaction oldact; if (sigaction(SIGSEGV, NULL, &oldact) == -1 || (oldact.sa_flags & SA_UNSUPPORTED) || !(oldact.sa_flags & SA_EXPOSE_TAGBITS)) { _exit(EXIT_FAILURE); } _exit(EXIT_SUCCESS); } int main(void) { struct sigaction act = { 0 }; act.sa_flags = SA_SIGINFO | SA_UNSUPPORTED | SA_EXPOSE_TAGBITS; act.sa_sigaction = &handler; if (sigaction(SIGSEGV, &act, NULL) == -1) { perror("sigaction"); exit(EXIT_FAILURE); } raise(SIGSEGV); } ZOBACZ TAKZE kill(1), kill(2), pause(2), pidfd_send_signal(2), restart_syscall(2), seccomp(2), sigaltstack(2), signal(2), signalfd(2), sigpending(2), sigprocmask(2), sigreturn(2), sigsuspend(2), wait(2), killpg(3), raise(3), siginterrupt(3), sigqueue(3), sigsetops(3), sigvec(3), core(5), signal(7) TLUMACZENIE Tlumaczenie niniejszej strony podrecznika: Przemek Borys , Robert Luberda 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.15 17 maja 2025 r. sigaction(2)