
Source: Robbins and Robbins, UNIX Systems Programming, Prentice Hall, 2003. Chapter 8 Signals. 8.1 Basic Signal Concepts. Basic Signal Concepts. A signal is a software notification to a process of an event A signal is generated when the event that causes the signal occurs
Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.
NBR
DESCRIPTION
DEFAULT ACTION
SIGABRT
6
Process abort (sent by assert)
Implementation dependent
SIGALRM
14
alarm clock
Abnormal termination
SIGCONT
25
Execution continued if stopped
Continue
SIGFPE
8
Arithmetic error (i.e., divide by zero)
Implementation dependent
SIGINT
2
Interactive attention signal (Ctrl-C)
Abnormal termination
SIGKILL
9
Termination (cannot be caught or ignored)
Abnormal termination
SIGQUIT
3
Interactive termination; core dump
Implementation dependent
SIGSEGV
11
Segmentation fault
Abnormal termination
SIGSTOP
23
Execution stop (cannot be caught or ignored)
Stop
SIGTERM
15
Termination
Abnormal termination
SIGUSR1
16
User-defined signal 1
Abnormal termination
SIGUSR2
17
User-defined signal 2
Abnormal termination
Certain POSIX Signals#include <stdio.h>
#include <limits.h>
// #define NDEBUG
#include <assert.h>
#define MIN_SCORES 2
#define MAX_SCORES 5
// ******************************************
int main(void)
{
float average;
int i;
int score;
float sum = 0;
int nbrOfScores;
int scoreTable[MAX_SCORES];
printf("Enter the number of scores (%d - %d: “, MIN_SCORES,
MAX_SCORES);
scanf("%d", &nbrOfScores);
printf(“\n");
assert( (nbrOfScores >= MIN_SCORES) && (nbrOfScores <= MAX_SCORES) );
(More on next slide)
for (i = 0; i < nbrOfScores; i++)
{
printf("Enter score #%d (x >= 0): ", i + 1);
scanf("%d", &score);
assert( (score >= 0) && (score < INT_MAX) );
assert( (i >= 0) && ( i < nbrOfScores) );
scoreTable[i] = score;
sum = sum + score;
} // End for
printf("\nList of Scores: ");
for (i = 0; i < nbrOfScores; i++)
printf(" %d ", scoreTable[i]);
assert(sum >= 0);
average = sum / nbrOfScores;
assert(average >= 0);
printf("\n\nAverage score: %.2f\n", average);
return 0;
} // End main
uxb3% a.out
Enter the number of scores (2 - 5): 3
Enter score #1 (x >= 0): 89
Enter score #2 (x >= 0): 72
Enter score #3 (x >= 0): 84
List of Scores: 89 72 84
Average score: 81.67
uxb3%
uxb3% a.out
Enter the number of scores (2 - 5): 1
assert-demo.c:25: failed assertion `(nbrOfScores >= MIN_SCORES) && (nbrOfScores <= MAX_SCORES)'
Abort
uxb3%
uxb3% a.out
Enter the number of scores (2 - 5): 4
Enter score #1 (x >= 0): -1
assert-demo.c:32: failed assertion `(score >= 0) && (score < INT_MAX)'
Abort
uxb3%
uxb2% a.out
Enter the number of scores (2 - 5): 10
Enter score #1 (x >= 0): -5
Enter score #2 (x >= 0): -10
Enter score #3 (x >= 0): -15
Enter score #4 (x >= 0): -20
Enter score #5 (x >= 0): -25
Enter score #6 (x >= 0): 5
Enter score #7 (x >= 0): 10
Enter score #8 (x >= 0): 15
Enter score #9 (x >= 0): 20
Enter score #10 (x >= 0): 25
Enter score #11 (x >= 0): 34
List of Scores: -5 -10 -15 -20 -25 5 10 15 1117650944 34 10 0 0 0 -4195632
Average score: 5.27
uxb2%
Notice the amount of incorrect input and output that is not flagged nor pointed out as wrong
#include <stdio.h>
#include <signal.h>
// *******************************
int main(void)
{
int status;
sigset_t mySet;
status = sigemptyset(&mySet);
if (status == -1)
perror("Failed to empty signal set");
status = sigaddset(&mySet, SIGINT);
if (status == -1)
perror("Failed to add SIGINT signal to signal set");
status = sigaddset(&mySet, SIGQUIT);
if (status == -1)
perror("Failed to add SIGQUIT signal to signal set");
if (sigismember(&mySet, SIGINT))
fprintf(stderr, "The set contains the SIGINT signal\n");
else
fprintf(stderr, "The set does not contain the SIGINT signal\n");
return 0;
} // End main
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int i;
sigset_t intMask;
int repeatFactor = 10000;
double y = 0.0;
int status;
status = sigemptyset(&intMask);
if (status == -1)
{
perror("Failed to initialize the signal set");
return 1;
} // End if
status = sigaddset(&intMask, SIGINT);
if (status == -1)
{
perror("Failed to add SIGINT to the signal set");
return 1;
} // End if
(More on next slide)
for ( ; ; ) // Infinite loop
{
status = sigprocmask(SIG_BLOCK, &intMask, NULL);
if (status == -1)
break;
fprintf(stderr, "Blocked the SIGINT signal\n");
for (i = 0; i < repeatFactor; i++)
y = y + sin((double)i);
fprintf(stderr, "[SIGINT Blocked] Calculation ran safe from interruption\n");
status = sigprocmask(SIG_UNBLOCK, &intMask, NULL);
if (status == -1)
break;
fprintf(stderr, "Unblocked the SIGINT signal\n");
for (i = 0; i < repeatFactor; i++)
y = y + sin((double)i);
fprintf(stderr,
"[SIGINT Unblocked] Calculation ran, but vulnerable to interruption\n");
} // End for
perror("Failed to block or unblock signal mask");
return 1;
} // End main
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
sigset_t mask, oldMask;
int status;
status = sigfillset(&mask);
if (status == -1)
{
perror("Failed to fill the signal set");
return 1;
} // End if
(More on next slide)
status = sigprocmask(SIG_SETMASK, &mask, &oldMask);
if (status == -1)
{
perror("Failed to block signals using the signal mask");
return 1;
} // End if
else
fprintf(stderr,
"\nParent set mask to block all signals before creating child\n\n");
pid = fork();
if (pid == -1)
{
perror("Failed to create child process");
return 1;
} // End if
if (pid == 0) // Child process
{
fprintf(stderr,
"Child process is running with inherited signal mask from parent\n\n");
execl("/bin/ls", "ls", "-l", NULL);
perror("exec function failed in child process");
return 1;
} // End if
(More on next slide)
else // Parent process
{
fprintf(stderr, "Parent created child process\n\n");
status = sigprocmask(SIG_SETMASK, &oldMask, NULL);
if (status == -1)
{
perror("Parent failed to restore signal mask");
return 1;
} // End if
else
fprintf(stderr,
"Parent reset signal mask to original values after creating child\n\n");
fprintf(stderr, "Parent waiting for child process to terminate...\n\n");
status = wait(NULL);
if (status == -1)
{
perror("Parent failed to wait for child");
return 1;
} // End if
fprintf(stderr, "\nParent has detected termination of child process\n");
} // End else
return 0;
} // End main
uxb2% a.out
Parent set mask to block all signals before creating child
Parent created child process
Parent reset signal mask to original values after creating child
Parent waiting for child process to terminate...
Child process is running with inherited signal mask from parent
total 6
drwx------ 12 jjt107 faculty 1024 Jun 21 10:35 Files
drwx------ 2 jjt107 faculty 1024 Jul 24 08:43 Mail
drwx--x--x 19 jjt107 faculty 1024 Jul 3 12:32 http
Parent has detected termination of child process
uxb2%
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#define MAX_PRESSES 5
static int pressCount = 0;
void catchCtrlC(int signalNbr);
int main(void)
{
// See next slide
}
// This function is the signal handler
void catchCtrlC(int signalNbr)
{
char message[] = "Ctrl-C was pressed\n";
write(STDERR_FILENO, message, strlen(message) );
pressCount++; // Global variable
} // End catchCtrlC
The catchCtrlC() function is defined here as
a signal handler for the SIGINT signal generated
by Ctrl-C.
The write() function is used instead offprintf() because POSIX guarantees thatit is async-signal safe, meaning that thefunction can be called safely from within
a signal handler.
(More on next slide)
Sample Output
// *****************************************
int main(void)
{
struct sigaction action;
int status;
action.sa_handler = catchCtrlC;
action.sa_flags = 0;
status = sigemptyset(&action.sa_mask);
if (status == -1)
{
perror("Failed to initialize signal set");
exit(1);
} // End if
status = sigaction(SIGINT, &action, NULL);
if (status == -1)
{
perror("Failed to set signal handler for SIGINT");
exit(1);
} // End if
while (pressCount < MAX_PRESSES); // Loop has no statements
return 0;
} // End main
uxb3% a.out
Ctrl-C was pressed
Ctrl-C was pressed
Ctrl-C was pressed
Ctrl-C was pressed
Ctrl-C was pressed
uxb3%
Sample Output
int main(void)
{
struct sigaction action;
int status;
action.sa_handler = catchCtrlC;
action.sa_flags = 0;
status = sigemptyset(&action.sa_mask);
if (status == -1)
{
perror("Failed to initialize signal set");
exit(1);
} // End if
status = sigaction(SIGINT, &action, NULL);
if (status == -1)
{
perror("Failed to set signal handler for SIGINT");
exit(1);
} // End if
fprintf(stderr, "Program paused . . .\n");
pause();
return 0;
} // End main
uxb3% a.out
Program paused . . .
Ctrl-C was pressed
uxb3%
Command Shell A
#include <stdio.h>
#include <signal.h>
static sig_atomic_t sigReceived = 0;
int main(void)
{
int status;
sigset_t maskAll;
sigset_t maskMost;
sigset_t maskOld;
int sigNbr = SIGUSR1;
fprintf(stderr, "PID: %d\n", getpid());
sigfillset(&maskAll);
sigfillset(&maskMost);
sigdelset(&maskMost, sigNbr);
sigprocmask(SIG_SETMASK, &maskAll, &maskOld);
if (sigReceived == 0)
sigsuspend(&maskMost);
sigprocmask(SIG_SETMASK, &maskOld, NULL);
return 0;
} // End main
uxb3% a.out
PID 2624
uxb3% a.out
PID 3548
uxb3%
Command Shell B
uxb3% kill –INT 2624
uxb3%
uxb3% kill –USR1 2624
uxb3% kill –9 3548
uxb3%
#include <signal.h>
#include <stdio.h>
int main(void)
{
int signalCount = 0;
int signalNbr;
sigset_t signalSet;
int status;
status = sigfillset(&signalSet);
if (status == -1)
perror("Failed to fill the signal set");
status = sigprocmask(SIG_BLOCK, &signalSet, NULL);
if (status == -1)
perror("Failed to block signals");
fprintf(stderr, "This process has ID %ld\n", (long)getpid());
(More on next slide)
for ( ; ; ) // Infinite loop
{
signalNbr = sigwait(&signalSet); // Default version
if (signalNbr == -1)
{
perror("Failed to wait using sigwait");
return 1;
} // End if
else
fprintf(stderr, "Unblocked signal #%d\n", signalNbr);
/*
status = sigwait(&signalSet, &signalNbr); // POSIX version
if (status == -1)
{
perror("Failed to wait using sigwait");
return 1;
} // End if
*/
signalCount++;
fprintf(stderr, "Number of signals so far: %d\n", signalCount);
} // End for
} // End main
Command Shell A
Command Shell B
uxb3% a.out
This process has ID 15469
Unblocked signal #16
Number of signals so far: 1
Unblocked signal #17
Number of signals so far: 2
Unblocked signal #2
Number of signals so far: 3
Unblocked signal #14
Number of signals so far: 4
Unblocked signal #16
Number of signals so far: 5
Unblocked signal #2
Number of signals so far: 6
Killed
uxb3%
uxb3% kill -USR1 15469
uxb3% kill -USR2 15469
uxb3% kill -INT 15469
uxb3% kill -ALRM 15469
uxb3% kill -USR1 15469
uxb3% kill -INT 15469
uxb3% kill -KILL 15469
uxb3%
getppid
read
stat
chdir
kill
rmdir
time
chmod
link
sigaction
unlink
chown
lstat
sigaddset
wait
close
mkdir
sigdelset
waitpid
execle
mkfifo
sigfillset
write
execve
open
sigismember
fork
pause
sigprocmask
fstat
pipe
sigsuspend
getpid
raise
sleep
Some Async-signal Safe Functions