Presentation is loading. Please wait.

Presentation is loading. Please wait.

Signals What is a Signal?

Similar presentations


Presentation on theme: "Signals What is a Signal?"— Presentation transcript:

1 Signals What is a Signal?
A signal is an event generated by the UNIX and Linux systems in response to some condition, upon receipt of which a process may in turn take some action. Signals are software generated interrupts that are sent to a process when a event happens.

2 The Role of Signals Signals serve two main purposes:
To make a process aware that a specific event has occurred. To force a process to execute a signal handler function included in its code.

3 Each signal defined by the system falls into one of five classes:
Hardware conditions Software conditions Input/output notification Process control Resource control

4 Signal Handling func() can have three values: SIG_DFL SIG_IGN
a pointer to a system default function SID_DFL(), which will terminate the process upon receipt of sig. SIG_IGN a pointer to system ignore function SIG_IGN() which will disregard the sig action (UNLESS it is SIGKILL). A function address a user specified function.

5 Each signal has a default action which is one of the following:
The signal is discarded after being received The process is terminated after the signal is received A core file is written, then the process is terminated Stop the process after the signal is received

6 Signals Function void signal(int sig, void (*func) (int) );
Programs can handle signals using the signal library function. Header file: #include <signal.h> Function declaration: void signal(int sig, void (*func) (int) ); Parameters: sig :The signal to be caught or ignored. func :The function to be called when the specified signal is received.

7 Macros are defined in <signal.h>
Signals can be numbered from 0 to 31. SIGHUP 1 /* hangup */ SIGINT 2 /* interrupt */ SIGQUIT 3 /* quit */ SIGILL 4 /* illegal instruction */ SIGABRT 6 /* used by abort */ SIGKILL 9 /* hard kill */ SIGALRM 14 /* alarm clock */  SIGCONT 19 /* continue a stopped process */  SIGCHLD 20 /* to parent on child stop or exit */ 

8 Signals Function Table of Signal Name Description
SIGINT Linux sends a process this signal when the user tries to end it by pressing Ctrl+C. SIGABORT The abort function causes the process to receive this signal. SIGKILL This signal ends a process immediately and cannot be handled. SIGUSR This signal is reserved for application use.

9 The most common way of sending signals to processes is using the keyboard. There are certain key presses that are interpreted by the system as requests to send signals to the process with which we are interacting: Ctrl-C Pressing this key causes the system to send an INT signal (SIGINT) to the running process. By default, this signal causes the process to immediately terminate. Ctrl-Z Pressing this key causes the system to send a TSTP signal (SIGTSTP) to the running process. By default, this signal causes the process to suspend execution. Ctrl-\ Pressing this key causes the system to send a ABRT signal (SIGABRT) to the running process. By default, this signal causes the process to immediately terminate. Note that this redundancy (i.e. Ctrl-\ doing the same as Ctrl-C) gives us some better flexibility. We'll explain that later on.

10 example 1 /* We'll start by writing the function which reacts to the signal which is passed in the parameter sig. This is the function we will arrange to be called when a signal occurs. We print a message, then reset the signal handling for SIGINT (by default generated by pressing CTRL-C) back to the default behavior. Let's call this function ouch. */ #include <signal.h> #include <stdio.h> #include <unistd.h> void ouch(int sig) { printf("OUCH! - I got signal %d\n", sig); (void) signal(SIGINT, SIG_DFL); } /* The main function has to intercept the SIGINT signal generated when we type Ctrl-C . For the rest of the time, it just sits in an infinite loop, printing a message once a second. */ int main() (void) signal(SIGINT, ouch); while(1) { printf("Hello World!\n"); sleep(1);

11 #include <signal.h>
int n;main(int argc, char **argv) { void InterruptHandler(), InitHandler(); n = 0; signal(SIGINT, InterruptHandler); /* signal 2 */ signal(SIGHUP, InitHandler); /* signal 1 */ while (1) { n++; sleep(1); } } void InterruptHandler() { printf("The current value of n is %d\n", n); exit(0); } void InitHandler() { printf("Resetting the value of n to zero\n"); n = 0;

12 % cc -o signal signal.c % ./signal ./signal ^C (interrupt character) The current value of n is 3% ./signal & [1] 20822 % kill -1 %1 Resetting the value of n to zero % kill -2 %1 The current value of n is 19 [1] Done /signal

13 Sending Signals There are two common functions used to send signals.
int kill(int pid, int signal) a system call that send a signal to a process, pid. If pid is greater than zero, the signal is sent to the process whose process ID is equal to pid. If pid is 0, the signal is sent to all processes, except system processes. int raise(int sig) sends the signal sig to the executing program.

14 Sending Signals kill -<signal> <PID>
raise() actually uses kill() to send the signal to the executing program: kill(getpid(), sig); There is also a UNIX command called kill that can be used to send signals from the command line to terminate running process. kill -<signal> <PID> kill -INT 5342 kill (SIGKILL 9 /* hard kill */)

15 alarm() The alarm function call can be used by a process to schedule a SIGALRM signal at some time in the future.

16 example 3 /* In alarm.c, the first function, ding, simulates an alarm clock. */ #include <signal.h> #include <stdio.h> #include <unistd.h> static int alarm_fired = 0; void ding(int sig) { alarm_fired = 1; } /* In main, we tell the child process to wait for five seconds before sending a SIGALRM signal to its parent. */ int main() int pid; printf("alarm application starting\n"); if((pid = fork()) == 0) { sleep(5); kill(getppid(), SIGALRM); exit(0);

17 /* The parent process arranges to catch SIGALRM with a call to signal
and then waits for the inevitable. */ printf("waiting for alarm to go off\n"); (void) signal(SIGALRM, ding); pause(); if (alarm_fired) printf("Ding!\n"); printf("done\n"); exit(0); }

