signal(sig, function) 系统调用

发行日期:

在这星期《操作系统实验指导》上看到了这样一个系统调用:signal(sig, function),呵呵,很好奇,因为每次这课的系统调用都说得很不清楚,连函数原型也没有。所以导致很多同学写的(也可能是抄的..)程序编译不成功,即使编译成功了程序也出错。

于是翻了翻书,书上说这个系统调用的函数原型是 void (*signal (int sig, void (*func) (int))) (int);,更是一惊,这样的函数原型在学校这种SB 课本上是很少见的,可能有些同学看都看不懂,更别说,好好的调用了。当然 <signal.h> 头文件(跟进去看看就知道了,老外还真细心)为代码用户解决了 conversion from 'int (*)(int)' to 'void (*)(int)' 这样的问题,虽然能成功编译文件,但编译时照样会出现警告!

当然如果你认为“警告”无关紧要的话,你就去死吧。0 warning,0 error ,才是我的追求。

void (*signal (int sig, void (*func) (int))) (int); 的原型其实是这样的 void (*p) (int);,有点熟悉了吧?再深入一点 signal (int sig, void (*func) (int));,会引出一个问题,如果 *func 函数是 int (*func) (int) 的怎么办?很多人一不小心就会写成这样。需要强制转换对吧?应该出现ERROR,但为什么,还能编译成功呢?进去 <signal.h> 头文件看看,在75行:

/* Type of a signal handler.  */
typedef void (*__sighandler_t) (int);
extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler)
  __THROW;

原来人家都把强制转换做好了的。我们也可以这样,显示的强制转换:

signal (SIGINT, (void (*)(int))func);
/* 或者可读性好一些的:*/
typedef void (*func_t)(int);
...
signal (SIGINT, (func_t)func);

好了,现在来对这个typedef 进行理解吧,直接看《THE C PROGRAMMING LANGUAGE》 Page.147:

typedef int (*PFI) (char *, char *);
/*
 * creates the type PFI, for ''pointer to function (of two char * arguments) returning int,'' which can be used in contexts like
 * PFI strcmp, numcmp;
 */

现在应该完全理解这个 signal(sig, function) 系统调用了吧。