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);

Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

sigaction(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

siginfo_t: _POSIX_C_SOURCE >= 199309L

OPIS
Wywołanie systemowe sigaction() jest używane do zmieniania akcji, którą obiera proces po odebraniu określonego sygnału. (Wprowadzenie do sygnałów można znaleźć w podręczniku signals(7)).

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

Jeśli act nie jest NULL-em, to nowa akcja dla sygnału signum jest brana z act. Jeśli oldact też jest różny 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 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 tylko jeden 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 (rzutowany na void *) jako jej trzeci argument (Zazwyczaj funkcja obsługi sygnału w ogóle nie używa trzeciego argumentu. Więcej informacji o ucontext_t można znaleźć w getcontext(3)).

sa_mask określa maskę sygnałów, które powinny być blokowane (tj. dodane do maski sygnałów wątku, z którego sygnał został wywołany) podczas wywoływania funkcji obsługi sygnałów. Dodatkowo, sygnał, który wywołał tę funkcję obsługi 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 jest równe SIGCHLD, to nie są odbierane powiadomienia o zatrzymaniu procesu-dziecka (np. gdy dziecko otrzyma jeden z SIGSTOP, SIGTSTP, SIGTTIN lub SIGTTOU) ani o jego wznowieniu (np. po otrzymaniu SIGCONT) (patrz wait(2)). Flaga ta ma znaczenie tylko w przypadku ustawiania funkcji obsługi sygnału SIGCHLD.

    SA_NOCLDWAIT (od Linuksa 2.6)
        Jeśli signum jest równy SIGCHLD, to dzieci po swoim zakończeniu nie zostaną przekształcone w zombie. Patrz także waitpid(2). Znacznik ma znaczenie tylko ustanawiania funkcji obsługującej sygnał SIGCHLD lub podczas ustawiania tego sygnału na SIG_DLF.

        Jeśli znacznik SA_NOCLDWAIT jest ustawiony podczas ustanawiania funkcji obsługującej sygnał SIGCHLD, to POSIX.1 nie określa, czy sygnał SIGCHLD po zakończeniu procesu potomnego. Pod Linuksem sygnał SIGCHLD jest w takim przypadku generowany; niektóre inne systemy go nie generują.

    SA_NODEFER
        Nie chroni sygnałów przed ich odebraniem z ich własnej procedury obsługi. Znacznik ma znaczenie tylko podczas ustanawiania procedury obsługi sygnału. SA_NOMASK jest przestarzałym, niestandardowym synonimem tego znacznika.

    SA_ONSTACK
        Wywołuje funkcję obsługi 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. Flaga ta ma znaczenie tylko w przypadku ustanawiania funkcji obsługi sygnału.

    SA_RESETHAND
        Odtwarza akcję sygnałową do stanu domyślnego po wejściu funkcji obsługi sygnału. Flaga ta ma znaczenie tylko w przypadku ustanawiania funkcji obsługi sygnału. SA_ONESHOT jest przestarzałym, niestandardowym synonimem tej flagi.

    SA_RESTART
        Dostarcza zachowania kompatybilnego z semantyką sygnałową BSD, czyniąc pewne wywołania systemowe odtwarzalnymi przez sygnały. Flaga ta ma znaczenie podczas ustanawiania procedury obsługi sygnału. Informacje na temat odtwarzania wywołań systemowych można znaleźć w podręczniku signal(7).

    SA_SIGINFO (od Linuksa 2.2)
        Funkcja obsługi sygnałów pobiera trzy argumenty, a nie jeden. W typ przypadku zamiast ustawiać sa_handler należy ustawić sa_sigaction. Flaga ta ma znaczenie tylko w przypadku ustanawiania funkcji obsługi sygnału.

Argument 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ść zmiennej errno */
    int      si_code;     /* Kod sygnału */
    int      si_trapno;   /* Numer pułapki, które spowodowała
                             sprzętowe wygenerowanie sygnału
                             (nieużywane na większości architektur) */
    pid_t    si_pid;      /* ID procesu wysyłającego */
    uid_t    si_uid;      /* Rzeczywiste ID użytkownika procesu wysyłającego */
    int      si_status;   /* Kod lub sygnał zakończenia */
    clock_t  si_utime;    /* Czas zużyty w przestrzeni użytkownika */
    clock_t  si_stime;    /* Czas zużyty przez system operacyjny */
    sigval_t si_value;    /* Wartość sygnału */
    int      si_int;      /* Sygnał POSIX.1b */
    void    *si_ptr;      /* Sygnał POSIX.1b */
    int      si_overrun;  /* Licznik przekroczeń timerów; timery POSIX.1b */
    int      si_timerid;  /* ID timera; timery POSIX.1b */
    void    *si_addr;     /* Adres pamięci powodujący błąd */
    long     si_band;     /* Grupa zdarzenia (był int w
                             glibc 2.3.2 i wcześniejszych) */
    int      si_fd;       /* Deskryptor pliku */
    short    si_addr_lsb; /* Mniej istotny bit adresu
                             (od Linuksa 2.6.32) */
}

