SOCKET用户接口与系统调用关系

所有的socket系统调用的总入口是sys_socketcall(),在include/linux/Syscalls.h中定义

其中,
@param call 标识接口编号,
@param args 是接口参数指针

接口编号的定义在 include/uapi/linux/net.h中定义
SOCKET用户接口与系统调用关系_第1张图片

接口编号对应的参数个数在net/socket.c文件中的nargs数组中定义
SOCKET用户接口与系统调用关系_第2张图片

在net/socket.c中有一个函数SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)便是socket调用的入口。
SOCKET用户接口与系统调用关系_第3张图片

其中SYSCALL_DEFINE2是一个宏,定义在include/linux/syscall.h中
SOCKET用户接口与系统调用关系_第4张图片



SOCKET用户接口与系统调用关系_第5张图片

下面我们来展开展开SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args):
展开第一步得到:
SYSCALL_DEFINEx(2, _##socketcall, int, call, unsigned long __user *, args)

继续展开SYSCALL_DEFINEx,
SYSCALL_METADATA(_socketcall,2,int, call, unsigned long __user *, args) \
__SYSCALL_DEFINEx(2, _socketcall, int, call, unsigned long __user *, args)

SYSCALL_METADATA定义是空,忽略

继续展开__SYSCALL_DEFINEx,
asmlinkage long sys_socketcall(__MAP(2,__SC_DECL,__VA_ARGS__));\
static inline long SYSC_socketcall(__MAP(2,__SC_DECL,__VA_ARGS__)); \
asmlinkage long SyS_socketcall(__MAP(2,__SC_LONG,__VA_ARGS__))\
{\
	long ret = SYSC_socketcall(__MAP(2,__SC_CAST,__VA_ARGS__));\
	__MAP(2,__SC_TEST,__VA_ARGS__);\
	__PROTECT(x, ret,__MAP(2,__SC_ARGS,__VA_ARGS__));\
	return ret;\
} \
SYSCALL_ALIAS(sys_socketcall, SyS_socketcall);\
static inline long SYSC_socketcall(__MAP(2,__SC_DECL,__VA_ARGS__))

这时候的宏包括__MAP(),__SC_DECL 将其展开得到,其中__MAP是一个降维的过程,继续展开得到:
asmlinkage long sys_socketcall (int call, unsigned long __user *args);
static inline long SYSC_socketcall(int call, unsigned long __user *args);
asmlinkage long SyS_socketcall(int call, unsigned long __user *args)
{
long ret = SYSC_socketcall (call, ( unsigned long __user *)args);
return ret;
}
SYSCALL_ALIAS(sys_socketcall, SyS_socketcall);
static inline long SYSC_socketcall((int call, unsigned long __user *args)

到目前为止,sys_socketcall似乎并没有定义,原因是还有一个宏未展开,SYSCALL_ALIAS,在include/linux/linkage.h中定义,
SOCKET用户接口与系统调用关系_第6张图片

在include/linux/export.h中定义,
SOCKET用户接口与系统调用关系_第7张图片

将 SYSCALL_ALIAS(sys_socketcall, SyS_socketcall) 展开得到:
asm (".globl" sys_socketcall
".set" sys_socketcall, SyS_socketcall)

即sys_socketcall是SyS_socketcall的别名。

所以:展开之后是:
SOCKET用户接口与系统调用关系_第8张图片

那内核为什么要这样呢?可以参考 http://blog.csdn.net/hxmhyp/article/details/22619729

你可能感兴趣的:(CentOs,7.1,源码TCP部分)