c - glibc 的套接字实现在哪里?

标签 c sockets posix glibc

在 glibc 2.22 中,在 /socket 目录中,socket 库实现位于。
但是,当打开这些文件中的任何一个时,我所看到的只是一个错误设置函数,它下面有一些宏。
这是一个示例文件 (/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)

(删除许可后发表评论。)

send weak_alias 宏的参数在哪里?这些宏定义在哪里?
我认为这是由于与一些蹩脚的旧编译器的兼容性,但为什么他们仍然使用 K&R 语法?
最重要的是,为什么 __send 这样定义?

最佳答案

这里发生了几件事。

首先,如 this answer 中所述, glibc 本身不能定义标准 C 不保留的随机标识符,因为标准 C 允许程序自己定义那些标识符。双下划线开头的名称是为实现保留的,所以这里的实现定义了函数__send()。弱别名允许使用名称 send() 来引用它,但也允许该引用被其他地方的强定义覆盖。

其次,解释为in the glibc documentation ,为了便于移植,glibc 要求任何特定于机器的函数都具有相应的通用函数。如果可以编写相应的泛型函数,那么它应该是,但如果不能,那么泛型函数应该是一个“ stub 函数”,它本质上只是将 errno 设置为 ENOSYS (未实现)并返回错误。如果提供了特定于机器的函数,则将使用该函数代替 stub 函数。由于send()需要系统调用,显然不能用机器无关的方式来写,所以这里有一个 stub 函数。因此,您应该能够找到 __send() 的特定于机器的实现(或其中的多种实现),例如,在 /sysdeps/unix/sysv/linux/x86_64/send .c 在 glibc 源代码树中。

顺便说一句,因为 send() 确实是一个系统调用,所以您在 glibc 中通常会看到的只是一个进行系统调用的简短汇编语言例程。实际执行任务的代码将存在于内核中。

关于c - glibc 的套接字实现在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34502501/

相关文章:

c - 某些 OSX 会阻止对端口 80 的套接字调用,直到完成 HTTP 请求

c - 如何使用 lseek 创建有漏洞的文件?

c - 将某些线程的资源分配到全局资源,这样就没有并发性(仅使用互斥体)

c - 未知转义序列

c - "#include <asm/io.h>"导致 "error: asm/io.h: No such file or directory"

C++网络爬虫

c - fork 后选择阅读

c - C中图像接收和处理的并行操作

objective-c - gcc 为 Objective C 定义

c - 为什么 RTOS 任务必须无限循环执行?