SIGACTION(2)

NAZWA
sigaction - bada i zmienia akcję sygnału

SKŁADNIA
#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

OPIS
Wywołanie systemowe sigaction() jest używane do zmieniania akcji, którą obiera proces po odebraniu określonego sygnału.

signum określa sygnał i może być dowolnym prawidłowym sygnałem poza SIGKILL i SIGSTOP.

Jeśli act jest niezerowe, to nowa akcja dla sygnału signum jest brana z act. Jeśli oldact też jest niezerowe, 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 niektórych architekturach część tej struktury może być unią: nie należy ustawiać jednocześnie pól sa_handler oraz sa_sigaction.

Element sa_restorer jest przedawniony i nie powinno się go używać. POSIX nie definiuje tego elementu.

sa_handler podaje akcję, związaną z sygnałem signum i może to być m.in SIG_DFL dla akcji domyślnej, SIG_IGN dla akcji ignorowania lub wskaźnik do funkcji obsługującej sygnał. Funkcja ta ma jtylko eden argument, w którym będzie przekazany numer sygnału.

Jeżeli wartość SA_SIGINFO jest podana w sa_flags, to sa_sigaction (zamiast sa_handler) określa funkcję obsługi sygnału dla signum. Funkcja ta otrzymuje numer sygnału jako pierwszy argument, wskaźnik do siginfo_t jako drugi argument oraz wskaźnik do ucontext_t (zrzutowany na void *) jako jej trzeci argument.

sa_mask podaje maskę sygnałów, które powinny być blokowane podczas wywoływania handlera sygnałów. Dodatkowo, sygnał, który wywołał handler będzie zablokowany, chyba że użyto flagi SA_NODEFER.

sa_flags podaje zbiór flag, które modyfikują zachowanie procesu obsługi sygnałów. Jest to zbiór wartości połączonych bitowym OR:

    SA_NOCLDSTOP
        Jeśli signum to SIGCHLD, nie odbieraj powiadomienia o zatrzymaniu procesu potomnego (np. gdy proces potomny otrzyma jeden z SIGSTOP, SIGTSTP, SIGTTIN lub SIGTTOU) lub o jego wznowieniu (np. po otrzymaniu SIGCONT) (patrz wait(2)).

    SA_NOCLDWAIT
        (Linux 2.6 i kolejne) Jeżeli signum to SIGCHLD, to procesy potomne po ich zakończeniu nie będą przekształcone w procesy-duchy (zombie). Patrz także waitpid(2).

    SA_RESETHAND
        Odtwórz akcję sygnałową do stanu domyślnego po wywołaniu handlera sygnałów. SA_ONESHOT jest przestarzałym, niestandardowym synonimem tej flagi.

    SA_ONSTACK
        Wywołaj handler sygnału, używając alternatywnego stosu ustawionego przez sigaltstack(2). Jeżeli ten alternatywny stos nie jest dostępny, zostanie użyty stos domyślny.

    SA_RESTART
        Daj zachowanie, kompatybilne z semantyką sygnałową BSD, czyniąc pewne wywołania systemowe odtwarzalnymi przez sygnały.

    SA_NODEFER
        Nie chroń sygnałów od bycia odebranymi z ich własnego handlera.SA_NOMASK jest przestarzałym, niestandardowym synonimem tej flagi.

    SA_SIGINFO
        Handler sygnałów pobiera 3 argumenty, a nie jeden. W typ przypadku zamiast ustawiać sa_handler należy ustawić sa_sigaction. (Pole sa_sigaction zostało dodane w Linuksie 2.1.86).

