UNIT-V
Signals and Daemon Processes
SIGNALS
• Signals are triggered by events and are posted on a process
to notify it that some thing has happened and requires
some action.
• Signals can be generated from a process, a user, or the
UNIX kernel.
• A process performs a divide by zero or dereferences a NULL
pointer.
• A user hits <Delete> or <Ctrl-C> key at the keyboard.
• A parent and child processes can send signals to each other
for process synchronization.
• Thus, signals are the software version of hardware
interrupts.
• Signals are defined as integer flags in the <signal.h> header
file.
Signals
• When a signal is sent to a process, it is pending on the process to
handle it.
• The process can react to signals in one of the three ways.
– Accept the default action of the signal – most signals terminate the
process
– Ignore the signal.
– Invoke a user defined function – The function is called signal hander
routine
• Most signals can be caught or ignored except the SIGKILL and
SIGSTOP signals.
• A companion signal to SIGSTOP is SIGCONT, which resumes a
process execution after it has been stopped, both SIGSTOP
• a process may specify a per signal handler function, these function
would then be called when their corresponding signals are caught.
The UNIX Kernel Supports of Signals
• In Unix System V.3, each entry in the kernel process table slot has
an array of signal flags,.
• When a signal is generated for a process, the kernel will set the
corresponding signal flag in the process table slot of the recipient
process.
• If the recipient process is asleep (waiting a child to terminate or
executing pause API) the kernel will awaken the process by
scheduling it.
• When the recipient process runs, the kernel will check the process
U-area that contains an array of signal handling specifications.
• The kernel will consult the array to find out how the process will
react to the pending signal.
• If the array entry contains a zero value, the process will accept the
default action of the signal
• If the array entry contains a one value, the process will ignore the
signal.
• Finally, if the array entry contains any other value, it is used as the
function pointer for a used defined signal hander routine.
signal -API
• All UNIX systems and ANSI – C support the
signal API, which can be used to define the
per-signal handing method.
• The function prototype of the signal is:
#include <signal.h>
void (*signal (int signal_num, void (*handler)(int))(int);
• signal_num is the signal identifier like SIGINT or SIGTERM
defined in the <signal.h>.
• handler is the function pointer of a user defined signal
handler function.
catch the SIGTERM, ignores the SIGINT, and accepts the default
action of the SIGSEGV signal.
#include <iostream.h>
#include <signal.h>
void catch_sig(int sig_num)
{
signal(sig_sum, catch_sig);
cout << “catch_sig:” << sig_num << endl;
}
int main()
{
signal(SIGTERM, catch_sig);
signal(SIGINT, SIG_IGN);
signal(SIGSEGV, SIG_DFL);
pause(); // wait for signal interruption
}
The SIG_IGN and SIG_DFL are manifest constants defined in <signal.h>
#define SIG_DFL void (*)(int)0 // Default action
#define SIG_IGN void (*)(int)1 // Ignore the signal
sigset API
• UNIX system V.3 and V.4 support the sigset
API, which has the same prototype and similar
use a signal.
#include <signal.h>
void (*sigset (int signal_num, void (*handler)(int))(int);
Signal Mask
• Each process in UNIX or POSIX.1 system has signal
mask that defines which signals are blocked when
generated to a process.
• A process initially inherits the parent’s signal mask
when it is created, but any pending signals for the
parent process are not passed on.
• A process may query or set its signal mask via the
sigprocmask API:
#include <signal.h>
int sigprocmask(int cmd, const sigset_t *new_mask, sigset_t *old_mask);
• If the actual argument to new_mask argument is a NULL pointer, the cmd
argument will be ignored, and the current process signal mask will not be
altered.
• The return value of sigprocmask call is zero if it succeeds or -1 if it fails.
Signal Mask
The segset_t is a data type defined in <signal.h>. It contains a collection of bit flags, with each
bit flag representing one signal defined in the system.
• The BSD UNIX and POSIX.1 define a set of API
known as sigsetops functions
#include <signal.h>
int sigemptyset(sigset_t *sigmask);
int sigaddset(sigset_t *sigmask, const int signal_num);
int sigdelset(sigset_t *sigmask, const int signal_num);
int sigfillset(sigset_t sigmask);
int sigismember(const sigset_t *sigmask, const int signal_num);
• checks whether the SIGINT signal is present in a process signal
mask and adds it to the mask if it is not there. Then clears the
SIGSEGV signal from the process signal mask.
#include <stdio.h> #include <signal.h> int main()
{
sigset_t sigmask;
sigemptyset(&sigmask); /*initialize set*/
if (sigprocmask(0, 0, &mask) == -1) /*get current signal mask*/
{
perror(“sigprocmask”);
exit(1);
}
else
sigaddset(&sigmask, SIGINT); /*set SIGINT flag*/
sigdelset(&sigmask, SIGSEGV); /*clear SIGSEGV flag*/
if (sigprocmask(SIG_SETMASK, &sigmask, 0) == -1)
perror(“sigprocmask”); /*set a new signal mask*/
}