プログラムの終了状態を信号名に変換する方法

プログラムの終了状態を信号名に変換する方法
pid_t waitpid(pid_t pid, int *status, int options);

たとえば、status = 2の場合は「SIGINT」文字列が返され、status = 11の場合は「SIGSEGV」文字列が返されます。状態を受け取り、信号名を出力する組み込みのc関数はありますか?

答え1

strerror(n)と同様に、strsignal(n)SIGINT -> "Interrupt"などの詳細な名前を提供します。しかし、それは実際にあなたが望むものではありません。

Stackoverflowに対するこの回答はsigabbrev_np()glibc 2.32で利用可能であることを示唆しています。 https://stackoverflow.com/a/68481682/6372809

プリプロセッサはシグナルの略語とエラー番号の略語を知っているため、コードレビューで次の回答に示すようにリストを手動で作成できます。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

ここで問題は、フォームに記入するすべての名前を見つけることです。

これに対する 1 つのオプションは、コンパイラに既知の定義をダンプさせることです。例:

$ 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+1などであるのかよくわかりませんSIGRTMAX

または、少なくともLinuxを使用している場合は確認してください。マニュアルページ信号のリストを取得します。数字は異なるアーキテクチャ間で混在しており、存在するシグナルはわずかに異なりますが、そこから名前のリストを取得できます。

答え2

glibc 2.32以降の場合は、次のものを使用できます。sigabbrev_np:

sigabbrev_np() 関数は、シグナルの省略名である sig を返します。たとえば、SIGINT 値が与えられた場合、文字列 "INT" が返されます。

SIGしたがって、それを取得するには接頭辞を付けるだけですSIGINT

関連情報