从linux 系统调用 学习可变参数宏的用法
来源:互联网 发布:爱口袋软件下载 编辑:程序博客网 时间:2024/04/28 18:06
转载自http://blog.chinaunix.net/uid-23069658-id-4106015.html?page=2
截取了作者原文中,自己比较关系你的一部分
这段时间又碰到系统调用这个家伙,结果在我当前用的3.0.x内核里全变样了。为了将这个问题弄明白,还得自己动手才行,这里非常感谢CSDN的"海风林影"兄弟提供的博文和相关参考文献,还是那句话“成果和荣耀归于前辈”。
很多人也都发现,在2.6.28及其之后的内核源码里,系统调用的写法发生了比较大的变化,出现了大量宏定义的代码。在源代码里,以前的诸如open()系统调用的sys_open()函数,现在仅仅能找到其声明,而其定义却“找不到”了。如果你把系统调用的宏展开后就会发现,以前的sys_open()依然安然无恙地躺在哪里。
这里我们仍然以open系统调用为例。在内核源码(当然这里的内核版本要大于等于2.6.28)fs目录下的open.c源文件里,我们会看到下面这样的代码:
点击(此处)折叠或打开
- SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode)
- {
- long ret;
- if (force_o_largefile())
- flags |= O_LARGEFILE;
- ret = do_sys_open(AT_FDCWD, filename, flags, mode);
- /* avoid REGPARM breakage on x86: */
- asmlinkage_protect(3, ret, filename, flags, mode);
- return ret;
- }
点击(此处)折叠或打开
- asmlinkage long sys_open(const char __user * filename, int flags, int mode)
- {
- long ret;
- if (force_o_largefile())
- flags |= O_LARGEFILE;
- ret = do_sys_open(AT_FDCWD, filename, flags, mode);
- asmlinkage_protect(3, ret, filename, flags, mode);
- return ret;
- }
那么SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)是如何转换成asmlinkage long sys_open(const char __user *filename, int flags, umode_t mode)形式的呢?其实就是宏的一些基本用法而已,我们来简单分析一下。在include/linux/syscall.h里有下面一组宏:
点击(此处)折叠或打开
- #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void)
- #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
- #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
点击(此处)折叠或打开
- #define SYSCALL_DEFINEx(x, sname, ...) \
- __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
点击(此处)折叠或打开
- #define __SYSCALL_DEFINEx(x, name, ...) \
- asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))
点击(此处)折叠或打开
- #define __SC_DECL1(t1, a1) t1 a1
- #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__)
- #define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__)
- #define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__)
- #define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__)
- #define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__)
1 0
- 从linux 系统调用 学习可变参数宏的用法
- 可变参数宏的用法
- 《C预处理》Linux内核中可变参数宏的用法
- va宏的用法 可变参数
- 关于可变参数的用法
- vsnprintf()可变参数的用法
- 可变个数参数的用法
- vsnprintf()可变参数的用法
- LINUX 可变参数的使用
- LINUX 可变参数的使用
- 可变参数宏的用法举例--求平均数的例子
- 学习C的可变参数
- 学习C的可变参数
- “可变参数列表”的学习
- 可变参数的宏
- 可变参数的宏
- 可变参数的宏
- 动态的调用可变参数函数
- python读取、写入csv数据:csv模块
- android 流式布局简单实现
- 10.数据库命令操作 runCommand()
- android 请求工具FinalHttp和HttpUtils的一个区别
- mac vim下的批量缩进
- 从linux 系统调用 学习可变参数宏的用法
- 非常实用的C# backgroundworker使用方法
- Ubuntu14安装pcl点云库
- 获取IP地址
- RegExp对象方法
- kaldi 中安装GridEngine的一些注意事项
- 自方幂数
- 【nodejs】数据解析处理的一些问题
- 输入框EditText