Как преобразовать имя сигнала (строку) в код сигнала? - PullRequest
7 голосов
/ 09 августа 2011

Я пишу программу, которая читает имя сигнала (например, SIGSTOP, SIGKILL и т. Д.) В виде строки из командной строки и вызывает системный вызов kill () для отправки сигнала. Мне было интересно, если есть простой способ преобразовать строку в сигнальные коды (в signal.h).

В настоящее время я делаю это, написав свою собственную карту, которая выглядит следующим образом:

signal_map["SIGSTOP"] = SIGSTOP;
signal_map["SIGKILL"] = SIGKILL;
....

Но утомительно писать это для всех сигналов. Итак, я искал более элегантный способ, если он существует.

Ответы [ 3 ]

15 голосов
/ 09 августа 2011

Не уверен, что это то, что вы ищете, но: strerror () преобразует код ошибки в сообщение об ошибке, аналог strsignal () преобразует сигнал в сигнальное сообщение.

fprintf(stdout, "signal 9: %s\n", strsignal(9));
fprintf(stdout, "errno 60: %s\n", strerror(60));

Output:
signal 9: Killed
errno 60: Device not a stream
5 голосов
/ 09 августа 2011

Вы можете использовать такую ​​командную строку, как эта

kill -l \
        | sed 's/[0-9]*)//g' \
        | xargs -n1 echo \
        | awk '{ print "signal_map[\"" $0 "\"] = " $0 ";" }'

Она напишет вашу карту для вас.

1 голос
/ 09 августа 2011

Используя C ++ 0x, вы можете использовать списки инициализаторов, чтобы сделать это более простым:

const std::map<std::string, signal_t> signal_map{ 
   {"SIGSTOP", SIGSTOP },
   {"SIGKILL", SIGKILL },
   ... 
};

Это дает вам карту с меньшим количеством кода для написания.Если вы хотите, вы также можете использовать магию препроцессора, чтобы сделать код еще проще и избежать многократного написания имени.Но чаще всего злоупотребление препроцессором приводит только к тому, что код становится менее полезным, а не к лучшему.(Обратите внимание, что магию препроцессора все еще можно использовать, если вы решите не использовать C ++ 0x и продолжайте в том же духе).

...