Linux内核中的文件描述符(二)——socket和文件描述符

发表于:2013-1-14 10:26

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:ce123    来源:51Testing软件测试网采编

  下图说明了socket和fd是怎样联系起来的。

  下面通过来具体分析一下。sys_socket是socket相关函数的总入口。

net/socket.c
/*
 * System call vectors.
 *
 * Argument checking cleaned up. Saved 20% in size.
 *  This function doesn't need to set the kernel lock because
 *  it is set by the callees.
 */

asmlinkage long sys_socketcall(int call, unsigned long __user *args)
{
 unsigned long a[6];
 unsigned long a0,a1;
 int err;

 if(call<1||call>SYS_RECVMSG)
  return -EINVAL;

 /* copy_from_user should be SMP safe. */
 if (copy_from_user(a, args, nargs[call]))
  return -EFAULT;

 err = audit_socketcall(nargs[call]/sizeof(unsigned long), a);
 if (err)
  return err;

 a0=a[0];
 a1=a[1];
 
 switch(call)
 {
  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_accept(a0,(struct sockaddr __user *)a1, (int __user *)a[2]);
   break;
  case SYS_GETSOCKNAME:
   err = sys_getsockname(a0,(struct sockaddr __user *)a1, (int __user *)a[2]);
   break;
  case SYS_GETPEERNAME:
   err = sys_getpeername(a0, (struct sockaddr __user *)a1, (int __user *)a[2]);
   break;
  case SYS_SOCKETPAIR:
   err = sys_socketpair(a0,a1, a[2], (int __user *)a[3]);
   break;
  case SYS_SEND:
   err = sys_send(a0, (void __user *)a1, a[2], a[3]);
   break;
  case SYS_SENDTO:
   err = sys_sendto(a0,(void __user *)a1, a[2], a[3],
      (struct sockaddr __user *)a[4], a[5]);
   break;
  case SYS_RECV:
   err = sys_recv(a0, (void __user *)a1, a[2], a[3]);
   break;
  case SYS_RECVFROM:
   err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
        (struct sockaddr __user *)a[4], (int __user *)a[5]);
   break;
  case SYS_SHUTDOWN:
   err = sys_shutdown(a0,a1);
   break;
  case SYS_SETSOCKOPT:
   err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]);
   break;
  case SYS_GETSOCKOPT:
   err = sys_getsockopt(a0, a1, a[2], (char __user *)a[3], (int __user *)a[4]);
   break;
  case SYS_SENDMSG:
   err = sys_sendmsg(a0, (struct msghdr __user *) a1, a[2]);
   break;
  case SYS_RECVMSG:
   err = sys_recvmsg(a0, (struct msghdr __user *) a1, a[2]);
   break;
  default:
   err = -EINVAL;
   break;
 }
 return err;
} /* It may be already another descriptor 8) Not kernel problem. */
 return retval;

out_release:
 sock_release(sock);
 return retval;
}

42/4<1234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号