Sunday, October 19, 2014

Unix Prog: sleep function and signals

1. Implement sleep using sigalrm

sleep.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<signal.h>  
   
 void sig_alrm(int signo)  
 {}  
   
 unsigned int sleep(unsigned int nsecs)  
 {  
  struct sigaction newact, oldact;  
  sigset_t newmask, oldmask, suspmask;  
  unsigned int unslept;  
   
  // Setup the SIGALRM handler  
  newact.sa_handler = sig_alrm;  
  sigemptyset(&newact.sa_mask);  
  newact.sa_flags = 0;  
  sigaction(SIGALRM, &newact, &oldact);  
   
  // Block SIGALRM  
  sigemptyset(&newmask);  
  sigaddset(&newmask, SIGALRM);  
  sigprocmask(SIG_BLOCK, &newmask, &oldmask);  
   
  alarm(nsecs);  
   
  // Make suspend mask, make sure SIGALRM is unblocked  
  suspmask = oldmask;  
  sigdelset(&suspmask, SIGALRM);  
  sigsuspend(&suspmask);  
   
  // Restore SIGALRM action, restore signal mask  
  unslept = alarm(0);  
  sigaction(SIGALRM, &oldact, NULL);  
   
  sigprocmask(SIG_SETMASK, &oldmask, NULL);  
  return(unslept);  
 }  
   
 int main(int argc, char* argv[])  
 {  
  sleep(3);  
 }  

2. Problem of "sleep with SIGALRM"
Since it use alarm function to generate the SIGALRM signal.
But what if user is trying to call more than one alarm function across different system calls. At some operating system, the second alarm function will cancel the previous one.
But in above case, we are using sigsuspend to stop the process, so there is no way to run another sleep function with alarm which can cancel previous alarm.

No comments:

Post a Comment