title: C + UNIX, siglongjmp and sigsetjmp
body: <p>I have a program from a (oldish) text book that is intended to illustrate the use of POSIX signals on UNIX. The program runs a computational loop to compute perfect numbers starting at a fixed point.</p>
  
  <ul>
  <li>A time alarm signal is used to periodically print status.</li>
  <li>An interrupt signal is used for status on demand.</li>
  <li>A quit signal is used to reset the test interval (or terminate).</li>
  </ul>
  
  <hr>
  
  <pre><code>void perfect(int);
  
  sigjmp_buf jmpenv; /* environment saved by setjmp*/
  
  int n; /* global variable indicating current test point */
  
  int main() {
  
      int begin; /* starting point for next search*/
          /* interrupt routines*/
      void status();
      void query();
  
      sigset_t mask;
      struct sigaction action;
  
  
      if (sigsetjmp(jmpenv,0)) {
          printf("Enter search starting point (0 to terminate): ");
          scanf("%d",&amp;begin);
          if (begin==0) exit(0);
          sigprocmask(SIG_UNBLOCK, &amp;mask, NULL);
          }
      else begin=2;
  
      /* Status Routine will handle timer and INTR */
  
      sigemptyset(&amp;mask);
      sigaddset(&amp;mask, SIGINT);
      sigaddset(&amp;mask, SIGALRM);
      sigaddset(&amp;mask, SIGQUIT);
      action.sa_flags=0;
      action.sa_mask=mask;
  
      action.sa_handler=status;
      sigaction(SIGINT,&amp;action,NULL);
      sigaction(SIGALRM,&amp;action,NULL);
  
      action.sa_handler=query;
      sigaction(SIGQUIT,&amp;action,NULL);
  
      /* start alarm clock */
      alarm(20);
      perfect(begin);
  }
  
  void perfect(start) 
      int start;
  {
      int i,sum;
  
      n=start;
  
  while (1) {
      sum=1;
      for (i=2;i&lt;n;i++)
          if (!(n%i)) sum+=i;
  
      if (sum==n) printf("%d is perfect\n",n);
      n++;
      }
  }
  
  void status(signum) 
  int signum;
  {
  
      alarm(0); /* shutoff alarm */
  
      if (signum == SIGINT) printf("Interrupt ");
      if (signum == SIGALRM) printf("Timer ");
  
      printf("processing %d\n",n);
  
      alarm(20);  /*restart alarm*/
  }   
  
  void query() {siglongjmp(jmpenv,1);}
  </code></pre>
  
  <p>My questions are:</p>
  
  <ol>
  <li>Why does it call void status(); and void query(); in the main at first?</li>
  <li>After the if statement checks begin == 0 and decides to exit, it follows a line called "sigprocmask(SIG_UNBLOCK, &amp;mask, NULL);" Why do I have to make it unblock after I exit already?</li>
  </ol>