18 Example 5 /* sig_talk.c --- Example of how 2 processes can talk to each other using kill() and signal(). We will fork() 2 process and let the parent send a few signals to it`s child. */ /* cc sig_talk.c -o sig_talk */ #include <stdio.h> #include <signal.h> void sighup(); /* routines child will call upon sigtrap */ void sigint(); void sigquit(); main() { int pid; /* get child process */ if ((pid = fork()) < 0) { perror("fork"); exit(1); } if (pid == 0) { /* child */ signal(SIGHUP,sighup); /* set function calls */ signal(SIGINT,sigint); signal(SIGQUIT, sigquit); for(;;); /* loop for ever */ } else /* parent */

19 { /* pid hold id of child */
printf("\nPARENT: sending SIGHUP\n\n"); kill(pid,SIGHUP); sleep(3); /* pause for 3 secs */ printf("\nPARENT: sending SIGINT\n\n"); kill(pid,SIGINT); printf("\nPARENT: sending SIGQUIT\n\n"); kill(pid,SIGQUIT); sleep(3); }} void sighup() { signal(SIGHUP,sighup); /* reset signal */ printf("CHILD: I have received a SIGHUP\n"); } void sigint() signal(SIGINT,sigint); /* reset signal */ printf("CHILD: I have received a SIGINT\n"); void sigquit() printf("My DADDY has Killed me!!!\n"); exit(0);

20 sigaction. X/Open specification recommends a newer programming interface for signals that is more robust

21 sigaction structure If the argument act is not a null pointer, it points to a structure specifying the action to be associated with the specified signal The sigaction structure, used to define the actions to be taken on receipt of the signal specified by sig, is defined in signal.h and has at least the following members: If the argument act is a null pointer, signal handling is unchanged

22 sigaction structure The sa_handler field of the sigaction structure identifies the action to be associated with the specified signal. If the sa_handler field specifies a signal-catching function, the sa_mask field identifies a set of signals that will be added to the process' signal mask before the signal-catching function is invoked. The SIGKILL and SIGSTOP signals will not be added to the signal mask using this mechanism; this restriction will be enforced by the system without causing an error to be indicated. The sa_flags field can be used to modify the behaviour of the specified signal.

23 #include <signal.h>
#include <stdio.h> #include <unistd.h> void ouch(int sig) { printf("OUCH! - I got signal %d\n", sig); } int main() struct sigaction act; act.sa_handler = ouch; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGINT, &act, 0); while(1) { printf("Hello World!\n"); sleep(1);

24 Signal Sets The header file signal.h defines the type sigset_t and functions used to manipulate sets of signals.

25 Signal Sets #include <signal.h>
int sigaddset(sigset_t *set, int signo);   DESCRIPTION The sigaddset() function adds the individual signal specified by the signo to the signal set pointed to by set

26 Signal Sets #include <signal.h> int sigemptyset(sigset_t *set);
DESCRIPTION The sigemptyset() function initialises the signal set pointed to by set, such that all signals defined in this document are excluded.

27 Signal Sets #include <signal.h> int sigfillset(sigset_t *set);
DESCRIPTION The sigfillset() function initialises the signal set pointed to by set, such that all signals defined in this document are included

28 Signal Sets include <signal.h>
int sigdelset(sigset_t *set, int signo);  DESCRIPTION The sigdelset() function deletes the individual signal specified by signo from the signal set pointed to by set.

29 sigismember The function sigismember determines whether the given signal is amember of a signal set.

30 example 6 /* signaldef.c This program binds the signal SIGCLD to a handler sig_cld, then it loops ten times. In each iteration it creates a child and pauses. The handler is called when the child terminates. It collects and prints out information about the defunct chil`d. Notice that it is implemented as a loop because multiple SIGCLD signals may result in a single signal event. */ #include <signal.h> #include <wait.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> typedef void Sigfunc(int); /* Sigfunc is type of function with one int arg, and void return */ Sigfunc * signal(int signo, Sigfunc *func) { struct sigaction act, oact; act.sa_handler = func; sigemptyset(&act.sa_mask); act.sa_flags = 0; #ifdef SA_RESTART if (signo != SIGALRM) act.sa_flags |= SA_RESTART; #endif if (sigaction(signo, &act, &oact) < 0) return (SIG_ERR); return (oact.sa_handler); }

31 static void sig_cld();
int main() { pid_t pid; int i; if (signal(SIGCLD, sig_cld) == SIG_ERR) { printf("signal error\n"); exit(1);} for (i=0; i < 10; i++){ if ( (pid = fork()) < 0) { printf("fork error\n"); exit(1); } else if (pid == 0) { /* child */ sleep(2); exit(0); pause(); /* parent */ static void sig_cld() int status; printf("SIGCLD received, "); while ( (pid = waitpid(-1, &status, WNOHANG)) > 0){ printf("child pid = %d terminated\n", pid); printf ("Returning from handler\n"); return;


Download ppt "Signals What is a Signal?"

Similar presentations


Ads by Google