![if !IE]> <![endif]>
Posix way to establish the disposition of a signal is to call the sigaction function. However this is complicated at one argument to the function is a structure that we must allocate and fill in. An easier way to set the disposition for a signal is to call the signal function. The first argument is the signal name and the second arguments is the pointer to a function or one of the constants SIG_IGN or SIG_DFE.
Normally, the define our own signal function that just calls the Posix sigaction.
line 2-3 call to the function when a signal occurs. It has pointer to signal handling function as the second argument
Line 6: Set Handler : The sa_handler member of the sigaction structure is set to the func argument
Line 7: Set signal mask to handler: POSIX allows us to specify a set of signals that will be blocked when our signal handler is called. Any signal that is blocked cannot be delivered to the process. We set the sa_mask member to the empty set, which means that no additional signals are blocked while our signal handler is running Posix guarantees that he signal being caught is always blocked while its handler is executing
Line 8 – 17: An optional flag SA_RESTART, if it is set, a system call interrupted by this signal will automatically restarted by the kernal.
Line 18 – 20: The function sigaction is called and then return the old action for the signal as the return value of the signal function.
Posix Signal semantics:
1. Once a signal handler is installed, it remains installed.
2. While a signal handler is executing, the signal being delivered is blocked. Further any additional signals that were specified in the sa_mask signal set passed to sigaction when the handler was installed are also blocked . When the sa_mask is set to empty set, no additional signals are blocked other than the signal being caught.
3. If a signal is being generated more times while it is blocked, it is normally delivered only one time
after the signal is unblocked.
4. It is possible to selectively block and unblock a set of signals using the sigprocmask function. This protects a critical region of code by providing certain signals from being caught while the region of code is executing.
Handling SIGCHLD signals:
A zombie is a process that ha terminated whose parent is still running, but has not yet waited for its child processes. This will result in the resources occupied by the terminated process not returned to the system. If there are a lot of zombies in the system the system resources may run out.
The purpose of the zombie state is to maintain information about the child for the parent to fetch at some time later. The information are : the process ID of the child, its termination status and information on the resource utilization of the child (CPU time, memory etc). If a process terminates, and the process has children in the zombie state. The parent process ID of all the zombie children is set to 1 (the init process), which will inherit the children and clean them up.
The zombie are not desired to be left. They take up space in the kernal and eventually we can run out of process. Whenever we fork children, we must wait, for them to prevent them from becoming zombies.
When a child terminates, the kernal generates a SGICHLD signal for the parent. The parent process should catch the signal and take an appropriate action. If the signal is not caught, the default action of this signal is to be ignored.
To handle a zombie, the parent process establishes a signal handler to catch SIGCHLD signal. The handler then invokes the function wait() or waitpid () to wait for a terminated child process and free all the system resources occupied by the process.
To do this we establish a signal handler called SIGCHLD and within the handler, we call wait. The signal handler is established by adding function call
Interrupted System Calls:
There are certain system calls in the Client Server communication that are blocked while waiting for input. It can be seen that in the case of echo client server programme, in the server programme, the function accept () is blocked while waiting for the call from a client. This condition is called slow system call . This can also occur in case of functional calls such as read(), write (), select(), open () etc. Under such condition, when a SIGCHLD is delivered on termination of a process, the sig_chld function executes (the signal handler for SIGCHLD), wait function fetches the child‘s pid and termination status. The signal handler then returns.
But as the signal was caught by the parent while parent was blocked in a slow system call (accept), the kernal causes the accept to return an error of EINTR (interrupted system call). The parent does not handle this error, so it aborts. This is a potential problem which all slow system call (read, write, open, select etc) face whenever they catch any signal. This is undesirable.
In case of Solaris 2.5, the signal function provided in the C library does not cause an interrupted system call to be automatically restarted by the kernal. That is SA_RESTART flag that is set in signal function is not set by the signal function in the system library. Where as some other systems like, 4.4 BSD using the library version of signal function, the kernal restarts the interrupted system call and accept does not return an error.
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.