22
1 Reference Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel” (OReilly) in the reference material section

1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

Embed Size (px)

Citation preview

Page 1: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

1

ReferenceReference

• “Introduction To Unix Signals Programming” in the reference material section

• Man page – sigprocmask, alarm

• “Understanding the Linux Kernel” (OReilly) in the reference material section

Page 2: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

2

Signal: An IPC Mechanism Signal: An IPC Mechanism

• With pipes we communicated data

• With signal, we can communicate control command

• The only information is: The number identifying the signal

• Interrupts a process and forces it to handle the event immediately

• kill –l can be used to view all the signals supported by your system

Page 3: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

3

Sending signals to processSending signals to process• From keyboard

Ctrl-C, Ctrl-Z etc• From the command line

kill -<signal> <PID> fg :On most shells, using the 'fg' command will resume execution of the process

(that was suspended with Ctrl-Z), by sending it a CONT signal.

• Using the kill() system call• Also used by the kill and fg command#include <signal.h> /* signal name macros, and the kill() prototype */

/* first, find my own process ID */ pid_t my_pid = getpid(); /* now that i got my PID, send myself the STOP signal. */ kill(my_pid, SIGSTOP);

Page 4: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

4

Actions Performed upon Actions Performed upon Receiving a SignalReceiving a Signal

• There are three ways in which a process can respond to a signal:

1. Explicitly ignore the signal.

2. Execute the default action associated with the signal.

3. Catch the signal by invoking a corresponding signal-handler function.

Page 5: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

5

Signal HandlerSignal Handler• Corresponding to each signal is a signal handler• Called when a process receives a signal• The function is called “asynchronously”• When the signal handler returns the process

continues, as if it was never interrupted• Signal are different from interrupts as:

Interrupts are sent to OS by H/W Signals are sent to a process by the OS, or by other

processes Note that signals have nothing to do with software

interrupts, which are still sent by the hardware (the CPU itself, in this case).

Page 6: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

6

Catching a SignalCatching a Signal

Page 7: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

7

The The signal()signal() System Call System Call

• Used to set signal handler for a signal type

Page 8: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

8

ExampleExamplevoid main(){ /* set the INT (Ctrl-C) signal handler to 'catch_int' */ signal(SIGINT, catch_int);

/* now, lets get into an infinite loop of doing nothing. */ for ( ;; )

pause();} /* first, here is the signal handler */ void catch_int(int sig_num) { /* re-set the signal handler again to catch_int, for next time */

signal(SIGINT, catch_int); /* and print the message */ printf("Don't do that");

}

Page 9: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

9

Signal HandlersSignal Handlers

• Pre-defined Signal Handlers

• SIG_IGN: Causes the process to ignore the specified signal. To ignore Ctrl-C completely

• signal(SIGINT, SIG_IGN);

• SIG_DFL: Causes the system to set the default signal

handler for the given signal• signal(SIGTSTP, SIG_DFL);

Page 10: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

10

Race conditionsRace conditions

• The occurrence of a second signal while the signal handler function executes

• Might be of a different type then the one being handled

• Or even of the same type

Page 11: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

11

sigprocmask() sigprocmask() • Allows us to specify a set of signals to block• Returns the list of signals that were previously

blocked• int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

Page 12: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

12

sigprocmask()sigprocmask()• int how

SIG_BLOCK • Add set to the set of currently blocked signals

SIG_UNBLOCK The signals in set are removed from the current set of blocked

signals. SIG_SETMASK

• The set of blocked signals is set to the argument set. • const sigset_t *set

The set of signals to be blocked, or to be added to the current mask, or removed from the current mask (depending on the 'how' parameter).

• sigset_t *oldset If this parameter is not NULL, then it'll contain the previous mask. Can be used later restore back the situation, before sigprocmask() was

called.

Page 13: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

13

Signal functionsSignal functions• Define a new mask set

