Scroll to navigation

signal(2) System Calls Manual signal(2)

NUME

signal - gestionarea semnalelor ANSI C

BIBLIOTECA

Biblioteca C standard (libc, -lc)

REZUMAT

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

DESCRIERE

ATENȚIE: comportamentul signal() variază între versiunile UNIX și a variat, de asemenea, de-a lungul timpului, între diferitele versiuni de Linux. Evitați utilizarea sa: utilizați în schimb sigaction(2). A se vedea secțiunea Portabilitate de mai jos.

signal() stabilește dispoziția semnalului signum la handler, care este fie SIG_IGN, SIG_DFL, fie adresa unei funcții definite de programator (un „gestionar de semnal”).

Dacă semnalul signum este transmis procesului, atunci apare una dintre următoarele situații:

*
Dacă dispoziția este stabilită la SIG_IGN, atunci semnalul este ignorat.
*
Dacă dispoziția este stabilită la SIG_DFL, atunci are loc acțiunea implicită asociată cu semnalul (a se vedea signal(7)).
*
Dacă dispoziția este stabilită la o funcție, atunci mai întâi fie dispoziția este restabilită la SIG_DFL, fie semnalul este blocat (a se vedea secțiunea Portabilitate de mai jos), iar apoi se apelează handler cu argumentul signum. În cazul în care invocarea gestionarului a cauzat blocarea semnalului, atunci semnalul se deblochează la returnarea gestionarului.

Semnalele SIGKILL și SIGSTOP nu pot fi capturate sau ignorate.

VALOAREA RETURNATĂ

signal() returnează valoarea anterioară a gestionarului de semnal. În caz de eșec, returnează SIG_ERR, iar errno este configurată pentru a indica eroarea.

ERORI-IEȘIRE

signum nu este valid.

VERSIUNI

Utilizarea lui sighandler_t este o extensie GNU, expusă dacă este definită _GNU_SOURCE; glibc definește, de asemenea, sig_t (derivat din BSD) dacă este definită _BSD_SOURCE (glibc 2.19 și versiunile anterioare) sau _DEFAULT_SOURCE (glibc 2.19 și versiunile ulterioare). Fără utilizarea unui astfel de tip, declarația lui signal() este cu atât mai greu de citit:


void ( *signal(int signum, void (*handler)(int)) ) (int);

Portabilitate

Singura utilizare portabilă a signal() este de a stabili dispoziția unui semnal la SIG_DFL sau SIG_IGN. Semantica atunci când se utilizează signal() pentru a stabili un gestionar de semnal variază de la un sistem la altul (iar POSIX.1 permite în mod explicit această variație); nu o utilizați în acest scop..

POSIX.1 a rezolvat problema portabilității prin specificarea sigaction(2), care oferă un control explicit al semanticii atunci când este invocat un gestionar de semnal; utilizați această interfață în loc de signal().

STANDARDE

C11, POSIX.1-2008.

ISTORIC

C89, POSIX.1-2001.

În sistemele UNIX originale, atunci când un gestionar stabilit cu ajutorul signal() era invocat de livrarea unui semnal, dispoziția semnalului era restabilită la SIG_DFL, iar sistemul nu bloca livrarea altor instanțe ale semnalului. Acest lucru este echivalent cu apelarea sigaction(2) cu următoarele fanioane:


sa.sa_flags = SA_RESETHAND | SA_NODEFER;

System V oferă, de asemenea, această semantică pentru signal(). Acest lucru era rău deoarece semnalul putea fi transmis din nou înainte ca operatorul să aibă șansa de a se restabili. În plus, transmiterea rapidă a aceluiași semnal ar putea duce la invocări recursive ale gestionarului.

BSD a îmbunătățit această situație, dar, din păcate, a schimbat și semantica interfeței signal() existente. Pe BSD, atunci când este invocat un gestionar de semnal, dispoziția semnalului nu este restabilită, iar alte instanțe ale semnalului sunt blocate în timp ce gestionarul este în curs de execuție. În plus, anumite apeluri de sistem cu blocare sunt repornite automat dacă sunt întrerupte de un gestionar de semnal (a se vedea signal(7)). Semantica BSD este echivalentă cu apelarea sigaction(2) cu următoarele fanioane:


sa.sa_flags = SA_RESTART;

Situația în Linux este următoarea:

Apelul de sistem signal() al nucleului asigură semantica System V.
În mod implicit, în glibc 2 și versiunile ulterioare, funcția de învăluire signal() nu invocă apelul de sistem al nucleului. În schimb, aceasta apelează sigaction(2) folosind fanioane care furnizează semantica BSD. Acest comportament implicit este furnizat atâta timp cât este definită o macro de testare a funcției corespunzătoare: _BSD_SOURCE pe glibc 2.19 și versiunile anterioare sau _DEFAULT_SOURCE în glibc 2.19 și versiunile ulterioare; (în mod implicit, aceste macro sunt definite; consultați feature_test_macros(7) pentru detalii). Dacă o astfel de macro de testare a caracteristicilor nu este definită, atunci signal() oferă semantica System V.

NOTE

Efectele lui signal() într-un proces cu mai multe fire de execuție sunt nespecificate.

În conformitate cu POSIX, comportamentul unui proces este nedefinit după ce acesta ignoră un semnal SIGFPE, SIGILL sau SIGSEGV care nu a fost generat de kill(2) sau raise(3). Divizarea unui număr întreg cu zero are un rezultat nedefinit. Pe unele arhitecturi, aceasta va genera un semnal SIGFPE; (de asemenea, împărțirea celui mai negativ număr întreg cu -1 poate genera SIGFPE). Ignorarea acestui semnal ar putea duce la o buclă fără sfârșit.

A se vedea sigaction(2) pentru detalii despre ce se întâmplă atunci când dispoziția SIGCHLD este stabilită la SIG_IGN.

A se vedea signal-safety(7) pentru o listă a funcțiilor async-signal-safe care pot fi apelate în siguranță din interiorul unui gestionar de semnal.

CONSULTAȚI ȘI

kill(1), alarm(2), kill(2), pause(2), sigaction(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), bsd_signal(3), killpg(3), raise(3), siginterrupt(3), sigqueue(3), sigsetops(3), sigvec(3), sysv_signal(3), signal(7)

TRADUCERE

Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.

30 martie 2023 Pagini de manual de Linux 6.05.01