In glibc 2.22, in the /socket
directory, the socket library implementation is located.
When opening any of these files, though, all I see is an error-setting function with some macros beneath it.
Here's an example file (/socket/send.c
):
#include <errno.h>
#include <sys/socket.h>
/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */
ssize_t
__send (fd, buf, n, flags)
int fd;
const __ptr_t buf;
size_t n;
int flags;
{
__set_errno (ENOSYS);
return -1;
}
libc_hidden_def (__send)
weak_alias (__send, send)
stub_warning (send)
(Comment with license removed.)
Where is that send
the weak_alias
macro has as an argument? Where are these macros defined?
I think this is due to compatibility with some crappy old compiler but why do they still use K&R syntax?
And most important, why is __send
defined like that?
There's a couple of things going on here.
First, as explained in this answer, glibc itself cannot define random identifiers that standard C does not reserve, because standard C allows programs to define those identifiers itself. Names beginning with a double underscore are reserved for the implementation, so the implementation here defines the function __send()
. The weak alias then allows the name send()
to be used to refer to it, but also allows that reference to be overridden by a strong definition somewhere else.
Second, as explained in the glibc documentation, for ease of porting glibc requires any machine-specific function to have a corresponding generic function. If a corresponding generic function can be written, then it should be, but if not, the generic one should be a "stub function", which essentially just sets errno
to ENOSYS
(not implemented) and returns an error. If there is a machine-specific function provided, that'll be used instead of the stub function. Since send()
requires a system call, obviously it cannot be written in a machine-independent way, so there's a stub function for it here. So you should be able to locate a machine-specific implementation (or a variety of them) of __send()
, for instance, at /sysdeps/unix/sysv/linux/x86_64/send.c
in the glibc source tree.
Incidentally, since send()
is indeed a system call, all you're typically going to see in glibc is a short assembly language routine that makes the system call. The code that actually does stuff will live in the kernel.