Parametr siginfo_t z sa_sigaction jest strukturą zawierającą następujące elementy:

    siginfo_t {
    	int	si_signo;	/* Numer sygnału */
    	int	si_errno;	/* Wartość errno */
    	int	si_code;	/* Kod sygnału */
    	pid_t	si_pid;	/* Id procesu wysyłającego */
    	uid_t	si_uid;	/* Rzeczywisty ID użytkownika wysyłającego procesu */
    	int	si_status;	/* Kod zakończenia lub sygnał */
    	clock_t	si_utime;	/* Czas spędzony w przestrzeni użytkownika */
    	clock_t	si_stime;	/* Czas spędzony w przestrzeni systemu */
    	sigval_t	si_value;	/* Wartość sygnału */
    	int	si_int;	/* sygnał POSIX.1b */
    	void *	si_ptr;	/* sygnał POSIX.1b */
    	void *	si_addr;	/* Adres pamięci, który spowodował błąd */
    	int	si_band;	/* Zdarzenie grupy (band event) */
    	int	si_fd;	/* Deskryptor pliku */
    }
si_signo, si_errno i si_code są zdefiniowane dla wszystkich sygnałów. (si_signo nie jest używane pod Linuksem). Reszta tej struktury może być unią, tak że powinno się czytać tylko te pola, które mają znaczenie dla danego sygnału. Sygnały POSIX.1b i SIGCHLD wypełniają si_pid i si_uid. SIGCHLD wypełnia też si_status, si_utime i si_stime. si_int i si_ptr są określone przez nadawcę sygnału POSIX.1b. SIGILL, SIGFPE, SIGSEGV i SIGBUS wypełniają si_addr adresem błędu. SIGPOLL wypełnia si_band i si_fd. si_code określa, dlaczego sygnał został wysłany. Jest to wartość, a nie maska bitowa. Poniższa tabela pokazuje możliwe wartości dla każdego sygnału:
si_code
Wartość | Źródło sygnału
SI_USER | kill(), sigsend() lub raise()
SI_KERNEL | Jądro
SI_QUEUE | sigqueue()
SI_TIMER | wygaśnięcie timera POSIX
SI_MESGQ | zmiana stanu kolejki komunikatów POSIX (od Linuksa 2.6.6)
SI_ASYNCIO | ukończenie AIO
SI_SIGIO | kolejkowany SIGIO
SI_TKILL | tkill() lub tgkill() (od Linuksa 2.4.19)
SIGILL
ILL_ILLOPC | niedozwolony opcode
ILL_ILLOPN | niedozwolony operand
ILL_ILLADR | niedozwolony tryb adresowania
ILL_ILLTRP | niedozwolona pułapka
ILL_PRVOPC | uprzywilejowany kod operacji
ILL_PRVREG | uprzywilejowany rejestr
ILL_COPROC | błąd koprocesora
ILL_BADSTK | wewnętrzny błąd stosu
SIGFPE
FPE_INTDIV | dzielenie całkowite przez zero
FPE_INTOVF | przepełnienie liczby całkowitej
FPE_FLTDIV | dzielenie wartości zmiennoprzecinkowej przez zero
FPE_FLTOVF | przekroczenie zakresu operacji zmiennoprzecinkowej
FPE_FLTUND | przekroczenie (w dół) zakresu operacji zmiennoprzecinkowej
FPE_FLTRES | niedokładny wynik operacji zmiennoprzecinkowej
FPE_FLTINV | niepoprawna operacja zmiennoprzecinkowa
FPE_FLTSUB | dolny indeks poza zakresem
SIGSEGV
SEGV_MAPERR | adres niemapowany do obiektu
SEGV_ACCERR | niepoprawne uprawnienia mapowanego obiektu
SIGBUS
BUS_ADRALN | niepoprawne wyrównanie adresu
BUS_ADRERR | nieistniejący adres fizyczny
BUS_OBJERR | błąd sprzętowy specyficzny dla obiektu
SIGTRAP
TRAP_BRKPT | punkt wstrzymania procesu
TRAP_TRACE | śledzony proces złapany
SIGCHLD
CLD_EXITED | proces-dziecko się zakończył
CLD_KILLED | proces-dziecko został zabity
CLD_DUMPED | potomek zakończył się w nienormalny sposób
LD_TRAPPED | śledzony potomek został złapany
CLD_STOPPED | proces-potomek został zatrzymany
CLD_CONTINUED | zatrzymany potomek został wznowiony (od Linuksa 2.6.9)
SIGPOLL
POLL_IN | dostępne dane na wejściu
POLL_OUT | dostępne bufory wyjścia
POLL_MSG | dostępna wiadomość na wejściu
POLL_ERR | błąd wejścia/wyjścia
POLL_PRI | dostępne wejście o wysokim priorytecie
POLL_HUP | urządzenie odłączone

