Signals are software interrupts that give us a way to handle asynchronous events.Stuck with your System Programming Assignment. Get 24/7 help from tutors with Phd in the subject. Email us at support@helpwithassignment.com
Reach us at http://www.HelpWithAssignment.com
2. SIGNALS
• Signals are software interrupts that give us a way to
handle asynchronous events
• Signals can be received by or sent to any existing process
• It provides a flexible way to stop execution of a process
or to tell it that something has happened, requiring
attention
• All signals are integers which are #define’d as
constants starting with the characters SIG inside the
header signal.h
• All signals received by a process have a default action
associated with them, which are: ignore, terminate with
core or stop
3. SIGNALS
• Signals are of different types:
• Kill process (SIGTERM, SIGABRT, SIGKILL,
SIGQUIT, SIGSEGV)
• Suspend process (SIGSTOP, SIGSTP)
• Resume process (SIGCNT)
• Notify ^C (SIGINT)
• Memory violation (SIGSEGV)
• Child process termination (SIGCHLD)
• User defined events (SIGUSR1, SIGUSR2)
5. SIGNALS
• Signals can occur due to one of the following events:
• Certain terminal keys (ex. ^C)
• Hardware exception (ex: divide by zero)
• Software events
• The kill() system call
• A process has one of three options on how to react to a
signal arriving
• Ignore it (except for SIGKILL and SIGSTOP)
• Perform the default action
• Catch the signal using a user defined function
6. SIGNAL HANDLING
#include <signal.h>
void (*signal(int signo,
void(*func)(int)))(int)
return a pointer to previous
signal handler, SIG_ERR on error
- or -
typedef void sigfunc(int)
sigfunc *signal(int, sigfunc *)
7. SIGNAL HANDLING
• If we register a signal handler, when that signal is
received execution is temporarily suspended until
the signal handler returns
• signal() lets us register signal handlers for
specific signals
• func may be one of: SIG_IGN, SIG_DFL, or a
function that takes an integer and returns nothing
• SIGKILL and SIGSTOP should not be trapped
and many system do not let you trap them
8. SIGNAL HANDLING
• On most system, when a user defined signal handler
executes, the signal handling disposition is reset and
has to be set again
• Most slow system calls on System V implementation
trap signals by returning an error value of -1 and
setting errno to EINTR
• One has to be careful about system calls which are
interrupted by a signal and the action taken inside
the signal handler. Only re-entrant functions can be
used in the signal handler but the errno variable
might still be corrupted
9. REENTRANT FUNCTIONS
• When a signal is being handled by a process the
normal sequence of instruction being executed is
temporarily interrupted by the signal handler
• If the signal handler returns then the normal
instruction sequence that the process was executing
continues (similar to hardware interrupt)
• In the signal handler we can’t tell where the process
was executing (say, if it was malloc’ing)
• To conserve the state of the system, signal handlers
should only use re-entrant system calls
10. REENTRANT FUNCTIONS
• Non re-entrant functions either:
• Use static data structures
• Call malloc or free
• Are part of the standard I/O library (printf is
not guaranteed to produce expected results)
• There is only one errno variable per thread, and
function calls in the signal handler might modify its
value
11. TERMINOLOGY
• A signal is generated for a process when an event
causes that signal to occur
• A signal is delivered to a process when the action for
a signal is taken
• During the time between signal generation and
delivery the signal is pending
• A process has the option of blocking delivery of a
signal. If the action is either default or caught,
signal remain pending until the process unblocks or
changes the action to ignore the signal
12. TERMINOLOGY
• The system determines what to do with a blocked signal
when the signal is delivered, not generated
• This allows the process to change the action for the
signal before it’s delivered
• signpending function can be called to determine
which signal are blocked and pending
• If blocked signal is generated more than once, most
systems deliver the signal once (not queued)
• If more than one signal is ready to be delivered, signal
related to the current state of the process is delivered
before others (eg SIGSEGV)
13. SIGNAL HANDLING
static void sig_usr(int);
int main(void)
{
if (signal(SIGUSR1, sig_usr) == SIG_ERR)
fprintf(stderr, “Can’t catch SIGUSR1”);
for ( ; ; )
pause();
}
static void sig_usr(int signo)
{
if (signo == SIGUSR1)
printf(“Received SIGUSR1n”);
else
fprintf(stderr, “Received signal %dn”, signo);
}
14. SENDING SIGNALS
• From the command prompt one can send a signal to
a process using:
kill -<SIGNAL> <pid>
• Default signal is SIGTERM
• kill() is used to send a signal to a specific
process while raise() sends a signal to itself
• A superuser can send a signal to any process
• A process can send signals only to process with the
same real or effective UID
15. SIGNAL FUNCTIONS
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);
return 0 if OK, -1 on error
unsigned int alarm(unsigned int seconds);
return 0 or number of seconds until
previously set alarm
int pause(void)
return -1 with errno=EINTR
16. SENDING SIGNALS
• Four different condition for the pid argument:
• pid > 0, signal sent to process with ID pid
• pid == 0, signal sent to all processes whose
process group equals the process group ID of the
sender
• pid < 0, signal sent to all processes whose
group ID equals the absolute value of pid
• pid == 1, signal sent to all processes on the
system
17. SIGNAL FUNCTIONS
• A process needs permission to send a signal to
another process
• pause() blocks the running process until a signal
handler returns
• Can be used as a sort of Inter Process
Communication
• alarm() allows us to set a timer that will expire
at a specified time in the future. When timer expires
the SIGALRM signal is generated. Default action is
to terminate the process
18. SIGNAL MASKS
• Signal sent represents a set of signals
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
Return 0 if OK, 1 on error
int sigismember(const sigset_t *set,
int signo)
Return 1 if true/error, 0 if false
19. SIGNAL MASKS
• Signals can be blocked so that critical sections are
not interrupted
• Every process maintains a signal mask telling which
signals are blocked
• Signal masks are stored in the data type
sigset_t
• This is guaranteed to be able to hold all signals
supported by the system
• sigemptyset() or sigfillset() must be
called at least once
20. MASKING SIGNALS
#include <signal.h>
int sigprocmask(int how,
const sigset_t *set,
sigset_t *oset);
Returns 0 if OK, -1 on error
How value:
SIG_BLOCK (union)
SIG_UNBLOCK (intersection)
SIG_SETMASK (equality)
21. SIGNAL MASKS
• If oset is NULL, the old signal mask is returned in it
• set defines the signals we want to block or unblock
• If there are any pending signals and we unblock it with
sigprocmask(), one these signals is received
before sigprocmask() returns
• Blocking signal make sure critical sections are executed
atomically
• We could call pause() if we want to wait for a signal
after unblocking the signal mask, however this could
make the process wait forever
22. SIGNAL MASKS
• Tells us what signals that are blocked frim delivery
are currently pending
• The list of signals is returned inside set
• sigismember() can be used to find out what
signals are present in set
#include <signal.h>
int sigpending(sigset_t *set);
returns 0 if OK, -1 on error
25. SIGNAL MASKS
• Allows us to examine and/or modify the action
associated with a particular signal
• Supersedes the signal function from earlier systems
• If the act pointer is not NULL, we are modifying the
action
• If the oact pointer is not NULL the system returns the
previous action for the signal
• When changing the action of a signal the
sa_handler field contains the address of a signal-
catching function and sa_mask specifies a signal set
that are added to the mask before function is called.
26. SIGSUSPEND
1. Sets the signal mask to sigmask
2. Calls the pause function
3. If pause() returns, signal mask is set back to its
original value
• All above steps are guaranteed to be performed
atomically and thus get no lost signals
#include <signal.h>
int sigsuspend(const sigset_t *sigmask);
returns -1 with errno set to EINT
28. SLEEP
• Function causes the calling process to be suspended
until:
• Amount of wall clock time has elapsed
• A signal is caught by the process and the signal
handler returns
• In the latter case, the number of unslept seconds is
returned
#include <unistd.h>
unsigned int sleep(unsigned int secs);
29. SIGSUSPEND
1. Sets the signal mask to sigmask
2. Calls the pause function
3. If pause() returns, signal mask is set back to its
original value
• All above steps are guaranteed to be performed
atomically and thus get no lost signals
#include <signal.h>
int sigsuspend(const sigset_t *sigmask);
returns -1 with errno set to EINT