signal原型分析
来源:互联网 发布:淘宝鞋子试用报告 编辑:程序博客网 时间:2024/06/05 09:56
在linux-0.11内核中,我们找到signal函数原型:
void (*signal(int _sig, void (*_func)(int)))(int);
这个函数很难理解,先复习看一些基础知识。
1、函数指针定义
int (*f)(int); //定义f为 有一个int类型参数,返回值为int的 函数指针
int p(int); // 我们可以通过 f = &p; 对f进行赋值。
char ( *pf(long) )(int) {} //定义pf为有一个long类型参数,返回值为(有一个int类型参数,返回值为char类型函数指针) 的函数
那么void (*signal(int _sig, void (*_func)(int)))(int);
即是 声明了一个带有2个参数,返回值为带有一个int类型参数,返回值为void的函数指针 的函数
2、通过小例子进一步学习
#include <stdio.h>void pt(int){printf("2\n");}void (*f(int, void (*fun)(int)))(int){return fun;}int main(){f(0, pt);printf("----\n");(*f(0, pt))(0);}这个小程序的输出为:
f(0, pt); 调用后,返回fun的地址,即将fun的地址推送到eax, 但是并未执行。
(*f(0, pt))(0); 调用后, 将eax的地址作为一个函数进行调用, 所以这样的输出就不难理解了。
3、signal源码分析
signal通过int0x80调用系统中断sys_signal. 实现和上面的f基本一样, 其实f就是signal的简化版。
int sys_signal(int signum, long handler, long restorer){struct sigaction tmp;if (signum<1 || signum>32 || signum==SIGKILL)return -1;tmp.sa_handler = (void (*)(int)) handler;tmp.sa_mask = 0;tmp.sa_flags = SA_ONESHOT | SA_NOMASK;tmp.sa_restorer = (void (*)(void)) restorer;handler = (long) current->sigaction[signum-1].sa_handler;current->sigaction[signum-1] = tmp;return handler;}这个函数将signal(SIG_NUM, handle)传递的参数在进程上下文(信号处理表)中进行注册, 同时返回旧的handle地址。
该函数和上面的f一样,只是将handle地址存放到eax寄存器,当做调用的返回, 并未实际执行函数。
4、更好的方法
typedef void (*__sighandler_t) (int);
//引入 __sighandler_t 类型 为 一个带int类型参数,返回值为void的函数指针 的关键字
extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler)
//声明一个返回值为函数指针的函数
- signal原型分析
- signal函数的原型声明void (*signal(int signo, void (*fun(int))))(int)分析
- C专家编程—分析signal函数的原型声明{void (*signal(int sig,void (*func)(int)))(int)}(2)
- C专家编程—分析signal函数的原型声明{void (*signal(int sig,void (*func)(int)))(int)}(2)
- signal()函数分析
- Linux Signal实现代码分析
- Linux信号(signal) 机制分析
- Linux信号(signal) 机制分析
- Linux信号(signal) 机制分析
- Linux Signal实现代码分析
- Linux信号(signal) 机制分析
- Linux信号(signal) 机制分析
- Linux信号(signal) 机制分析
- Linux信号(signal) 机制分析
- Linux Signal实现代码分析
- Linux信号(signal) 机制分析
- Linux信号(signal) 机制分析
- Linux Signal实现代码分析
- linux网络编程:并发服务器的模型
- Fiddler 教程
- 打印1到最大的n位数
- Eclipse快捷键 10个最有用的快捷键
- [教程] 手把手教你如何安装Google Play框架服务不闪退
- signal原型分析
- priority_queue优先队列容器
- Windows Server 2012重复数据删除增强
- twitter授权后,在填入pincode时闪退
- iframe/window.open打开一个新窗口/子窗口中调用父窗口的方法
- 提交表单
- MATLAB CIC滤波
- android 代码实现软件的静默安装,卸载功能(转载)
- JPA & Hibernate 注解