sigaction(2) | System Calls Manual | sigaction(2) |
sigaction, rt_sigaction - onderzoek en verander een signaal actie
Standard C bibliotheek (libc, -lc)
#include <stdio.h>
int sigaction(int signum, const struct sigaction *restrict act, struct sigaction *_NULL_baar restrict oudeact);
sigaction():
_POSIX_C_SOURCE
siginfo_t:
_POSIX_C_SOURCE >= 199309L
De sigaction() systeem aanroep wordt gebruikt om de te nemen actie door een proces bij ontvangst van een signaal te veranderen. (Zie signal(7) voor een overzicht van de signalen.)
signum bepaald het signaal en kan elk geldig signaal zijn behalve SIGKILL en SIGSTOP.
Als act on-gelijk nul is wordt de nieuwe actie voor het signaal signum geïnstalleerd van act. Als oudeact niet-nul is, dan wordt de vorige actie bewaard in oudeact.
De sigaction structuur is bepaald als
struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); };
Op sommige architecturen wordt een union gebruikt: ken niet aan beiden sa_handler en sa_sigaction toe
Het sa_restorer veld is is niet bedoeld voor gebruik in applicaties. (POSIX specificeert het sa_restorer veld niet.) Meer details over het doel van dit veld kunnen worden gevonden in sigreturn(2)
sa_handler specificeert de actie die wordt geassocieerd met signum en die kan een van de volgende zijn:
Als SA_SIGINFO werd opgegeven in sa_flags dan specificeert sa_sigaction (in plaats van sa_handler) de signaal afhandel functie voor signum. Deze functie ontvangt drie argumenten zoals hieronder beschreven.
sa_mask specificeert een masker voor signalen die geblokkeerd zouden moeten worden (dat is, toegevoegd aan een signaal masker van de thread in welke de signaal afhandelaar wordt aangeroepen) tijdens de uitvoering van de signaal afhandelaar. In toevoeging daarop zal het signaal dat de behandelaar af liet gaan geblokkeerd worden, tenzij de SA_NODEFER vlag werd gebruikt.
sa_flags geeft een aantal vlaggen op die het gedrag van het signaal behandelings proces aanpassen. Het wordt gevormd door de bitsgewijze OF van nul of meer van het volgende:
Indien de SA_SIGINFO vlag werd gespecificeerd in act.sa_flags dan wordt het adres van de afhandelaar doorgegeven via het act.sa_sigaction veld. Deze afhandelaar heeft drie argumenten, die zijn als volgt:
void handler(int sig, siginfo_t *info, void *ucontext) { ... }
Deze drie argumenten zijn als volgt
Het siginfo_t data type is een structure met de volgende velden:
siginfo_t { int si_signo; /* Signaal nummer */ int si_errno; /* Een fout waarde */ int si_code; /* Signaal code */ int si_trapno; /* Trap nummer dat het hardware-gegenereerde signaal veroorzaakte (ongebruikt op de meeste architecturen) */ pid_t si_pid; /* proces ID van de zender*/ uid_t si_uid; /* Huidig UID van zendende proces */ int si_status; /* Exit waarde of signaal */ clock_t si_utime; /* Gebruikte User tijd */ clock_t si_stime; /* Gebruikte Systeem tijd */ union sigval si_value; /* Signaal waarde */ int si_int; /* POSIX.1b signal */ void *si_ptr; /* POSIX.1b signal */ int si_overrun; /* Timer overrun teller; POSIX.1b timers */ int si_timerid; /* Timer ID; POSIX.1b timers */ void *si_addr; /* Geheugen locatie die fout veroorzaakte */ long si_band; /* Band gebeurtenis (was int in glibc 2.3.2 en eerder) */ int si_fd; /* Bestandsindicator */ short si_addr_lsb; /* Minst significant bit van adres (vanaf Linux 2.6.32) */ void *si_lower; /* Laagste grens bij adres schending occurred (vanaf Linux 3.19) */ void *si_upper; /* Hoogste grens bij adres schending occurred (vanaf Linux 3.19) */ int si_pkey; /* Beveiliging sleutel op PTE die fout veroorzaakte (vanaf Linux 4.6) */ void *si_call_addr; /* Addres van de systeem aanroep instructie (vanaf Linux 3.5) */ int si_syscall; /* Aantal geprobeerde systeem aanroepen (vanaf Linux 3.5) */ unsigned int si_arch; /* Architecture van geprobeerde systeem aanroep (vanaf Linux 3.5) */ }
si_signo, si_errno en si_code zijn gedefinieerd voor alle signalen. (si_errno wordt in het algemeen niet gebruikt op Linux.) De rest van de structure mag een union zijn, zodat men alleen die velden moet lezen die van betekenis zijn voor het gegeven signaal:
Het si_code veld in het siginfo_t argument, dat wordt doorgegeven naar een SA_SIGINFO signaal afhandelaar, is een waarde (geen bit masker) die aangeeft waarom dit signaal werd verstuurd. Voor een ptrace(2) gebeurtenis zal si_code SIGTRAP bevatten en heeft een ptrace gebeurtenis in het hoge byte:
(SIGTRAP | PTRACE_EVENT_foo << 8).
Voor een niet-ptrace gebeurtenis, worden de waarden die kunnen verschijnen in si_code beschreven in het vervolg van deze sectie. Vanaf glibc 2.20 worden de definities van de meeste symbolen verkregen uit <signal.h> door het definiëren van feature test macro´s (vóór het invoegen van enig header bestand) als volgt:
Voor de TRAP_* constanten worden de symbool definities alleen in de eerste twee gevallen voorzien. Voor glibc 2.20 werden geen feature test macro´s vereist om deze symbolen te verkrijgen.
Voor een regulier signaal toont de volgende lijst de waarden die kunnen worden geplaatst in si_code voor elk signaal, samen met de reden waarom dat signaal werd gegenereerd.
De volgende waarden kunnen worden geplaatst in si_code voor een SIGILL signaal:
De volgende waarden kunnen worden geplaatst in si_code voor een SIGFPE signaal:
De volgende waarden kunnen worden geplaatst in si_code voor een SIGSEGV signaal:
De volgende waarden kunnen worden geplaatst in si_code voor een SIGBUS signaal:
De volgende waarden kunnen worden geplaatst in si_code voor een SIGTRAP signaal:
De volgende waarden kunnen worden geplaatste in si_code voor een SIGCHLD signaal:
De volgende waarden kunnen worden gezet in si_code voor een SIGIO/SIGPOLL signaal:
De volgende waarde kan worden geplaatst in si_code voor een SIGSYS signaal:
De sigaction() aanroep in Linux accepteert onbekende bits gezet in act->sa_flags zonder een fout. Het gedrag van de kernel vanaf Linux 5.11 is dat een tweede sigaction() onbekende bits in oudeact->sa_flags zal wissen. Echter, historisch, zou een tweede sigaction() aanroep deze bits typisch gezet laten in oudeact->sa_flags.
Dit betekent dat ondersteuning van nieuwe vlaggen niet kan worden gedetecteerd door het eenvoudigweg testen van vlaggen in sa_flags, en een programma moet testen dat SA_UNSUPPORTED gewist werd voordat het kan vertrouwen op de inhoud van sa_flags.
Omdat het gedrag van de signaal afhandelaar niet kan worden gegarandeerd behalve als de test slaagt, is het slim om ofwel het betrokken signaal te blokkeren terwijl de afhandelaar geregistreerd wordt en in geval de controle uit te voeren, ofwel indien dit niet mogelijk is, bijvoorbeeld als het signaal synchroon is, om een tweede sigaction() te maken in de signaal afhandelaar zelf.
In kernels die geen specifieke vlag ondersteunen, gedraagt de kernel zich alsof deze vlag niet werd gezet, zelfs als de vlag werd gezet in act->sa_flags.
De vlaggen SA_NOCLDSTOP, SA_NOCLDWAIT, SA_SIGINFO, SA_ONSTACK, SA_RESTART, SA_NODEFER, SA_RESETHAND, en indien gedefinieerd door dearchitectuur, SA_RESTORER mogen niet betrouwbaar getest worden om dit mechanisme te gebruiken, omdat ze geïntroduceerd werden voor Linux 5.11. Echter programma´s mogen er in het algemeen vanuit gaan dat deze vlaggen ondersteund worden, omdat ze allen ondersteund werden vanaf Linux 2.6, dat werd vrijgegeven in het jaar 2003.
Zie VOORBEELDEN hieronder voor de demonstratie van het gebruik van SA_UNSUPPORTED.
Bij succes geeft sigaction() nul terug. Bij falen wordt -1 teruggegeven en wordt errno naar behoren gezet.
POSIX.1-2001, POSIX.1-2008, SVr4.
Een kind aangemaakt met fork(2) erft een kopie van de signaal dispositie van zijn ouder. Tijdens een execcve(2) worden de disposities van de afgehandelde signalen terug gezet naar de standaard; de dispositie van de genegeerde signalen blijft onveranderd.
Volgens POSIX is het gedrag van een proces ongedefinieerd als het een SIGFPE, SIGILL of SIGSEGV negeert dat niet voortgebracht werd door de kill() of de raise() functies. Heel getal delen door nul heeft ongedefinieerd gevolg. Op sommige architecturen zal het een SIGFPE signaal veroorzaken. (Ook het delen van het meest negatieve hele getal door -1 kan een SIGFPE veroorzaken.) Negeren van dit signaal zou tot een eindeloze lus kunnen leiden.
POSIX.1-1990 stond niet toe om de actie voor SIGCHLD op SIG_IGN te zetten. POSIX.1-2001 en later stond dit toe, zodat het negeren van SIGCHLD kan worden gebruikt om zombies aan te maken (zie wait(2)). Desalniettemin verschillen de historische BSD en System V gedragingen voor negeren van SIGCHLD, daarom is de enige compleet overdraagbare methode om te voorkomen dat beëindigde kinderen zombies worden om signaal SIGCHLD op te vangen en het uitvoeren van een wait(2) of vergelijkbaar.
POSIX.1-1990 specificeerde alleen SA_NOCLDSTOP. POSIX.1-2001 voegde SA_NOCLDSTOP, SA_NOCLDWAIT, SA_NODEFER, SA_ONSTACK, SA_RESETHAND, SA_RESTART, en SA_SIGINFO toe. Het gebruik van de laatste waarden in sa_flagsis mogelijk minder overdraagbaar in applicaties die bedoeld zijn voor oudere UNIX implementaties.
De SA_RESETHAND vlag is overdraagbaar met de SVr4 vlag met dezelfde naam.
De SA_NODEFER vlag is compatibel met de SVr4 vlag met dezelfde naam onder kernels 1.3.9 en nieuwer. Op oudere kernels liet de Linux-implementatie het ontvangen van elk signaal toe, niet alleen dat dat we installeren (daarbij de sa_mask instelling overschrijvend).
sigaction() kan aangeroepen worden met een tweede argument nul om de huidige signaalbehandelaar te ondervragen. Het kan ook gebruikt worden om te testen of een gegeven signaal geldig is voor de huidige machine, door het aan te roepen met 'nul' tweede en derde argumenten.
Het is niet mogelijk om SIGKILL of SIGSTOP te blokkeren door opgeven in sa_mask. Pogingen om dat te doen zullen stilzwijgend genegeerd worden.
Ze sigsetops(3) voor details hoe signaal verzamelingen te manipuleren.
Zie signal-safety(7) voor een lijst van de async-signal-safe functies die veilig gebruikt kunnen worden binnen een signaal afhandelaar.
De glibc omwikkel functie voor sigaction() meldt een fout (EINVAL) bij pogingen om de dispositie te veranderen van de twee realtime signalen die intern worden gebruikt door de NPTL threading implementatie. Zie nptl(7) voor details.
Op architecturen waar de signaal trampoline zich in de C bibliotheek bevindt, plaatst de glibc omwikkel functie voor sigaction() het adres van de trampoline code in het act.sa_restorer veld en zet de SA_RESTORER vlag in het act.sa_flags veld. Zie sigreturn(2).
De originele Linux systeem aanroep was sigaction(). Echter met het toevoegen van realtime signalen in Linux 2.2 was het vaste-grootte 32-bit sigset_t type ondersteund door die systeem aanroep niet meer geschikt voor dit doel. Daarom werd de nieuwe systeem aanroep rt_sigaction() toegevoegd om een groter sigset_t type te ondersteunen. De nieuwe systeem aanroep benodigd een vierde argument, size_t sigsetsize, die de grootte in bytes bepaald van de signaal verzamelingen in act.sa_mask en oudeact.sa_mask. Dit argument vereist momenteel de waarde sizeof(sigset_t) (of de fout EINVAL waarde). De glibc sigaction() omwikkel functie verbergt deze details voor ons, door transparant rt_sigaction() aan te roepen wanneer de kernel daarin voorziet.
Voor de introductie van SA_SIGINFO, was het ook mogelijk om enige additionele informatie over het signaal te verkrijgen. Dit werd gedaan door het voorzien een sa_handler signaal afhandelaar met een tweede argument van het type struct sigcontext, hetgeen dezelfde structure is als die die wordt doorgegeven in het uc_mcontext veld van de ucontext structure die wordt doorgegeven (via een wijzer) in het derde argument van de sa_sigaction afhandelaar. Zie de relevante Linux kernel bronnen voor details. Dit gebruik is nu overbodig.
Tijdens het afleveren van een signaal met een SA_SIGINFO afhandelaar, voorziet de kernel niet altijd in betekenisvolle waarden voor alle velden in de siginfo_t die relevant zijn voor dat signaal.
Tot en met Linux 2.6.13 voorkomt het opgeven van SA_NODEFER in sa_flags dat het afgeleverde signaal wordt gemaskeerd tijdens het uitvoeren van de afhandelaar, maar ook voor de signalen opgegeven in sa_mask. Deze bug werd opgelost in Linux 2.6.14.
Zie mprotect(2).
Het volgende voorbeeld programma eindigt met status EXIT_SUCCESS als besloten werd om SA_EXPOSE_TAGBITS te ondersteunen, en anders EXIT_FAILURE.
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void handler(int signo, siginfo_t *info, void *context) { struct sigaction oudeact; if (sigaction(SIGSEGV, NULL, &oudeact) == -1 || (oudeact.sa_flags & SA_UNSUPPORTED) || !(oudeact.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)
De Nederlandse vertaling van deze handleiding is geschreven door Jos Boersema <joshb@xs4all.nl>, Mario Blättermann <mario.blaettermann@gmail.com> en Luc Castermans <luc.castermans@gmail.com>
Deze vertaling is vrije documentatie; lees de GNU General Public License Version 3 of later over de Copyright-voorwaarden. Er is geen AANSPRAKELIJKHEID.
Indien U fouten in de vertaling van deze handleiding zou vinden, stuur een e-mail naar debian-l10n-dutch@lists.debian.org.
10 februari 2023 | Linux man-pagina's 6.03 |