LINUX.ORG.RU

Список названий доступных сигналов в системе


1

2

Хочу вывести на экран список всех сигналов, доступных в системе, как это делает kill -l. Знаю два способа: 1. Рекомендуемый в signal.h:

void print_signals() {
    for(int i = 0;i<NSIG;i++) {
        printf("%d %s\n", i, strsignal(i));
    }
}

2. Более универсальный

void print_signals() {
    for(int i = 0;i<NSIG;i++)
    {
        printf("%d %s\n", i, sys_siglist[i]);
    }
}

Естественно, не обращаем внимание на отсутствие проверок и тп. Так вот, и тот и другой способ в linux выдает не название сигналов(SIGHUP, SIGINT, SIGQUIT, SIGILL, ....), а их описание: 1 Hangup 2 Interrupt 3 Quit 4 Illegal instruction 5 Trace/breakpoint trap

Беглый осмотр исходников kill показал, что список имен сигналов в ней зашит физически. Скорее всего такой подход себя оправдывает, но, возможно, есть какой-то способ получить список имен без зашивания его в код? Например, названия в netbsd и linux немного отличаются, не хотелось бы городить огород из defineов.

есть какой-то способ получить список имен без зашивания его в код?

Сигнал - всего лишь цифра. Ты хочешь в ядре помимо таблицы сигналов хранить еще и таблицу их названий?

anonymous
()
Ответ на: комментарий от anonymous

Во-первых, описания хранятся и никому не мешают. Во-вторых, в BSD вроде хранятся и описания и названия - есть два массива sys_siglist и sys_signame, насколько я помню. Да и не в ядре это держать, а достаточно в libc.

deadedge
() автор топика

Хочу вывести на экран список всех сигналов, доступных в системе, как это делает kill -l

список имен сигналов в ней зашит физически.

Сколько там байт на таблицу? Стоит их экономить?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Дело не в экономии. Дело в переносимости. Например, сигнал номер 7 в linux - SIGBUS, в NetBSD - SIGEMT. Во-первых, уже надо держать две разных таблицы и на этапе сборки проверять под какой ОС собираемся. Во-вторых, если вдруг одна из ОС расширит список сигналов, придется эти таблицы дополнять вручную. Такое решение не универсально и не удобно. Более того, в netbsd такую таблицу сделать догадались, я надеялся, что в glibc тоже есть такая возможность, просто я о ней не знаю.

deadedge
() автор топика
Ответ на: комментарий от deadedge

О, теперь понятно.

Может на этапе компиляции так делать?

echo '#include <signal.h>' | gcc -dM -E - | grep '^#define SIG[A-Z]\+ [0-9]\+' | sed -r 's/^#define (SIG[A-Z]+) ([0-9]+)/  { "\1", \2 },/'

signal.h должен везде быть.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от deadedge

Во, вот так лучше получается:

echo '#include <signal.h>' | gcc -dM -E - | grep '^#define SIG[A-Z]\+ [0-9]\+' | grep -v "SIGSTKSZ" | awk '{if($3>m){m=$3}; q[$3]=$2;}END{print "static const int signames_cnt = "(m+1)";\nstatic const char *signames[] = {";for(i=0;i<=m;i++){if(i==m)print"  \""q[i]"\"";else print"  \""q[i]"\","}print"}"}'
static const int signames_cnt = 32;
static const char *signames[] = {
  "",
  "SIGHUP",
  "SIGINT",
  "SIGQUIT",
  "SIGILL",
  "SIGTRAP",
  "SIGIOT",
  "SIGBUS",
  "SIGFPE",
  "SIGKILL",
  "",
  "SIGSEGV",
  "",
  "SIGPIPE",
  "SIGALRM",
  "SIGTERM",
  "SIGSTKFLT",
  "SIGCHLD",
  "SIGCONT",
  "SIGSTOP",
  "SIGTSTP",
  "SIGTTIN",
  "SIGTTOU",
  "SIGURG",
  "SIGXCPU",
  "SIGXFSZ",
  "SIGVTALRM",
  "SIGPROF",
  "SIGWINCH",
  "SIGIO",
  "SIGPWR",
  "SIGUNUSED"
}

Кроме linux, у меня проверить больше негде.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Предыдущий вариант был удобнее - там по номеру искать проще.

Так вот, возвращаясь к сути проблемы. Что дает нам линукс:

static const int signames_cnt = 32;
static const char *signames[] = {
  "",
  "SIGHUP",
  "SIGINT",
  "SIGQUIT",
  "SIGILL",
  "SIGTRAP",
  "SIGIOT",
  "SIGBUS",
  "SIGFPE",
  "SIGKILL",
  "",
  "SIGSEGV",
  "",
  "SIGPIPE",
  "SIGALRM",
  "SIGTERM",
  "SIGSTKFLT",
  "SIGCHLD",
  "SIGCONT",
  "SIGSTOP",
  "SIGTSTP",
  "SIGTTIN",
  "SIGTTOU",
  "SIGURG",
  "SIGXCPU",
  "SIGXFSZ",
  "SIGVTALRM",
  "SIGPROF",
  "SIGWINCH",
  "SIGIO",
  "SIGPWR",
  "SIGUNUSED"
}

и что дает нам netbsd:

static const int signames_cnt = 33;
static const char *signames[] = {
  "",
  "SIGHUP",
  "SIGINT",
  "SIGQUIT",
  "SIGILL",
  "SIGTRAP",
  "SIGABRT",
  "SIGEMT",
  "SIGFPE",
  "SIGKILL",
  "SIGBUS",
  "SIGSEGV",
  "SIGSYS",
  "SIGPIPE",
  "SIGALRM",
  "SIGTERM",
  "SIGURG",
  "SIGSTOP",
  "SIGTSTP",
  "SIGCONT",
  "SIGCHLD",
  "SIGTTIN",
  "SIGTTOU",
  "SIGIO",
  "SIGXCPU",
  "SIGXFSZ",
  "SIGVTALRM",
  "SIGPROF",
  "SIGWINCH",
  "SIGINFO",
  "",
  "",
  "SIGPWR"
}

как говориться - разница на лицо.

deadedge
() автор топика
Ответ на: комментарий от deadedge

Предыдущий вариант был удобнее - там по номеру искать проще.

А по мне так signames[9] проще, чем обходить массив структур каждый раз.

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.