簡體   English   中英

在 C 的 sa_handler 中阻止 SIGINT

[英]Blocking SIGINT within an sa_handler in C

我正在嘗試編寫一個程序,它將設置警報 10 秒,在 10 秒后阻止 SIGINT,設置另一個警報 10 秒,然后解除阻止並忽略 SIGINT,設置另一個警報 10 秒然后終止。 我希望我可以在 sa_handler 中為 SIGALRM 執行所有操作,但它並沒有像我希望的那樣工作。 有可能做到這一點嗎? 編輯:當在 SIGALRM 的 sa 處理程序中時,我無法將 SIGINT 設置為阻塞。

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

int ctrlct = 0;
int alrmct = 0;

void catchctrlc(int signo)
{
  printf("Caught CTRL-C! <%d>\n", ++ctrlct);
}

void catchalrm(int signo)
{
  sigset_t alrmset;
  switch(alrmct)
  {
    case 0:
      printf("Alarm 1\n");
      if( (sigemptyset(&alrmset) == -1) || (sigaddset(&alrmset, SIGINT) == -1) )
        printf("Failed to add SIGINT to the alrmset");
      else if( sigprocmask(SIG_BLOCK, &alrmset, NULL) == -1 )
        printf("Failed to block SIGINT");
      break;
    case 1:
      printf("Alarm 2\n");
      break;
    case 2:
      printf("Alarm 3\n");
      exit(EXIT_SUCCESS);
      break;
    default:
      break;
  }
  alrmct++;
  alarm(10);
}

int main(void)
{
  struct sigaction ctrlact, alrmact;
  ctrlact.sa_handler = catchctrlc;
  ctrlact.sa_flags = 0;
  alrmact.sa_handler = catchalrm;
  alrmact.sa_flags = 0;

  /* Install signal handler for CTRL-C */
  if((sigemptyset(&ctrlact.sa_mask) == -1) || (sigaction(SIGINT, &ctrlact, NULL) == -1))
    perror("Failed to set sa_handler for SIGINT");
  /* Install signal handler for SIGALRM */
  if((sigemptyset(&alrmact.sa_mask) == -1) || (sigaction(SIGALRM, &alrmact, NULL)== -1))
    perror("Failed to set sa_handler for SIGALRM");

  alarm(10);
  while(1){}

  return 0;
}

當一個信號被傳遞時,kernel 將 ->blocked 信號保存到信號幀中,將傳遞的信號添加到 ->blocked 集中(除非指定 SA_NODEFER),並在從處理信號返回時恢復 ->blocked設置為信號幀中的一個,從而覆蓋所做的任何更改。

如果需要這種行為,我們可以通過在信號幀(位於用戶線程的堆棧上)上編輯保存的信號來克服它。 為此,我們需要為警報處理程序指定 SA_SIGINFO 標志,然后:

void catchalrm(int signo, siginfo_t * info, ucontext_t * context)
{

    sigaddset(&context->uc_sigmask, SIGINT);
    ...
}

例如從信號返回時,恢復的->阻塞集將包含 SIGINT。

請注意,此行為可能是 linux 和體系結構特定的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM