在本节中,我们将会讲述如何在信号编号与信号名称之间进行映射。一些系统提供了数组
extern char *sys_siglist[];
其中数组索引就是信号编号,给出一个指向信号名称字符串的指针。
FreeBSD 8.0, Linux 3.2.0以及 Mac OS X 10.6.8都提供了这个信号名称的数组,Solaris 10也提供了,但是指针数组名称为_sys_siglist.
为了可移植地实现某一信号编号对应信号名称的字符串的打印,我们可以使用函数psignal.
#include <signal.h>
void psignal(int signo, const char *msg);
字符串msg将会被输出到标准错误中,并且后面紧跟着一个冒号以及空格,接下来是信号的描述信息以及一个换行符。如果参数msg是NULL,那么仅仅只有描述会被写出到标准输出中,该函数与函数perror类似(1.7节)。
如果你有一个来源于sigaction信号处理函数的siginfo结构,你可以使用函数psiginfo函数来打印信号信息。
#include <signal.h>
void psiginfo(const siginfo_t *info, const char *msg);
该函数的功能与函数psignal相类似,虽然该函数除了信号处理函数之外还有很多可以访问的信息,但是具体打印的信息因平台而异。
如果你只是需要字符串描述,并不想要将其写出到标准错误中去,比如说,你只是想要将其写到一个日志文件中去,那么你可以使用函数strsignal,该函数与函数strerror相似(1.7节中讲到)。
#include <string.h>
char *strsignal(int signo);
Returns: a pointer to a string describing the signal.
给定一个信号编号,函数strsignal就可以返回描述该信号的字符串。该字符串可以被应用程序用于打印接收到信号的错误信息。
本书中讲到的四个平台都实现了函数psignal以及strsignal,但是存在差异,在Solaris 10上,strsignal在信号编号无效的时候会返回一个空指针,而FreeBSD 8.0,Linux 3.2.0以及 Mac OS X 10.6.8会返回一个现实信号不可识别的字符串。
仅仅只有Linux 3.2.0以及Solaris 10支持函数psiginfo.
Solaris还提供了一对函数用于在信号编号与信号名称之间做转换。
#include <signal.h>
int sig2str(int signo, char *str);
int str2sig(const char *str, int *signop);
Both return: 0 if OK, -1 on error.
该函数对于需要接受和打印信号名称以及信号编号的交互式程序非常有用。
函数sig2str将信号编号转换成字符串并存储结果到str指向的内存中,调用者必须确保内存足够大来保存最大的字符串,包括终止的null字节,Solaris在中提供了常量SIG2STR_MAX来定义了最大字符长度,字符串包含了不带前缀”SIG”的信号名称,举例来说,转换信号SIGKILL的结果是”KILL”被存储到内存中。
函数str2sig将给定的信号名称转换成信号编号,信号编号被存储到整形指针指向的内存中,信号名称要么是没有SIG前缀的信号名,要么是十进制数,比如说”9”.
注意,函数sig2str与函数str2sig与常规惯例是不一样的,它们在执行失败的时候并不会设置errno.
Example
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
char msg[256] = "This is what I want to output before signal description:\n";
psignal(SIGUSR1,msg);
printf("msg = %s\n", msg);
}
执行效果如下图所示:
[email protected]:~/UnixProgram/Chapter10$ ./10_FF.exe
This is what I want to output before signal description:
: User defined signal 1
msg = This is what I want to output before signal description:
[email protected]:~/UnixProgram/Chapter10$