问题
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