si_signo, si_errno i si_code są zdefiniowane dla wszystkich sygnałów. (Generalnie si_errno nie jest używane pod Linuksem). Pozostałe pola struktury mogą być unią; powinno się odczytywać tylko pola istotne dla danego sygnału.

*   Sygnały wysłane przez kill(2) i sigqueue(3) mają wypełnione pola si_pid oraz si_uid. Dodatkowo sygnały wysłane przez sigqueue(3) mają w polach si_int i si_ptr ustawione wartości podane przez nadawcę sygnału; szczegóły opisano w sigqueue(3).

*   Sygnały wysłane przez timery POSIX.1b (od Linuksa 2.6) mają uzupełnione pola si_overrun i si_timerid. Pole si_timerid zawiera wewnętrzny identyfikator używany przez jądro do identyfikacji timera; nie jest to ten sam identyfikator, który zwraca timer_create(2). Pole si_overrun zawiera informację o tym, ile razy timer się przepełnił — jest to ta sama informacja, którą zwraca timer_getoverrun(2). Pola te są niestandardowymi rozszerzeniami Linuksa.

*   Sygnały wysłane w celu notyfikacji kolejki komunikatów (patrz opis SIGEV_SIGNAL in mq_notify(3)) mają pola si_int/si_ptr wypełnione wartościami sigev_value przekazanymi do mq_notify(3); ponadto si_pid zawiera identyfikator procesu wysyłającego sygnał, a si_uid rzeczywisty identyfikator użytkownika - nadawcy sygnału.

*   SIGCHLD ustawia pola si_pid, si_uid, si_status, si_utime i si_stime, dostarczając informacji o procesie potomnym. Pole si_pid jest identyfikatorem potomka, si_uid jest identyfikatorem rzeczywistego użytkownika procesu potomnego. Pole si_status zawiera kod zakończenia potomka (jeśli si_code jest równe CLD_EXITED) lub numer sygnału, który spowodował zmianę stanu. Pola si_utime i si_stime zawierają czasy spędzone przez potomka w przestrzeniach użytkownika i systemowej; w przeciwieństwie do getrusage(2) i time(2), pola te nie zawierają czasów oczekiwania na potomków. W jądrach wcześniejszych niż 2.6, a także w 2.6.27 i nowszych, pola zawierają czas CPU w jednostkach sysconf(_SC_CLK_TCK). W jądrach 2.6 wcześniejszych niż 2.6.27 z powodu błędu używane były (konfigurowalne) jednostki jiffy (patrz time(7)).

*   SIGILL, SIGFPE, SIGSEGV, SIGBUS oraz SIGTRAP wypełniają si_addr, ustawiając w nim adres błędu. Na niektórych architekturach sygnał wypełniają także pole si_trapno. Niektóre błędy pochodne SIGBUS, w szczególności BUS_MCEERR_AO i BUS_MCEERR_AR ustawiają także si_addr_lsb. Pole to oznacza najmniej znaczący bit adresu, zatem i rozmiary uszkodzeń. Na przykład jeśli cała strona została uszkodzona, si_addr_lsb zawierać będzie log2(sysconf(_SC_PAGESIZE)). BUS_MCERR_* i si_addr_lsb są rozszerzeniami specyficznymi dla Linuksa.

*   SIGIO/SIGPOLL (te dwie nazwy są synonimami pod Linuksem) wypełnia pola si_band i si_fd. Zdarzenie si_band jest maską bitową zawierającą te same wartości, które poll(2) umieszcza w polu revents. Pole si_fd oznacza deskryptor pliku, na którym wystąpiło dane zdarzenie wejścia/wyjścia.