WARTOŚĆ ZWRACANA
sigaction() zwraca 0, jeżeli zakończy się pomyślnie, lub -1, jeżeli wystąpi błąd.

BŁĘDY

EFAULT
    act lub oldact wskazują na pamięć poza przestrzenią adresową procesu.

EINVAL
    Podano nieprawidłowy sygnał. Będzie to też generowane w przypadku próby zmienienia akcji dla sygnałów SIGKILL lub SIGSTOP, które nie mogą być przechwycone lub zignorowane.

UWAGI

Zgodnie z POSIX, zachowanie procesu po zignorowaniu sygnału SIGFPE, SIGILL lub SIGSEGV, niewygenerowanego przez kill() lub raise(), 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.

POSIX.1-1990 zabraniał ustawiania akcji dla SIGCHLD na SIG_IGN. POSIX.1-2001 pozwala na to,tak że można użyć ignorowania SIGCHLD, żeby zapobiec tworzeniu procesów-duchów (patrz wait(2)). Niemniej jednak, historyczne zachowanie systemów BSD i SystemV w zakresie ignorowania SIGCHLD jest inne, tak więc jedyną całkowicie przenośną metodą zapewnienia, że potomek po zakończeniu nie zostanie procesem-duchem jest przechwytywanie sygnału SIGCHLD i wywołanie funkcji wait(2) lub podobnej.

POSIX.1-1990 określał tylko SA_NOCLDSTOP. W POSIX.1-2001 dodano SA_NOCLDWAIT, SA_RESETHAND, SA_NODEFER oraz SA_SIGINFO. Używanie tych nowych wartości sa_flags może być mniej przenośne w aplikacjach przewidzianych do użycia w starszych implementacjach Uniksa.

Obsługa SA_SIGINFO została dodana w Linuksie 2.2.

Flaga SA_RESETHAND jest kompatybilna z flagą w SVr4 o tej samej nazwie.

Flaga SA_NODEFER jest kompatybilna z podobną flagą z SVr4 dla jąder Linuksa 1.3.9 i nowszych.

sigaction() może być wywoływany z drugim argumentem o wartości null, powodując w ten sposób zapytanie o bieżący handler sygnału. Może go też użyć do sprawdzenia, czy dany sygnał jest prawidłowy na obecnej maszynie. W tym celu należy zarówno drugi, jak i trzeci argument ustawić na null.

Nie można zablokować sygnałów SIGKILL lub SIGSTOP (przez podanie ich w sa_mask. Próby takie zostaną zignorowane.

Zobacz sigsetops(3) dla szczegółów o operacjach na zbiorach sygnałów.

BŁĘDY
W jądrze 2.6.13 i wcześniejszych podanie SA_NODEFER w sa_flags zapobiegało maskowaniu nie tylko dostarczonego sygnału podczas wykonywania procedury obsługi sygnału, ale także sygnałów określonych w sa_mask. Ten błąd został poprawiony w 2.6.14.

ZGODNE Z
POSIX, SVR4. SVr4 nie dokumentuje błędu EINTR.

NIEUDOKUMENTOWANE
Przed wprowadzeniem SA_SIGINFO również było możliwe otrzymanie pewnych dodatkowych informacji - przez użycie sa_handler z drugim argumentem będącym typu struct sigcontext. Szczegóły można znaleźć w odpowiednich źródłach jądra. To użycie jest obecnie przestarzałe.

ZOBACZ TAKŻE
kill(1), kill(2), pause(2), sigaltstack(2), signal(2), sigpending(2), sigprocmask(2), sigqueue(2), sigsuspend(2), wait(2), killpg(3), raise(3), siginterrupt(3), sigsetops(3), sigvec(3), core(5), signal(7)