Operating System/System Programming(Arif Butt)

Lec25) Design and Code Of Signal Handlers

Tony Lim 2021. 7. 17. 22:17

kill system call

int kill(pid_t pid, int sig);

if sig is zero than normal error checking is performed but no signal is sent. Used to determine if a specified process still exists. if it doesn't exist, a -1 is returned and errno is set to ESRCH

if pid > 0 , the signal is sent to the process with the process ID specified by first argument

if pid == 0 the signal is sent to every process in the same process group as the calling process, including the calling process itself

if pid < -1 , the signal is sent to every process in the procss group whose PGID equals the absolute value of pid

if pid == -1 , the signal is sent to every process for which the calling process has permission to send a signal, except init an d the calling process. if a privileged process makes this call, then all processes on the system will be signaled , except for these last two.

 

raise library call = send a signal to itself.

abort library call = terminates the calling process by rasing a SIGABRT singal and generate core dump file.

pause system call = causese the invoking process/ thread to sleep until a signal is received that either terminates it or causes it to call a signal catching function.

alarm system call = used to ask th OS to send calling process a special signal SIGALARM after a given number of seconds.

 

using singal function(signal handler) to handle signal

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void sigint_handler(int signum){
  printf("\nHey, I got SIGINT: %d\n\n",signum);
  signal(SIGINT,SIG_DFL);
}
void sigquit_handler(int signum){
  printf("\nHey, I got SIGQUIT: %d\n\n",signum);
  signal(SIGQUIT,SIG_DFL);   
}
void sigtstp_handler(int signum){
  printf("\nHey, I got SIGTSTP: %d\n\n",signum);
  signal(SIGTSTP,SIG_DFL);   
}
        
int main(){
   signal(SIGINT,sigint_handler);
   signal(SIGQUIT, sigquit_handler);
   signal(SIGTSTP, sigtstp_handler);
   while(1) {
	printf("I am in an infinite loop!\n");
	sleep(1);
   }
   return 0;
}

signal 2, 3 20 will not work , but if we give signal twice it will work due to "signal(SIGINT,SIG_DFL);" meaning from now on it will be default setting.

 

 

Avoiding Race condition using signal mask

one of the problems that might occur when handling a signal is the occurrence of a second signal while the signal handler function is executing.

every process has a signal mask that defines the set of signals currently blocked for that process. One bit for each possible signal. If a bit is ON, that signal is currently blocked.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h> 
#include <unistd.h>

int main(){
   sigset_t newset, oldset;
   sigemptyset(&newset);
   sigaddset(&newset, SIGINT);
   sigprocmask(SIG_SETMASK, &newset, &oldset);
   int i = 0;
   for(i=1; i<=10; i++){
	printf("I am masking SIGINT for 10 seconds!\n");
	sleep(1);
  }
  sigprocmask(SIG_SETMASK, &oldset, NULL);
   for(i=1; i<=10; i++){
	printf("Now I am having the old sigset without any mask\n");
	sleep(1);
  }
   return 0;
}

this process will block "Control C" , SIGINT for 10 seconds.