/// @file signal.h /// @brief Signals definition. /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. #pragma once #include "sys/types.h" /// @brief List of signals. typedef enum { SIGHUP = 1, ///< Hang up detected on controlling terminal or death of controlling process. SIGINT = 2, ///< Issued if the user sends an interrupt signal (Ctrl + C). SIGQUIT = 3, ///< Issued if the user sends a quit signal (Ctrl + D). SIGILL = 4, ///< Illegal Instruction. SIGTRAP = 5, ///< Trace/breakpoint trap. SIGABRT = 6, ///< Abort signal from abort(). SIGEMT = 7, ///< Emulator trap. SIGFPE = 8, ///< Floating-point arithmetic exception. SIGKILL = 9, ///< If a process gets this signal it must quit immediately and will not perform any clean-up operations. SIGBUS = 10, ///< Bus error (bad memory access). SIGSEGV = 11, ///< Invalid memory reference. SIGSYS = 12, ///< Bad system call (SVr4). SIGPIPE = 13, ///< Broken pipe: write to pipe with no readers. SIGALRM = 14, ///< Alarm clock signal (used for timers). SIGTERM = 15, ///< Software termination signal (sent by kill by default). SIGUSR1 = 16, ///< User-defined signal 1. SIGUSR2 = 17, ///< User-defined signal 2. SIGCHLD = 18, ///< Child stopped or terminated. SIGPWR = 19, ///< Power failure. SIGWINCH = 20, ///< Window resize signal. SIGURG = 21, ///< Urgent condition on socket. SIGPOLL = 22, ///< Pollable event. SIGSTOP = 23, ///< Stop process. SIGTSTP = 24, ///< Stop typed at terminal. SIGCONT = 25, ///< Continue if stopped. SIGTTIN = 26, ///< Terminal input for background process. SIGTTOU = 27, ///< Terminal output for background process. SIGVTALRM = 28, ///< Virtual alarm clock. SIGPROF = 29, ///< Profiling timer expired. SIGXCPU = 30, ///< CPU time limit exceeded. SIGXFSZ = 31, ///< File size limit exceeded. NSIG } signal_type_t; /// @brief Codes that indentify the sender of a signal. typedef enum { SI_NOINFO, ///< Unable to determine complete signal information. // Signal : - // Enabled fields : si_pid, si_uid SI_USER, ///< Signal sent by kill(), pthread_kill(), raise(), abort() or alarm(). // Signal : - // Enabled fields : - SI_KERNEL, ///< Generic kernel function // Signal : - // Enabled fields : si_pid, si_uid, si_value SI_QUEUE, ///< Signal was sent by sigqueue(). SI_TIMER, ///< Signal was generated by expiration of a timer set by timer_settimer(). SI_ASYNCIO, ///< Signal was generated by completion of an asynchronous I/O request. SI_MESGQ, ///< Signal was generated by arrival of a message on an empty message queue. // Signal : SIGILL // Enabled fields : si_addr (address of failing instruction) ILL_ILLOPC, ///< Illegal opcode. ILL_ILLOPN, ///< Illegal operand. ILL_ILLADR, ///< Illegal addressing mode. ILL_ILLTRP, ///< Illegal trap. ILL_PRVOPC, ///< Privileged opcode. ILL_PRVREG, ///< Privileged register. ILL_COPROC, ///< Coprocessor error. ILL_BADSTK, ///< Internal stack error. // Signal : SIGFPE // Enabled fields : si_addr (address of failing instruction) FPE_INTDIV, ///< Integer divide-by-zero. FPE_INTOVF, ///< Integer overflow. FPE_FLTDIV, ///< Floating point divide-by-zero. FPE_FLTOVF, ///< Floating point overflow. FPE_FLTUND, ///< Floating point underflow. FPE_FLTRES, ///< Floating point inexact result. FPE_FLTINV, ///< Invalid floating point operation. FPE_FLTSUB, ///< Subscript out of range. // Signal : SIGSEGV // Enabled fields : si_addr (address of faulting memory reference) SEGV_MAPERR, ///< Address not mapped. SEGV_ACCERR, ///< Invalid permissions. // Signal : SIGBUS // Enabled fields : si_addr (address of faulting memory reference) BUS_ADRALN, ///< Invalid address alignment. BUS_ADRERR, ///< Non-existent physical address. BUS_OBJERR, ///< Object-specific hardware error. // Signal : SIGTRAP // Enabled fields : - TRAP_BRKPT, ///< Process breakpoint. TRAP_TRACE, ///< Process trace trap. // Signal : SIGCHLD // Enabled fields : si_pid (child process ID) // si_uid (real user ID of process that sent the signal) // si_status (exit value or signal) CLD_EXITED, ///< Child has exited. CLD_KILLED, ///< Child has terminated abnormally and did not create a core file. CLD_DUMPED, ///< Child has terminated abnormally and created a core file. CLD_TRAPPED, ///< Traced child has trapped. CLD_STOPPED, ///< Child has stopped. CLD_CONTINUED, ///< Stopped child has continued. // Signal : SIGIO/SIGPOLL // Enabled fields : si_band POLL_IN, ///< Data input available. POLL_OUT, ///< Output buffers available. POLL_MSG, ///< Input message available. POLL_ERR, ///< I/O error. POLL_PRI, ///< High priority input available. POLL_HUP, ///< Device disconnected. } signal_sender_code_t; /// @brief Defines what to do with the provided signal mask. typedef enum { /// @brief The set of blocked signals is the union of the current set /// and the set argument. SIG_BLOCK, /// @brief The signals in set are removed from the current set of /// blocked signals. It is permissible to attempt to unblock /// a signal which is not blocked. SIG_UNBLOCK, /// @brief The set of blocked signals is set to the argument set. SIG_SETMASK } sigmask_how_t; /// @defgroup SigactionFlags Flags associated with a sigaction. /// @{ #define SA_NOCLDSTOP 0x00000001U ///< Turn off SIGCHLD when children stop. #define SA_NOCLDWAIT 0x00000002U ///< Flag on SIGCHLD to inhibit zombies. #define SA_SIGINFO 0x00000004U ///< sa_sigaction specifies the signal-handling function for signum. #define SA_ONSTACK 0x08000000U ///< Indicates that a registered stack_t will be used. #define SA_RESTART 0x10000000U ///< Flag to get restarting signals (which were the default long ago) #define SA_NODEFER 0x40000000U ///< Prevents the current signal from being masked in the handler. #define SA_RESETHAND 0x80000000U ///< Clears the handler when the signal is delivered. /// @} /// Type of a signal handler. typedef void (*sighandler_t)(int); #define SIG_DFL ((sighandler_t)0) ///< Default signal handling. #define SIG_IGN ((sighandler_t)1) ///< Ignore signal. #define SIG_ERR ((sighandler_t)-1) ///< Error return from signal. /// @brief Structure used to mask and unmask signals. /// @details /// Each unsigned long consists of 32 bits, thus, the maximum number of signals /// that may be declared is 64. /// Signals are divided into two cathegories, identified by the two unsigned longs: /// [ 1, 31] corresponds to normal signals; /// [32, 64] corresponds to real-time signals. typedef struct sigset_t { /// Signals divided into two cathegories. unsigned long sig[2]; } sigset_t; /// @brief Holds the information on how to handle a specific signal. typedef struct sigaction_t { /// This field specifies the type of action to be performed; its value can be a pointer /// to the signal handler, SIG_DFL (that is, the value 0) to specify that the default /// action is performed, or SIG_IGN (that is, the value 1) to specify that the signal is /// ignored. sighandler_t sa_handler; /// This sigset_t variable specifies the signals to be masked when running the signal handler sigset_t sa_mask; /// This set of flags specifies how the signal must be handled; unsigned int sa_flags; } sigaction_t; /// @brief Data passed with signal info. typedef union sigval { int sival_int; ///< Integer value. void *sival_ptr; ///< Pointer value. } sigval_t; /// @brief Stores information about an occurrence of a specific signal. typedef struct siginfo_t { /// The signal number. int si_signo; /// A code identifying who raised the signal (see signal_sender_code_t). int si_code; /// Signal value. sigval_t si_value; /// The error code of the instruction that caused the signal to be raised, or 0 if there was no error. int si_errno; /// Process ID of sending process. pid_t si_pid; /// Real user ID of sending process. uid_t si_uid; /// Address at which fault occurred. void *si_addr; /// Exit value or signal for process termination. int si_status; /// Band event for SIGPOLL/SIGIO. int si_band; } siginfo_t; /// @brief Send signal to a process. /// @param pid The pid of the process to which we send the signal. /// @param sig The type of signal to send. /// @return On success 0, on error -1 and errno is set appropriately. int kill(pid_t pid, int sig); /// @brief Sets the disposition of the signal signum to handler. /// @param signum The signal number. /// @param handler The handler for the signal. /// @return The previous value of the signal handler, or SIG_ERR on error. sighandler_t signal(int signum, sighandler_t handler); /// @brief Examine and change a signal action. /// @param signum Specifies the signal and can be any valid signal except SIGKILL and SIGSTOP. /// @param act If non-NULL, the new action for signal signum is installed from act. /// @param oldact If non-NULL, the previous action is saved in oldact. /// @return returns 0 on success; on error, -1 is returned, and errno is set to indicate the error. int sigaction(int signum, const sigaction_t *act, sigaction_t *oldact); /// @brief Examine and change blocked signals. /// @param how Determines the behavior of the call. /// @param set The set of signals to manage by the function. /// @param oldset If non-NULL, the previous value of the signal mask is stored here. /// @return returns 0 on success, and -1 on error (errno is set to indicate the cause). /// @details /// If set is NULL, then the signal mask is unchanged (i.e., how is /// ignored), but the current value of the signal mask is /// nevertheless returned in oldset (if it is not NULL). int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); /// @brief Returns the string describing the given signal. /// @param sig The signal to inquire. /// @return String representing the signal. const char *strsignal(int sig); /// @brief Prepare an empty set. /// @param set The set to manipulate. /// @return 0 on success and -1 on error. int sigemptyset(sigset_t *set); /// @brief Prepare a full set. /// @param set The set to manipulate. /// @return 0 on success and -1 on error. int sigfillset(sigset_t *set); /// @brief Adds the given signal to the correct set. /// @param set The set to manipulate. /// @param signum The signalt to handle. /// @return 0 on success and -1 on error. int sigaddset(sigset_t *set, int signum); /// @brief Removes the given signal to the correct set. /// @param set The set to manipulate. /// @param signum The signalt to handle. /// @return 0 on success and -1 on error. int sigdelset(sigset_t *set, int signum); /// @brief Checks if the given signal is part of the set. /// @param set The set to manipulate. /// @param signum The signalt to handle. /// @return 1 if signum is a member of set, /// 0 if signum is not a member, and -1 on error. int sigismember(sigset_t *set, int signum);