| 2009年10月12日
socketcall是所有网络函数请求的系统调用接口函数,所有的网络函数的请求最终都会有这个函数要处理。下面就是这个函数的分析:
SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
{
unsigned long a[6];
unsigned long a0, a1;
。。。。
a0 = a[0];
a1 = a[1];
/* copy_from_user should be SMP safe. */
if (copy_from_user(a, args, len)) //这里将参数的地址都拷贝到a[6]这个数组中。
switch (call) { //这里根据这个call的值去判断是哪一个系统调用。其值在include/linux/net.h 中定义,见后面的附录
//这个和上面sysdeps/unix/sysv/linux/socketcall.h 中的是相对应的!!!!
case SYS_SOCKET:
err = sys_socket(a0, a1, a[2]);
break;
case SYS_BIND:
err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
break;
case SYS_CONNECT:
err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
break;
case SYS_LISTEN:
err = sys_listen(a0, a1);
break;
case SYS_ACCEPT:
err = sys_accept4(a0, (struct sockaddr __user *)a1,
(int __user *)a[2], 0);
break;
。。。。。。。。。。。。
注意这里面所调用的函数的参数和前面一篇中分析中的glibc中函数中的参数是要对应的。
这里的sys_socket等函数才是真正的实现,这样在节省了一定的系统调用号,更重要的是能将这一类的系统调用方便归类和维护管理。
附录: nclude/linux/net.h
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */
#define SYS_CONNECT 3 /* sys_connect(2) */
#define SYS_LISTEN 4 /* sys_listen(2) */
#define SYS_ACCEPT 5 /* sys_accept(2) */
#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
#define SYS_SEND 9 /* sys_send(2) */
#define SYS_RECV 10 /* sys_recv(2) */
#define SYS_SENDTO 11 /* sys_sendto(2) */
#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
#define SYS_ACCEPT4 18 /* sys_accept4(2) */
关注「黑光技术」,关注大数据+微服务