Linux

如何將程序的退出狀態轉換為信號名稱

  • October 16, 2021
pid_t waitpid(pid_t pid, int *status, int options);

比如status=2,返回字元串“SIGINT”,status=11,返回字元串“SIGSEGV”。是否有一個內置的 c 函式可以接收狀態並輸出信號名稱?

與 類似strerror(n),還有strsignal(n),它給出了詳細的名稱,例如 SIGINT -> “Interrupt”。但這不是你真正想要的。

Stackoverflow 上的這個答案表明sigabbrev_np()glibc 2.32 中應該可以使用: https

信號縮寫以及錯誤編號縮寫是預處理器已知的,因此您可以手動建構一個列表,如程式碼審查上的此答案:https ://codereview.stackexchange.com/a/252825/111089

在那里處理程式碼以減少 #預處理器運算符的重複,該程序將通過數字知道一些信號的名稱:

#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define init_signame(x) [x] = #x

static const char *signames[] = {
   init_signame(SIGINT),
   init_signame(SIGSTOP),
   init_signame(SIGTERM),
   init_signame(SIGKILL),
   init_signame(SIGHUP),
   [0] = ""
};

const char *getsig(int sig) {
   if (sig <= 0 || sig >= sizeof(signames) / sizeof(*signames) || !signames[sig])
       return "UNKN";

   return signames[sig];
}

int main(int argc, char *argv[])
{
   int i = 0;
   if (argc > 1) {
       i = atoi(argv[1]);
   }
   printf("%d = %s = %s\n", i, getsig(i), strsignal(i));
}

它給出了例如:

$ ./signame2 1
1 = SIGHUP = Hangup

這裡的問題是找出所有的名字來填寫表格……

為此,一種選擇是讓編譯器轉儲它知道的定義,例如:

$ gcc -dM -E - <<< '#include <signal.h>' |grep -E '#define SIG[A-Z]+ ' 
#define SIGBUS 7
#define SIGTTIN 21
#define SIGTTOU 22
...

然後使用腳本來建構一些有用的東西。請注意,也可能有這樣的條目:

#define SIGCLD SIGCHLD
#define SIGRTMAX (__libc_current_sigrtmax ())

而且我不確定實時信號是否在任何地方都有單獨的定義,或者它們是否只是SIGRTMIN+0,SIGRTMIN+1SIGRTMAX

或者,至少如果您使用的是 Linux,請查看手冊頁以獲取信號列表。這些數字在不同的架構之間打亂,存在的信號也略有不同,但您可以從那裡獲得名稱列表。

引用自:https://unix.stackexchange.com/questions/673100