[man] signal / sigaction

숭글·2022년 9월 6일
0

Each signal has a current disposition, which determines how the process behaves when it is delivered the signal.

A process can change the disposition of a signal using sigaction or signal.

(avoid using signal(). because signal() varies across UNIX versions, and has also varied historically across different versions of Linux. But signal() is easy to use and simple. so It'd be better to be aware of it.)


The signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer-defined function (a "signal handler").

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

programmer-defined function(signal handler) is needed to be made with proper format. signal handler is given the int type parameter and returns void * type.

Example
: if SIGINT occurs, then signal_handler is called with argument signum.

void signal_handler(int signum);

...

	signal(SIGINT, signal_handler);

The sigaction() system call is used to change the action taken by a process on receipt of a specific signal.

#include <signal.h>
int sigaction(int signum, const struct sigaction *restrict act, struct sigaction *restrict oldact);

Parameters

  • signum
    : signum specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.
  • act
    : the new action for signal signum is installed from act
  • oldact
    : the previous action is saved in oldact. so you can install old act again by using this parameter. (If you don't need to use old one, then just sent NULL.)

struct sigaction

struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };
  • sa_handler specifies the action to be associated with signum. (It could be SIG_DFL, SIG_IGN either or address of function you defined.)

  • sa_sigaction (using If SA_SIGINFO is specified in sa_flags. instead of sa_handler.) specifies the signal-handling function for signum.

  • sa_mask specifies a mask of signals which should be blocked during execution of the signal handler.

  • sa_flags specifies a set of flags which modify the behavior of the signal. (see the manual if there is some option you need.)

The siginfo_t argument to a SA_SIGINFO handler
When the SA_SIGINFO flag is specified in act.sa_flags, the signal handler address is passed via the act.sa_sigaction field.

void
handler(int sig, siginfo_t info, void ucontext)
{
...
}

  • info
    : A pointer to a siginfo_t, which is a structure containing further information about the signal.

  • ucontext
    : This is a pointer to a ucontext_t structure, cast to void *. The structure pointed to by this field contains signal context information that was saved on the user-space stack by the kernel; for details, see sigreturn(2).

siginfo_t {
               int      si_signo;     /* Signal number */
               int      si_errno;     /* An errno value */
               int      si_code;      /* Signal code */
               int      si_trapno;    /* Trap number that caused
                                         hardware-generated signal
                                         (unused on most architectures) */
               pid_t    si_pid;       /* Sending process ID */
               uid_t    si_uid;       /* Real user ID of sending process */
               int      si_status;    /* Exit value or signal */
               clock_t  si_utime;     /* User time consumed */
               clock_t  si_stime;     /* System time consumed */
               union sigval si_value; /* Signal value */
               int      si_int;       /* POSIX.1b signal */
               void    *si_ptr;       /* POSIX.1b signal */
               int      si_overrun;   /* Timer overrun count;
                                         POSIX.1b timers */
               int      si_timerid;   /* Timer ID; POSIX.1b timers */
               void    *si_addr;      /* Memory location which caused fault */
               long     si_band;      /* Band event (was int in
                                         glibc 2.3.2 and earlier) */
               int      si_fd;        /* File descriptor */
               short    si_addr_lsb;  /* Least significant bit of address
                                         (since Linux 2.6.32) */
               void    *si_lower;     /* Lower bound when address violation
                                         occurred (since Linux 3.19) */
               void    *si_upper;     /* Upper bound when address violation
                                         occurred (since Linux 3.19) */
               int      si_pkey;      /* Protection key on PTE that caused
                                         fault (since Linux 4.6) */
               void    *si_call_addr; /* Address of system call instruction
                                         (since Linux 3.5) */
               int      si_syscall;   /* Number of attempted system call
                                         (since Linux 3.5) */
               unsigned int si_arch;  /* Architecture of attempted system call
                                         (since Linux 3.5) */
           }

Example

       #include <signal.h>
       #include <stdlib.h>
       #include <stdio.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);
       }

📖 man signal(7)
📖 man signal(2)
📖 man sigaction(2)

profile
Hi!😁 I'm Soongle. Welcome to my Velog!!!

0개의 댓글