sigaction(2) | System Calls Manual | sigaction(2) |
sigaction, rt_sigaction - bada i zmienia akcję sygnału
Standardowa biblioteka C (libc, -lc)
#include <signal.h>
int sigaction(int signum, const struct sigaction *_Nullable restrict act, struct sigaction *_Nullable restrict oldact);
sigaction():
_POSIX_C_SOURCE
siginfo_t:
_POSIX_C_SOURCE >= 199309L
Wywołanie systemowe sigaction() jest używane do zmieniania akcji, którą odbiera 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.
Pole sa_restorer nie jest przeznaczone do bezpośredniego stosowania (POSIX nie określa pola sa_restorer). Więcej informacji o przeznaczeniu tego pola można znaleźć w podręczniku sigreturn(2).
sa_handler specifies the action to be associated with signum and can be one of the following:
If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of sa_handler) specifies the signal-handling function for signum. This function receives three arguments, as described below.
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:
When the SA_SIGINFO flag is specified in act.sa_flags, the signal handler address is passed via the act.sa_sigaction field. This handler takes three arguments, as follows:
void handler(int sig, siginfo_t *info, void *ucontext) { ... }
These three arguments are as follows
The siginfo_t data type is a structure with the following fields:
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żytk. 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 */ union sigval si_value; /* Wartość sygnału */ int si_int; /* Sygnał POSIX.1b */ void *si_ptr; /* Sygnał POSIX.1b */ int si_overrun; /* Licznik przekr. 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) */ void *si_lower; /* Kres dolny przy wystąpieniu naruszenia adresu (od Linuksa 3.19) */ void *si_upper; /* Kres górny przy wystąpieniu naruszenia adresu (od Linuksa 3.19) */ int si_pkey; /* Klucz zabezpieczający na PTE będący powodem błędu (od Linuksa 4.6) */ void *si_call_addr;/* Adres instrukcji wywołania systemowego (od Linuksa 3.5) */ int si_syscall; /* Liczba próbowanych wywołań systemowych (od Linuksa 3.5) */ unsigned int si_arch; /* Architektura próbowanego wywoł. systemowego (od Linuksa 3.5) */ }
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.
The si_code field inside the siginfo_t argument that is passed to a SA_SIGINFO signal handler is a value (not a bit mask) indicating why this signal was sent. For a ptrace(2) event, si_code will contain SIGTRAP and have the ptrace event in the high byte:
(SIGTRAP | PTRACE_EVENT_foo << 8).
For a non-ptrace(2) event, the values that can appear in si_code are described in the remainder of this section. Since glibc 2.20, the definitions of most of these symbols are obtained from <signal.h> by defining feature test macros (before including any header file) as follows:
For the TRAP_* constants, the symbol definitions are provided only in the first two cases. Before glibc 2.20, no feature test macros were required to obtain these symbols.
W przypadku zwykłego 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.
Następujące wartości mogą zostać umieszczone w si_code sygnału SIGILL:
Następujące wartości mogą zostać umieszczone w si_code sygnału SIGFPE:
Następujące wartości mogą zostać umieszczone w si_code sygnału SIGSEGV:
Następujące wartości mogą zostać umieszczone w si_code sygnału SIGBUS:
Następujące wartości mogą zostać umieszczone w si_code sygnału SIGTRAP:
Następujące wartości mogą zostać umieszczone w si_code sygnału SIGCHLD:
Następujące wartości mogą zostać umieszczone w si_code sygnału SIGIO/SIGPOLL:
Następująca wartość może zostać umieszczona w si_code sygnału SIGSYS:
The sigaction() call on Linux accepts unknown bits set in act->sa_flags without error. The behavior of the kernel starting with Linux 5.11 is that a second sigaction() will clear unknown bits from oldact->sa_flags. However, historically, a second sigaction() call would typically leave those bits set in oldact->sa_flags.
This means that support for new flags cannot be detected simply by testing for a flag in sa_flags, and a program must test that SA_UNSUPPORTED has been cleared before relying on the contents of sa_flags.
Since the behavior of the signal handler cannot be guaranteed unless the check passes, it is wise to either block the affected signal while registering the handler and performing the check in this case, or where this is not possible, for example if the signal is synchronous, to issue the second sigaction() in the signal handler itself.
In kernels that do not support a specific flag, the kernel's behavior is as if the flag was not set, even if the flag was set in act->sa_flags.
The flags SA_NOCLDSTOP, SA_NOCLDWAIT, SA_SIGINFO, SA_ONSTACK, SA_RESTART, SA_NODEFER, SA_RESETHAND, and, if defined by the architecture, SA_RESTORER may not be reliably probed for using this mechanism, because they were introduced before Linux 5.11. However, in general, programs may assume that these flags are supported, since they have all been supported since Linux 2.6, which was released in the year 2003.
See EXAMPLES below for a demonstration of the use of SA_UNSUPPORTED.
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.
POSIX.1-2001, POSIX.1-2008, SVr4.
Dziecko utworzone przez fork(2) dziedziczy kopię ustawień sygnałów od swojego rodzica. Podczas wywołania execve(2) przywracane są wartości domyślne ustawień, z wyjątkiem ustawienia ignorowania sygnału, które nie jest zmieniane.
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 i późniejsze pozwalają 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 System V 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_NOCLDSTOP, SA_NOCLDWAIT, SA_NODEFER, SA_ONSTACK, SA_RESETHAND, SA_RESTART 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.
The SA_NODEFER flag is compatible with the SVr4 flag of the same name under kernels 1.3.9 and later. On older kernels the Linux implementation allowed the receipt of any signal, not just the one we are installing (effectively overriding any sa_mask settings).
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-safety(7).
Funkcja opakowująca glibc dla sigaction() daje błąd (EINVAL) przy próbie zmiany dyspozycji dwóch sygnałów czasu rzeczywistego używanych wewnętrznie przez implementację wątkową NPTL. Więcej szczegółów w podręczniku nptl(7).
On architectures where the signal trampoline resides in the C library, the glibc wrapper function for sigaction() places the address of the trampoline code in the act.sa_restorer field and sets the SA_RESTORER flag in the act.sa_flags field. See sigreturn(2).
Oryginalne linuksowe wywołanie systemowe nazywało się sigaction(). Jednak po pojawieniu się sygnałów czasu rzeczywistego w Linuksie 2.2, 32-bitowy typ sigset_t o stałym rozmiarze obsługiwany przez to wywołanie przestał dobrze służyć swemu zadaniu. Z tego powodu, w celu obsługi powiększonego typu sigset_t dodano nowe wywołanie systemowe rt_sigaction(). Nowe wywołanie przyjmuje czwarty argument size_t sigsetsize, który określa rozmiar w bajtach zestawu sygnałów w act.sa_mask i oldact.sa_mask. Argument ten obecnie musi mieć wartość sizeof(sigset_t) (albo nastąpi błąd EINVAL). Opakowanie glibc sigaction() ukrywa te detale przed nami, po cichu wywołując rt_sigaction() jeśli udostępnia je jądro.
Before the introduction of SA_SIGINFO, it was also possible to get some additional information about the signal. This was done by providing an sa_handler signal handler with a second argument of type struct sigcontext, which is the same structure as the one that is passed in the uc_mcontext field of the ucontext structure that is passed (via a pointer) in the third argument of the sa_sigaction handler. See the relevant Linux kernel sources for details. This use is obsolete now.
When delivering a signal with a SA_SIGINFO handler, the kernel does not always provide meaningful values for all of the fields of the siginfo_t that are relevant for that signal.
Up to and including Linux 2.6.13, specifying SA_NODEFER in sa_flags prevents not only the delivered signal from being masked during execution of the handler, but also the signals specified in sa_mask. This bug was fixed in Linux 2.6.14.
Patrz mprotect(2).
The following example program exits with status EXIT_SUCCESS if SA_EXPOSE_TAGBITS is determined to be supported, and EXIT_FAILURE otherwise.
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> 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); }
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)
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Przemek Borys <pborys@dione.ids.pl>, Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.
10 lutego 2023 r. | Linux man-pages 6.03 |