当我遇到套接字代码时,我正在阅读glibc,有人可以解释发生了什么吗?

GRA*_*124 9 c glibc

这是我浏览的来源:glibc源码.我的特殊问题来自于这一特定功能集:套接字库.

例如(大多数函数都以这种方式设置)socket/bind.c的来源是:

  19 #include <errno.h>
  20 #include <sys/socket.h>
  21 
  22 /* Give the socket FD the local address ADDR (which is LEN bytes long).  */
  23 int
  24 __bind (fd, addr, len)
  25      int fd;
  26      __CONST_SOCKADDR_ARG addr;
  27      socklen_t len;
  28 {
  29   __set_errno (ENOSYS);
  30   return -1;
  31 }
  32 
  33 weak_alias (__bind, bind)
  34 
  35 stub_warning (bind)
  36 #include <stub-tag.h>
Run Code Online (Sandbox Code Playgroud)

我承认我没有花很多时间,但实际功能的代码究竟在哪里以及发生了什么?这是一个很好用的范例吗?

Gil*_*il' 9

__bind函数是一个存根:它是一个外观像真实的东西(相同的原型),但不执行必要的功能.

weak_alias宏告诉链接器bind要作为一个软弱的别名__bind.也就是说,这个定义bind是一个弱的符号.如果没有其他被称为符号的bind定义,则该定义代表; 如果存在另一个(非弱)定义,bind那么非弱定义就会出现,弱定义会被忽略.弱别名是一个弱符号,它是另一个符号的别名(而不是自己有一个定义).该stub_warning宏导致链接,如果使用的是弱别名发出警告.

真正的实现bind取决于Glibc编译的操作系统.在赫德,它的定义是sysdeps/mach/hurd/bind.c.在Linux上,bind是一个系统调用:在Glibc源代码中没有C代码,只有汇编代码.bind提供了sysdeps/unix/sysv/linux/bind.S重用socketin sysdeps/unix/sysv/linux/**/socket.S或中的体系结构相关定义ports/sysdeps/unix/sysv/linux/*/socket.S.这些定义都是基础系统调用的瘦包装器,注意将参数和返回值复制到适当的寄存器中.


nos*_*nos 8

您正在查看一般的bind()实现,它只是告诉您bind()不是实现(它只返回一个错误并将errno设置为ENOSYS - 未实现系统调用.).

glibc中的许多平台相关系统调用以这种方式工作 - 有一个默认实现只返回错误,并且每个平台/架构师必须提供系统调用的实现(如果存在).

查看例如./sysdeps/unix/sysv/linux/i386/socket.S以获取linux x86实现.

当然,socket()只是一个系统调用,所以实际的实现是在内核中.Glibc只提供一个C包装器来调用它.