sigset_t mask_set; • Clear the set (i.e. make it contain no signal numbers)

sigemptyset(&mask_set);• Add a signal

sigaddset(&mask_set, SIGTSTP); • Remove the TSTP signal from the set

sigdelset(&mask_set, SIGTSTP);• Check if the TSTP signal is defined in our set

if (sigismember(&mask_set, SIGINT) printf("signal INT is in our set\n");

else printf("signal INT is not in our set - how strange...\n");

• Make the set contain ALL signals available on the system sigfillset(&mask_set)

Page 14: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

14

Count_CTRL_C.c

Page 15: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

15

#include <stdio.h> /* standard I/O functions */#include <unistd.h> /* standard unix functions, like getpid()*/#include <signal.h> /* signal name macros, and the signal()

prototype *//* first, define the Ctrl-C counter, initialize it with zero. */int ctrl_c_count = 0;#define CTRL_C_THRESHOLD 5int main(int argc, char* argv[]){ /* set the Ctrl-C and Ctrl-Z signal handlers */ signal(SIGINT, catch_int); signal(SIGTSTP, catch_suspend);

/* enter an infinite loop of waiting for signals */ for ( ;; )

pause();

return 0;}

Page 16: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

16

/* the Ctrl-C signal handler */void catch_int(int sig_num){ sigset_t mask_set; /* used to set a signal masking set. */ sigset_t old_set; /* used to store the old mask set. */

/* mask any further signals while we're inside the handler. */ sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); /* increase count, and check if threshold was reached */ ctrl_c_count++; if (ctrl_c_count >= CTRL_C_THRESHOLD)

{char answer[30];/* prompt the user to tell us if to really exit or not */printf("\nRealy Exit? [y/N]: ");fflush(stdout);

Page 17: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

17

gets(answer);if (answer[0] == 'y' || answer[0] == 'Y') {

printf("\nExiting...\n"); fflush(stdout); exit(0);

}else {

printf("\nContinuing\n");fflush(stdout);/* reset Ctrl-C counter */ctrl_c_count = 0;

} } /* restore the old signal mask */ sigprocmask(SIG_SETMASK, &old_set, NULL);}

Page 18: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

18

/* the Ctrl-Z signal handler */void catch_suspend(int sig_num){ sigset_t mask_set; /* used to set a signal masking set. */ sigset_t old_set; /* used to store the old mask set. */

/* mask any further signals while we're inside the handler. */ sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set);

/* print the current Ctrl-C counter */ printf("\n\nSo far, '%d' Ctrl-C presses were counted\n\n", ctrl_c_count); fflush(stdout);

/* restore the old signal mask */ sigprocmask(SIG_SETMASK, &old_set, NULL);}

Page 19: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

19

Implementing Timers Using Implementing Timers Using SignalsSignals

• alarm : set a process alarm clock• #include <unistd.h> • unsigned alarm(unsigned sec); • Sends the signal SIGALRM to the calling

process after the sec number of seconds have elapsed

• If sec is 0, any previously made alarm request is canceled.

Page 20: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

20

• use-alarms_c.c

Page 21: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

21

#include <signal.h> /* signal name macros, and the signal() prototype */char user[40]; /* buffer to read user name from the user */int main(int argc, char* argv[]){ /* set a signal handler for ALRM signals */ signal(SIGALRM, catch_alarm); /* prompt the user for input */ printf("Username: "); fflush(stdout); /* start a 30 seconds alarm */ alarm(30); /* wait for user input */ gets(user); /* remove the timer, now that we've got the user's input */ alarm(0); printf("User name: '%s'\n", user);}`

Page 22: 1Reference “Introduction To Unix Signals Programming” in the reference material section Man page – sigprocmask, alarm “Understanding the Linux Kernel”

22

/* define an alarm signal handler. */void catch_alarm(int sig_num){ printf("Operation timed out. Exiting...\n\n"); exit(0);}