I was perusing glibc when I came across the socket code, can someone explain what is going on?

淺唱寂寞╮ 提交于 2019-12-12 07:51:02

问题


Here is the source I was browsing: glibc source. My particular question arises from this particular set of functions: socket library.

For example(most of the functions are set up this way) socket/bind.c's source is:

  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>

I admit I didn't spend a lot of time, but where exactly is the code for the actual function and what is going on? Is this a well used paradigm?


回答1:


The __bind function is a stub: it's a function that looks externally like the real thing (same prototype) but does not perform the requisite function.

The weak_alias macro tells the linker that bind is to be a weak alias for __bind. That is, this definition of bind is a weak symbol. If there is no other definition of a symbol called bind, this definition stands; if there is another (non-weak) definition of bind then that non-weak definition stands and the weak definition is ignored. A weak alias is a weak symbol that is an alias of another symbol (as opposed to having a definition in its own right). The stub_warning macro causes the linker to emit a warning if that weak alias is used.

The real implementation of bind depends on the operating system that Glibc is compiled for. On Hurd, it is defined in sysdeps/mach/hurd/bind.c. On Linux, bind is a system call: there is no C code for it in the Glibc source, only assembly code. bind is provided in sysdeps/unix/sysv/linux/bind.S which reuses the architecture-dependent definition of socket in sysdeps/unix/sysv/linux/**/socket.S or ports/sysdeps/unix/sysv/linux/*/socket.S. Those definitions are all thin wrappers around the underlying system call, taking care to copy the argument and the return values into the proper registers.




回答2:


You're looking at the general bind() implementation which ... just tells you that bind() is not implementet (It just returns an error and sets errno to ENOSYS - syscall not implemented.).

Many platform dependent system calls in glibc work this way - there's a default implementation that just returns an error, and each platform/architector have to provide an implementation of the system call if one exists.

Look in e.g. ./sysdeps/unix/sysv/linux/i386/socket.S for the linux x86 implementation.

Ofcourse, socket() is just a system call, so the actual implementation is in the kernel. Glibc just provides a C wrapper to call it.



来源:https://stackoverflow.com/questions/14882289/i-was-perusing-glibc-when-i-came-across-the-socket-code-can-someone-explain-wha

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!