signal(7) Miscellaneous Information Manual signal(7) NAZWA signal - przeglad sygnalow OPIS Linux wspiera zarowno rzeczywiste sygnaly POSIX-owe (zwane dalej ,,sygnalami standardowymi"), jak i sygnaly POSIX-owe czasu rzeczywistego. Zachowania sygnalu Kazdy sygnal ma przypisane biezace zachowanie, ktore okresla reakcje procesu na dostarczony sygnal. Wpisy w kolumnie ,,Akcja" tabel okreslaja domyslne zachowanie dla danego sygnalu, jako jedno z nastepujacych: Term Domyslna akcja jest przerwanie procesu. Ign Domyslna akcja jest zignorowanie sygnalu. Core Domyslna akcja jest przerwanie procesu i zapisanie obrazu pamieci (patrz core(5)). Stop Domyslna akcja jest zatrzymanie procesu. Cont Domyslna akcja jest kontynuowanie procesu, jezeli jest obecnie zatrzymany. Proces moze zmienic zachowanie sie sygnalu, uzywajac sigaction(2) lub signal(2) (to drugie jest mniej przenosne, jesli chodzi o ustawianie akcji obslugi sygnalu; szczegoly opisano w signal(2)). Uzywajac tych wywolan systemowych, proces moze wybrac jedna z ponizszych reakcji na dostarczenie sygnalu: wykonac domyslna akcje, zignorowac sygnal, przejac sygnal wykonujac procedure obslugi sygnalu, czyli podana przez programiste funkcje, wywolywana automatycznie po dostarczeniu sygnalu. Domyslnie procedura obslugi sygnalu jest uruchamiana na normalnym stosie procesu. Mozna to zmienic, tak zeby uzywany byl stos alternatywny; szczegoly, jak i po co to robic, mozna znalezc w sigaltstack(2) Zachowanie sygnalu jest atrybutem poszczegolnych procesow: w aplikacji wielowatkowej zachowanie danego sygnalu jest takie samo dla wszystkich watkow. 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. Wysylanie sygnalu Nastepujace wywolania systemowe lub funkcje biblioteczne umozliwiaja wysylanie sygnalow: raise(3) Wysyla sygnal do watku, ktory wywolal te funckje. kill(2) Wysyla sygnal do podanego procesu lub do wszystich czlonkow podanej grupy procesow, lub do wszystkich procesow w systemie. pidfd_send_signal(2) Wysyla sygnal do procesu identyfikowanego za pomoca deskryptora pliku PID. killpg(3) Wysyla sygnal do wszystkich czlonkow podanej grupy procesow. pthread_kill(3) Wysyla sygnal do podanego watku POSIX w tym samym procesie, co proces wywolujacy. tgkill(2) Wysyla sygnal do podanego watku w podanym procesie (jest to uzywane do zaimplementowania pthread_kill(3)). sigqueue(3) Wysyla sygnal czasu rzeczywistego wraz z powiazanymi danymi do podanego procesu. Oczekiwanie na przechwycenie sygnalu Nastepujace wywolania systemowe zawieszaja wykonywanie wywolujacego je watku do momentu obsluzenia sygnalu (lub do momentu, w ktorym nieobsluzony sygnal spowoduje zakonczenie procesu). pause(2) Zawiesza wykonywanie do momentu zlapania sygnalu. sigsuspend(2) Tymczasowo zmienia maske sygnalu (patrz nizej) i zawiesza wykonywanie do momentu przechwycenia jednego z niemaskowanych sygnalow. Synchroniczne akceptowanie sygnalu Zamiast asynchronicznego przechwytywania sygnalu przez procedure jego obslugi, mozliwe jest synchroniczne akceptowanie sygnalow, czyli blokowanie wykonywania do czasu dostarczenia sygnalu, w ktorym to momencie jadro zwraca informacje o sygnale do funkcji wywolujacej. W ogolnosci mozna to zrobic na dwa sposoby: o sigwaitinfo(2), sigtimedwait(2) oraz sigwait(3) zawieszaja wykonanie az do chwili dostarczenia jednego z sygnalow nalezacego do podanego zbioru sygnalow. Kazde z tych wywolan systemowych zwraca informacje o dostarczonym sygnale. o signalfd(2) zwraca deskryptor pliku, ktorego mozna uzyc do odczytania informacji o sygnalach dostarczanych do procesu wywolujacego. Kazda operacja odczytu za pomoca read(2) z tego deskryptora pliku jest blokowana do czasu dostarczenia do programu wywolujacego jednego z sygnalow przekazanych w zbiorze signalfd(2). Bufor zwracany przez read(2) zawiera strukture opisujaca sygnal. Maska sygnalu i sygnaly oczekujace Sygnal moze byc zablokowany, co oznacza, ze nie zostanie dostarczony, dopoki sie go nie odblokuje. Sygnal jest nazywany oczekujacym, jezeli zostal juz wygenerowany, ale nie zostal jeszcze dostarczony. Kazdy watek procesu ma swoja niezalezna maske sygnalow, okreslajaca zbior sygnalow obecnie blokowanych przez watek. Watek moze zmieniac maske sygnalow, uzywajac pthread_sigmask(3). Tradycyjna, jednowatkowa aplikacja moze do tego celu uzyc sigprocmask(2). Dziecko utworzone przez fork(2) dziedziczy kopie maski sygnalow od swojego rodzica. Maska jest zachowywana podczas wywolan execve(2). Sygnal moze byc kierowany do procesu lub kierowany do watku. Sygnal kierowany do procesu jest przeznaczony do (i oczekujacy wobec) calego procesu. Sygnal moze byc kierowany do procesu, poniewaz zostal wygenerowany przez jadro, z powodow innych niz wyjatek sprzetowy albo poniewaz zostal wyslany za pomoca kill(2) lub sigqueue(3). Sygnal kierowany do watku jest przeznaczony do konkretnego watku. Sygnal moze byc kierowany do watku, poniewaz zostal wygenerowany w konsekwencji wykonania specjalnej instrukcji jezyka maszynowego, ktora wyzwolila wyjatek sprzetowy (np. SIGSEGV w przypadku nieprawidlowego dostepu do pamieci lub SIGFPE w przypadku bledu matematycznego) albo poniewaz jest kierowany do konkretnego watku poprzez interfejs taki jak tgkill(2) lub pthread_kill(3). Sygnal kierowany do procesu moze byc dostarczony do dowolnego z watkow, ktory aktualnie nie blokuje sygnalu. Jesli wiecej niz jeden watkow ma odblokowany sygnal, jadro wybiera watek, do ktorego zostanie dostarczony sygnal, w sposob dowolny. Watek moze pobrac zbior obecnie oczekujacych sygnalow, uzywajac sigpending(2). Zbior ten bedzie zawieral sygnaly oczekujace skierowane zarowno do calego procesu, jak i do wywolujacego watku. Zbior sygnalow oczekujacych dziecka utworzonego przez fork(2) jest na samym poczatku pusty. Zbior ten jest zachowywany podczas execve(2). Wykonanie procecedur obslugi sygnalow Gdy tylko zachodzi przejscie wykonania z trybu jadra do trybu uzytkownika (np. powrot z wywolania systemowego lub zakolejkowanie watku do procesora) jadra sprawdza, czy wystepuje oczekujacy, niezablokowany sygnal, dla ktorego proces ustanowil procedure obslugi sygnalu. Jesli taki oczekujacy sygnal wystepuje, maja miejsce ponizsze kroki: (1) Jadro przeprowadza niezbedne dzialania przygotowawcze do wykonania procedury obslugi sygnalu: (1.1) Sygnal jest usuwany ze zbioru oczekujacych sygnalow. (1.2) Jesli sygnal zostal zainstalowany wywolaniem do sigaction(2) ze znacznikiem SA_ONSTACK oraz watek zdefiniowal alternatywny stos sygnalow (za pomoca sigaltstack(2)) -- stos ten jest instalowany. (1.3) Rozne czesci kontekstu zwiazanego z sygnalem sa zapisywane do specjalnej ramki, ktora jest tworzona na stosie. Zapisywane informacje obejmuja: o Rejestr licznika rozkazow (tj. adres nastepnej instrukcji w glownym programie, ktora powinna byc wykonana po powrocie z procedury obslugi sygnalu); o Stan rejestru zalezny od architektury, wymagany do wznowienia przerwanego programu; o biezaca maska sygnalow watku; o ustawienia alternatywnego stosu sygnalow watku. (Jesli procedure obslugi sygnalu zainstalowano przy uzyciu znacznika SA_SIGINFO sigaction(2), powyzsze informacje sa dostepne za pomoca obiektu ucontext_t, na ktory wskazuje trzeci argument procedury obslugi sygnalu). Obiekt ten wskazuje na stan, w jakim dostarczono sygnal, zamiast na procedure obsluge; np. maska zablokowanych sygnalow przechowana w tym obiekcie nie bedzie zawierala maski nowych sygnalow blokowanych za pomoca sigaction(2). (1.4) Wszelkie sygnaly podane w act->sa_mask przy rejestracji procedury obslugi przy uzyciu sigaction(2) sa dodawane do maski sygnalow watku. Dostarczany sygnal jest rowniez dodawany do maski sygnalow, chyba ze przy rejestracji procedury obslugi podano SA_NODEFER. Z tego powodu, te sygnaly sa blokowane w trakcie wykonywania procedury obslugi. (2) Jadro tworzy ramke na stosie, dla procedury obslugi sygnalu. Jadro ustawia licznik rozkazow dla watku tak, aby wskazywal na pierwsza instrukcje funkcji obslugi sygnalu i konfiguruje adres powrotny dla tej funkcji tak, aby wskazywal na kod w przestrzeni uzytkownika znany jako trampolina sygnalu (opisany w podreczniku sigreturn(2)). (3) Jadro zwraca kontrole do przestrzeni uzytkownika, gdzie wykonanie zaczyna sie na poczatku funkcji obslugi sygnalu. (4) Gdy procedura obslugi sygnalu powroci, kontrola jest przekazywana do kodu trampoliny sygnalu. (5) Trampolina sygnalu wywoluje sigreturn(2), wywolanie systemowe, ktore za pomoca informacji w ramce stosu utworzonej w kroku 1, przywraca watek do stanu sprzed wywolania procedury obslugi sygnalu. Jako czesc tej procedury, przywracana jest maska sygnalow watku oraz ustawienia alternatywnego stosu sygnalow. Po zakonczeniu wywolania sigreturn(2), jadro przekazuje kontrole z powrotem do przestrzeni uzytkownika, a watek zaczyna wykonanie w punkcie, w ktorym byl przerwany procedura obslugi sygnalu. Prosze zauwazyc, ze jesli procedura obslugi sygnalu nie powroci (np. kontrola zostanie przekazana poza procedure obslugi za pomoca siglongjmp(3) albo procedura obslugi wykona nowy program za pomoca execve(2)), to ostatni krok nie jest wykonywany. W szczegolnosci, w takich przypadkach to po stronie programisty lezy odpowiedzialnosc za przywrocenie stanu maski sygnalow (przy uzyciu sigprocmask(2)), jesli pozadane jest odblokowanie sygnalow, ktore zostaly zablokowane przy wejsciu do procedury obslugi sygnalu (prosze zauwazyc, ze siglongjmp(3) moze, ale nie musi przywrocic maski sygnalow, w zaleznosci od wartosci savesigs podanej w odpowiednim wywolaniu do sigsetjmp(3)). Z punktu widzenia jadra, wykonanie kodu procedury obslugi sygnalu jest identyczne jak wykonanie kazdego innego kodu w przestrzeni uzytkownika. Oznacza to, ze jadro nie zapisuje zadnych specjalnych informacji o stanie wskazujacych, ze watek jest aktualnie wykonywany w procedurze obslugi sygnalu. Wszystkie niezbedne informacje o stanie sa utrzymywane w rejestrach w przestrzeni uzytkownika i stosie w przestrzeni uzytkownika. Glebokosc zagniezdzenia wywolywanych procedur obslugi sygnalu zalezy zatem tylko od stosu w przestrzeni uzytkownika (i rozsadnego projektu oprogramowania!). Sygnaly standardowe Linux obsluguje sygnaly standardowe wypisane nizej. Druga kolumna wskazuje jaki standard (o ile w ogole) okresla sygnal: ,,P1990" oznacza, ze sygnal byl opisany w pierwotnym standardzie POSIX.1-1990; ,,P2001" wskazuje, ze sygnal dodano, lub jego definicja zmienila sie, w SUSv2 i POSIX.1-2001. Sygnal Standard Akcja Komentarz --------------------------------------------------------------------------------------------------- SIGABRT P1990 Core Sygnal abort od abort(3) SIGALRM P1990 Term Sygnal timera od alarm(2) SIGBUS P2001 Core Blad szyny (niepr. dostep do pamieci) SIGCHLD P2001 Ign Potomek zatrzymal sie, zakonczyl prace lub zostal wznowiony SIGCLD - Ign Synonim SIGCHLD SIGCONT P1990 Cont Kontynuuj, jesli sie zatrzymal SIGEMT - Term Pulapka emulatora SIGFPE P1990 Core Bledna operacja arytmetyczna SIGHUP P1990 Term Zawieszenie wykryte na terminalu kontrol. lub smierc procesu kontrolujacego SIGILL P1990 Core Nielegalna instrukcja SIGINFO - Synonim SIGPWR SIGINT P1990 Term Przerwanie nakazane z klawiatury SIGIO - Term I/O teraz mozliwe (4.2BSD) SIGIOT - Core Pulapka IOT. Synonim SIGABRT SIGKILL P1990 Term Sygnal Kill SIGLOST - Term Utracono blokade pliku (nieuzywane) SIGPIPE P1990 Term Uszkodzony potok: zapis do potoku bez odczytujacych; zob. pipe(7) SIGPOLL P2001 Term Zdarzenie odpytywalne (Sys V); synonim dla SIGIO SIGPROF P2001 Term Przeterminowanie zegara profilowego SIGPWR - Term Blad zasilania (System V) SIGQUIT P1990 Core Wyjscie nakazane z klawiatury SIGSEGV P1990 Core Nieprawidlowa referencja pamieciowa SIGSTKFLT - Term Blad stosu koprocesora (nieuzywany) SIGSTOP P1990 Stop Zatrzymaj proces SIGTSTP P1990 Stop Zatrzymanie napisane z terminala SIGSYS P2001 Core Nieprawidlowe wywolanie systemowe (SVr4); zob. tez seccomp(2) SIGTERM P1990 Term Sygnal zakonczenia pracy SIGTRAP P2001 Core Sledzenie/pulapka kontrolna SIGTTIN P1990 Stop Wejscie terminala dla procesu w tle SIGTTOU P1990 Stop Wyjscie terminala dla procesu w tle SIGUNUSED - Core Synonimiczny z SIGSYS SIGURG P2001 Ign Pilny warunek na gniezdzie (4.2BSD) SIGUSR1 P1990 Term Sygnal 1 uzytkownika SIGUSR2 P1990 Term Sygnal 2 uzytkownika SIGVTALRM P2001 Term Wirtualny zegar alarmu (4.2BSD) SIGXCPU P2001 Core Przekroczone ogran. czasu CPU (4.2BSD) zob. setrlimit(2) SIGXFSZ P2001 Core Przekr. ogran. rozmiaru pliku (4.2BSD) zob. setrlimit(2) SIGWINCH - Ign Sygnal zmiany rozm. okna (4.3BSD, Sun) Sygnalow SIGKILL oraz SIGSTOP nie mozna przechwycic, zablokowac ani zignorowac. Do wersji 2.2 Linuksa (wlacznie) domyslne zachowanie dla sygnalow SIGSYS, SIGXCPU, SIGXFSZ oraz (na architekturach innych niz SPARC i MIPS) SIGBUS polegalo na przerwaniu procesu (bez zrzutu pamieci). (W niektorych innych Uniksach domyslne zachowanie dla SIGXCPU i SIGXFSZ polega na przerwaniu procesu bez zrzutu pamieci). Linux 2.4 jest zgodny ze wymaganiami standardu POSIX.1-2001 dotyczacymi tych sygnalow i przerywa proces ze zrzutem pamieci. SIGEMT nie jest wymieniony w POSIX.1-2001, lecz pomimo to pojawia sie w wiekszosci innych Uniksow. Domyslna akcja dla tego sygnalu jest zazwyczaj przerwanie procesu ze zrzutem pamieci. SIGPWR (niewymieniony w POSIX.1-2001) jest zazwyczaj domyslnie ignorowany w tych Uniksach, w ktorych wystepuje. SIGIO (niewymieniony w POSIX.1-2001) jest domyslnie ignorowany w niektorych innych Uniksach. Kolejkowanie i semantyka dostarczania sygnalow standardowych Jesli na proces oczekuje kilka sygnalow standardowych, kolejnosc, w jakiej zostana dostarczone, jest nieokreslona. Sygnaly standardowe nie sa kolejkowane. Jesli w trakcie blokowania sygnalu wygenerowane zostanie wiele wystapien sygnalu standardowego, to tylko jedno jego wystapienie jest oznaczane jako oczekujace (i po jego odblokowaniu, sygnal zostanie dostarczony jeden raz). W przypadku, gdy istnieje juz sygnal oczekujacy, struktura siginfo_t (zob. sigaction(2)) zwiazana z danym sygnalem nie jest nadpisywana, po nadejsciu kolejnych wystapien tego samego sygnalu. Proces otrzyma zatem informacje powiazane z pierwszym wystepieniem danego sygnalu. Numerowanie sygnalow, w zakresie sygnalow standardowych Wartosc numeryczna kazdego sygnalu jest podana w ponizszej tabeli. Jak wskazano w tabeli, wiele sygnalow ma zroznicowane wartosci numeryczne na roznych architekturach. Pierwsza wartosc numeryczna w kazdym wierszu tabeli ukazuje numer sygnalu na architekturze x86, ARM i wiekszosci innych architektur; druga wartosc dotyczy Alpha i SPARC; trzecia -- MIPS; a ostatnia -- PARISC. Kreska (-) wskazuje, ze sygnal nie wystepuje na danej architekturze. Sygnal x86/ARM Alpha/ MIPS PARISC Uwagi wiekszosc innych SPARC ---------------------------------------------------------------------- SIGHUP 1 1 1 1 SIGINT 2 2 2 2 SIGQUIT 3 3 3 3 SIGILL 4 4 4 4 SIGTRAP 5 5 5 5 SIGABRT 6 6 6 6 SIGIOT 6 6 6 6 SIGBUS 7 10 10 10 SIGEMT - 7 7 - SIGFPE 8 8 8 8 SIGKILL 9 9 9 9 SIGUSR1 10 30 16 16 SIGSEGV 11 11 11 11 SIGUSR2 12 31 17 17 SIGPIPE 13 13 13 13 SIGALRM 14 14 14 14 SIGTERM 15 15 15 15 SIGSTKFLT 16 - - 7 SIGCHLD 17 20 18 18 SIGCLD - - 18 - SIGCONT 18 19 25 26 SIGSTOP 19 17 23 24 SIGTSTP 20 18 24 25 SIGTTIN 21 21 26 27 SIGTTOU 22 22 27 28 SIGURG 23 16 21 29 SIGXCPU 24 24 30 12 SIGXFSZ 25 25 31 30 SIGVTALRM 26 26 28 20 SIGPROF 27 27 29 21 SIGWINCH 28 28 20 23 SIGIO 29 23 22 22 SIGPOLL jak SIGIO SIGPWR 30 29/- 19 19 SIGINFO - 29/- - - SIGLOST - -/29 - - SIGSYS 31 12 12 31 SIGUNUSED 31 - - 31 Prosze zauwazyc, co nastepuje: o Jesli SIGUNUSED jest zdefiniowany, to jest synonimem dla SIGSYS. Od glibc 2.26, SIGUNUSED nie jest juz zdefiniowany na zadnej architekturze. o Sygnal 29 oznacza SIGINFO/SIGPWR (synonimy o tej samej wartosci) na architekturze Alpha, lecz SIGLOST na architekturze SPARC. Sygnaly czasu rzeczywistego Od Linuksa 2.2, Linux wspiera sygnaly czasu rzeczywistego zdefiniowane pierwotnie w rozszerzeniu dla czasu rzeczywistego POSIX.1b (a obecnie zawarte w POSIX.1-2001). Zakres obslugiwanych sygnalow czasu rzeczywistego jest definiowany przez makra SIGRTMIN i SIGRTMAX. POSIX.1-2001 wymaga od implementacji wspierania co najmniej _POSIX_RTSIG_MAX (8) sygnalow czasu rzeczywistego. Jadro Linux wspiera 33 rozne sygnaly czasu rzeczywistego, o numerach od 32 do 64. Jednakze implementacja watkow POSIX w glibc uzywa dwoch (dla NPTL) lub trzech (dla LinuxThreads) z nich na swoje wewnetrzne potrzeby (patrz pthreads(7)), odpowiednio zmieniajac takze SIGRTMIN (na 34 lub 35). Poniewaz zakres dostepnych sygnalow czasu rzeczywistego zmienia sie zaleznie od implementacji watkow w glibc (roznice moga wystepowac rowniez w czasie dzialania aplikacji, zaleznie od wersji jadra i glibc) i tak naprawde zakres ten rozni sie pomiedzy implementacjami Uniksa, programy nigdy nie powinny sie odwolywac do sygnalow czasu rzeczywistego za pomoca liczb wpisanych na stale, ale powinny zawsze sie odwolywac do sygnalow czasu rzeczywistego uzywajac notacji SIGRTMIN+n, i sprawdzac (podczas dzialania aplikacji), czy SIGRTMIN+n nie przekracza SIGRTMAX. W odroznieniu od sygnalow standardowych, sygnaly czasu rzeczywistego nie maja predefiniowanego znaczenia: mozna wykorzystywac caly zestaw sygnalow czasu rzeczywistego do celow okreslonych w aplikacji. Domyslna akcja na nieobsluzony sygnal czasu rzeczywistego jest przerwanie procesu, ktory go otrzymal. Sygnaly czasu rzeczywistego sa rozpoznawane w nastepujacy sposob: o Mozna kolejkowac wiele egzemplarzy sygnalu czasu rzeczywistego. Dla odroznienia, jesli w czasie gdy standardowy sygnal jest blokowany zostanie doreczonych wiele egzemplarzy tego sygnalu, tylko jeden egzemplarzy trafia do kolejki. o Jesli sygnal wyslano korzystajac z sigqueue(3), mozna wyslac wraz z tym sygnalem wartosc towarzyszaca (calkowita lub wskaznik). Jesli proces otrzymujacy ustanawia funkcje obslugi dla tego sygnalu za pomoca znacznika SA_SIGACTION funkcji sigaction(2), to otrzymuje towarzyszaca mu dana za posrednictwem pola si_value struktury siginfo_t przekazanej jako drugi argument funkcji obslugi. Ponadto, pola si_pid oraz si_uid tej struktury moga sluzyc do otrzymania identyfikatora procesu oraz rzeczywistego identyfikatora uzytkownika procesu wysylajacego sygnal. o Sygnaly czasu rzeczywistego sa doreczane w zagwarantowanej kolejnosci. Sygnaly czasu rzeczywistego jednego rodzaju sa doreczane w takiej kolejnosci, w jakiej zostaly wyslane. Jesli do procesu zostana wyslane rozne sygnaly czasu rzeczywistego, beda one doreczone poczawszy od sygnalu o najnizszym numerze. (Tzn. sygnaly o niskich numerach maja najwyzszy priorytet). Sygnaly standardowe zachowuja sie inaczej: jesli kilka standardowych sygnalow oczekuje na proces, to kolejnosc dostarczenia nie jest okreslona. POSIX nie okresla, ktore z sygnalow powinny zostac doreczone jako pierwsze w sytuacji, gdy obsluzenia wymagaja zarowno sygnaly standardowe, jak i sygnaly czasu rzeczywistego. Linux, podobnie do innych implementacji, daje w tym przypadku pierwszenstwo sygnalom standardowym. Zgodnie z POSIX, implementacja powinna zezwalac na kolejkowanie do procesu co najmniej _POSIX_SIGQUEUE_MAX (32) sygnalow czasu rzeczywistego. Jednakze w Linuksie zostalo to zaimplementowane inaczej. Az do Linuksa 2.6.7 (wlacznie), Linux narzuca ogolnosystemowe ograniczenie liczby sygnalow czasu rzeczywistego kolejkowanych do wszystkich procesow. Ograniczenie to mozna zobaczyc, a takze (przy odpowiednich uprawnieniach) zmienic za posrednictwem pliku /proc/sys/kernel/rtsig-max. Podobnie, za posrednictwem pliku /proc/sys/kernel/rtsig-nr mozna dowiedziec sie, ile sygnalow czasu rzeczywistego jest aktualnie w kolejce. W Linuksie 2.6.8 ten interfejs /proc zostal zastapiony limitem zasobow RLIMIT_SIGPENDING, ktory okresla limit kolejkowanych sygnalow dla poszczegolnych uzytkownikow; patrz setrlimit(2) w celu uzyskania dalszych informacji. Dodanie sygnalow czasu rzeczywistego wymoglo poszerzenie struktury zestawu sygnalow (sigset_t) z 32 do 64 bitow. W konsekwencji rozne wywolania systemowe zostaly zastapione nowymi, ktore obsluguja wiekszy zestaw sygnalow. Oto stare i nowe wywolania systemowe: Linux 2.0 i wczesniejsze Linux 2.2 i pozniejsze sigaction(2) rt_sigaction(2) sigpending(2) rt_sigpending(2) sigprocmask(2) rt_sigprocmask(2) sigreturn(2) rt_sigreturn(2) sigsuspend(2) rt_sigsuspend(2) sigtimedwait(2) rt_sigtimedwait(2) Przerywanie wywolan systemowych i funkcji bibliotecznych przez funkcje obslugi sygnalow Jesli procedura obslugi sygnalu jest wywolana w trakcie wywolania systemowego lub wywolania funkcji bibliotecznej to wtedy albo: o wywolanie jest automatycznie uruchamiane ponownie po zakonczeniu funkcji obslugujacej sygnal, albo o wywolanie zwraca blad EINTR. To, ktore z powyzszych wystapi, zalezy od interfejsu i od tego, czy podczas ustanawiania funkcji obslugi sygnalu uzyto znacznika SA_RESTART (patrz sigaction(2)). Szczegoly sie roznia miedzy roznymi Uniksami, ponizej podano szczegoly dotyczace Linuksa. Jesli blokowane wywolanie jednego z ponizszych interfejsow zostanie przerwane przez procedure obslugi sygnalu, to wywolanie to zostanie automatycznie uruchomione ponownie, jesli uzyto znacznika SA_RESTART. W przeciwnym wypadku wywolanie zwroci blad EINTR: o Wywolania read(2), readv(2), write(2), writev(2) i ioctl(2) na urzadzeniach ,,powolnych". Urzadzenie ,,powolne" to takie, w ktorym operacja wejscia/wyjscia moze sie blokowac przez nieskonczony czas, na przyklad: terminal, potok lub gniazdo. Jesli wywolanie systemowe wejscia/wyjscia na urzadzeniu powolnym spowodowalo juz jakis transfer danych, zanim zostalo przerwane przez sygnal, to zwroci ono pomyslny kod zakonczenie (bedacy zazwyczaj liczba przetransferowanych bajtow). Prosze zauwazyc, ze (lokalny) dysk zgodnie z ta definicja nie jest urzadzeniem powolnym: operacje wejscia/wyjscia na urzadzeniach dyskowych nie sa przerywane sygnalami. o open(2), jesli moze sie zablokowac (np. podczas otwierania FIFO, patrz fifo(7)). o wait(2), wait3(2), wait4(2), waitid(2) i waitpid(2). o Interfejsy gniazd: accept(2), connect(2), recv(2), recvfrom(2), recvmmsg(2), recvmsg(2), send(2), sendto(2) i sendmsg(2), chyba ze ustawiono czas przeterminowania na gniezdzie (patrz nizej). o Interfejsy blokady plikow: flock(2) i F_SETLKW oraz operacje F_OFD_SETLKW fcntl(2) o Interfejsy kolejek komunikatow POSIX: mq_receive(3), mq_timedreceive(3), mq_send(3) i mq_timedsend(3). o futex(2) FUTEX_WAIT (od Linuksa 2.6.22; wczesniej zawsze zwracal blad EINTR). o getrandom(2). o futex(2) FUTEX_WAIT_BITSET. o Interfejsy semaforow POSIX: sem_wait(3) i sem_timedwait(3) (od Linuksa 2.6.22; wczesniejsze wersje zawsze zwracaly blad EINTR). o read(2) z deskryptora pliku inotify(7) (od Linuksa 3.8; wczesniej zawsze zwracalo blad EINTR). Nastepujace interfejsy nigdy nie sa wznawiane po przerwaniu przez funkcje obslugi sygnalu, niezaleznie od tego, czy SA_RESTART zostalo uzyte. Jesli zostana przerwane przez funkcje obslugi sygnalu, to zawsze koncza sie niepowodzeniem, zwracajac blad EINTR: o ,,Wejsciowe" interfejsy gniazd, jesli ustawiono czas przeterminowania gniazda (SO_RCVTIMEO) za pomoca setsockopt(2): accept(2), recv(2), recvfrom(2), recvmmsg(2) (rowniez z niezerowym argumentem timeout) i recvmsg(2). o ,,Wyjsciowe" interfejsy gniazd, jesli ustawiono czas przeterminowania gniazda (SO_RCVTIMEO) za pomoca setsockopt(2): connect(2), send(2), sendto(2) i sendmsg(2). o Interfejsy oczekiwania na sygnaly: pause(2), sigsuspend(2), sigtimedwait(2) i sigwaitinfo(2). o Interfejsy zwielokrotniajace deskryptory plikow: epoll_wait(2), epoll_pwait(2), poll(2), ppoll(2), select(2) i pselect(2). o Interfejsy komunikacji miedzyprocesowej Systemu V: msgrcv(2), msgsnd(2), semop(2) oraz semtimedop(2). o Interfejsy pauzujace proces: clock_nanosleep(2), nanosleep(2) i usleep(3). o io_getevents(2). Funkcja sleep(3) nigdy nie zostanie zrestartowana po przerwaniu przez sygnal i zawsze konczy sie pomyslnie, zwracajac liczbe pozostalych sekund, podczas ktorych proces powinien byl pauzowac. W pewnych okolicznosciach, funkcji powiadomien w przestrzeni uzytkownika seccomp(2), moze spowodowac ponowne uruchomienia wywolan systemowych, ktore w innych przypadkach nigdy nie zostalyby zrestartowane przez SA_RESTART; wiecej szczegolow w podreczniku seccomp_unotify(2). Przerywanie wywolan systemowych i funkcji bibliotecznych przez sygnaly zatrzymujace proces Pod Linuksem, nawet jesli procedury obslugi sygnalu nie zostana ustawione, pewne interfejsy blokujace moga sie zakonczyc niepowodzeniem i zwrocic blad EINTR po tym, jak proces zostanie zatrzymany za pomoca jednego z sygnalow zatrzymujacych (takich jak SIGSTOP), a nastepnie wznowiony za pomoca SIGCONT. POSIX.1 nie wspiera tego zachowania, nie wystepuje ono takze na innych systemach. Nastepujace interfejsy Linuksa zachowuja sie w ten sposob: o ,,Wejsciowe" interfejsy gniazd, jesli ustawiono czas przeterminowania gniazda (SO_RCVTIMEO) za pomoca setsockopt(2): accept(2), recv(2), recvfrom(2), recvmmsg(2) (rowniez z niezerowym argumentem timeout) i recvmsg(2). o ,,Wyjsciowe" interfejsy gniazd, jesli ustawiono czas przeterminowania gniazda (SO_RCVTIMEO) za pomoca setsockopt(2): connect(2), send(2), sendto(2) i sendmsg(2), jesli ustawiono czas przeterminowania wysylania danych(SO_SNDTIMEO). o epoll_wait(2), epoll_pwait(2). o semop(2), semtimedop(2). o sigtimedwait(2), sigwaitinfo(2). o Linux 3.7 i wczesniejsze: read(2) czytajace z deskryptora pliku inotify(7). o Linux 2.6.21 i wczesniejsze: futex(2) FUTEX_WAIT, sem_timedwait(3), sem_wait(3). o Linux 2.6.8 i wczesniejsze: msgrcv(2), msgsnd(2). o Linux 2.4 i wczesniejsze: nanosleep(2). STANDARDY POSIX.1, z wyjatkami jak podano. UWAGI Opis funkcji async-signal-safe znajduje sie w podreczniku signal-safety(7). Plik /proc/pid/task/tid/status zawiera rozne pola, ktore pokazuja sygnaly, ktore sygnal: blokuje (SigBlk), przechwytuje (SigCgt) lub ignoruje (SigIgn) (przy czym zbior sygnalow przechwytywanych lub ignorowanych jest taki sam dla wszystkich watkow procesu). Inne pola ukazuja zbior sygnalow oczekujacych, ktore sa skierowane do watku (SigPnd) oraz zbior sygnalow oczekujacych, ktore sa skierowane do calego procesu (ShdPnd). Odpowiadajace im pola w /proc/pid/status pokazuja informacje dla glownego watku. Wiecej szczegolow w podreczniku proc(5). USTERKI Istnieje szesc sygnalow, ktore moga byc dostarczone z powodu wyjatku sprzetowego: SIGBUS, SIGEMT, SIGFPE, SIGILL, SIGSEGV i SIGTRAP. To, ktore z nich sa dostarczane dla jakiegos wyjatku sprzetowego nie jest udokumentowane i nie zawsze ma sens. Przykladowo, nieprawidlowy dostep do pamieci, ktory powoduje dostarczenie sygnalu SIGSEGV na jednej architekturze procesora, moze powodowac dostarczanie sygnalu SIGBUS na innej architekturze lub odwrotnie. Innym przykladem jest instrukcja int x86 z zabronionym argumentem (liczba inna niz 3 lub 128), ktora powoduje dostarczenie SIGSEGV, choc logiczniejszy, z powodu sposobu, w jaki procesor informuje jadro o zabronionych operacjach, bylby sygnal SIGILL. ZOBACZ TAKZE kill(1), clone(2), getrlimit(2), kill(2), pidfd_send_signal(2), restart_syscall(2), rt_sigqueueinfo(2), setitimer(2), setrlimit(2), sgetmask(2), sigaction(2), sigaltstack(2), signal(2), signalfd(2), sigpending(2), sigprocmask(2), sigreturn(2), sigsuspend(2), sigwaitinfo(2), abort(3), bsd_signal(3), killpg(3), longjmp(3), pthread_sigqueue(3), raise(3), sigqueue(3), sigset(3), sigsetops(3), sigvec(3), sigwait(3), strsignal(3), swapcontext(3), sysv_signal(3), core(5), proc(5), nptl(7), pthreads(7), sigevent(3type) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: 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.12 2 lutego 2025 r. signal(7)