si_code jest wartością (a nie maską bitową) określającą powód wysłania sygnału. Poniżej zestawiono wartości, które mogą występować w si_code dowolnego sygnału razem z powodami, dla których sygnał był wygenerowany.

    SI_USER
        kill(2)

    SI_KERNEL
        Wysyłany przez jądro.

    SI_QUEUE
        sigqueue(3)

    SI_TIMER
        Wygaśnięcie timera POSIX

    SI_MESGQ
        Zmiana stanu kolejki komunikatów POSIX (od Linuksa 2.6.6); patrz mq_notify(3)

    SI_ASYNCIO
        Ukończenie asynchronicznej operacji wejścia/wyjścia

    SI_SIGIO
        Kolejkowany SIGIO (tylko w jądrach do wersji 2.2 Linuksa; od Linuksa 2.4 SIGIO/SIGPOLL wypełniają si_code, tak jak to opisano poniżej).

    SI_TKILL
        tkill(2) lub tgkill(2) (od Linuksa 2.4.19)

Następujące wartości mogą zostać umieszczone w si_code sygnału 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

Następujące wartości mogą zostać umieszczone w si_code sygnału 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

Następujące wartości mogą zostać umieszczone w si_code sygnału SIGSEGV:

    SEGV_MAPERR
        adres niemapowany do obiektu

    SEGV_ACCERR
        niepoprawne uprawnienia mapowanego obiektu

Następujące wartości mogą zostać umieszczone w si_code sygnału SIGBUS:

    BUS_ADRALN
        niepoprawne wyrównanie adresu

    BUS_ADRERR
        nieistniejący adres fizyczny

    BUS_OBJERR
        błąd sprzętowy specyficzny dla obiektu

    BUS_MCEERR_AR (od Linuksa 2.6.32)
        Sprzętowy błąd pamięci podczas sprawdzania komputera; wymagane podjęcie akcji.

    BUS_MCEERR_AO (od Linuksa 2.6.32)
        Wykryto sprzętowy błąd pamięci w procesie; opcjonalne podjęcie akcji.

Następujące wartości mogą zostać umieszczone w si_code sygnału SIGTRAP:

    TRAP_BRKPT
        punkt wstrzymania procesu

    TRAP_TRACE
        śledzony proces złapany

    TRAP_BRANCH (od Linuksa 2.4)
        śledzone rozgałęzienie procesu złapane

    TRAP_HWBKPT (od Linuksa 2.4)
        pułapka sprzętowa

Następujące wartości mogą zostać umieszczone w si_code sygnału SIGCHLD:

    CLD_EXITED
        proces-dziecko się zakończył

    CLD_KILLED
        proces-dziecko został zabity

    CLD_DUMPED
        potomek zakończył się w nienormalny sposób

    CLD_TRAPPED
        śledzony potomek został złapany

    CLD_STOPPED
        proces-potomek został zatrzymany

    CLD_CONTINUED
        zatrzymany potomek został wznowiony (od Linuksa 2.6.9)

Następujące wartości mogą zostać umieszczone w si_code sygnału SIGIO/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() w przypadku powodzenia zwraca 0. W razie wystąpienia błędu zwracane jest -1 i ustawiana jest zmienna errno wskazując na 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.

ZGODNE Z
POSIX.1-2001, SVr4.

UWAGI
Potomek utworzony przez fork(2) dziedziczy kopię ustawień sygnałów swojego rodzica. Podczas execve(2) ustawienia procedur obsługi sygnałów są resetowane do wartości domyślnych, z wyjątkiem sygnałów ignorowanych, które nie są zmieniane (i będą dalej ignorowane po wywołaniu execve(2)).

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.

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.

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.

Listę funkcji, które można bezpiecznie wywołać w procedurze obsługi sygnału, można znaleźć w podręczniku signal(7).

  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 Linux. To użycie jest obecnie przestarzałe.

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.

PRZYKŁAD
Patrz mprotect(2).

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

O STRONIE
Angielska wersja tej strony pochodzi z wydania 3.52 projektu Linux man-pages. Opis projektu oraz informacje dotyczące zgłaszania błędów można znaleźć pod adresem http://www.kernel.org/doc/man-pages/.

TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika man są: Przemek Borys (PTM) <pborys@dione.ids.pl>, Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>.

Polskie tłumaczenie jest częścią projektu manpages-pl; uwagi, pomoc, zgłaszanie błędów na stronie http://sourceforge.net/projects/manpages-pl/. Jest zgodne z wersją 3.52 oryginału.