【问题标题】:Where is FreeBSD libc's _write defined?FreeBSD libc 的 _write 定义在哪里?
【发布时间】:2015-02-26 00:52:17
【问题描述】:

this _write() used in stdio 的代码在哪里?

wiki page 说每个系统调用都必须在主文件和 libc 的 Symbol.map 中注册,它还说对于 Symbol.map 中的每个条目都会生成三个符号:symbol、@987654327 @ 和 sys_symbol

我在Symbol.map 中找到了write syscall_write symbol 的系统,但我找不到_write 的实际代码。

【问题讨论】:

标签: freebsd system-calls libc


【解决方案1】:

请记住,_write 是一个 /very/ 复杂的系统调用。由于它在文件句柄上运行,该文件句柄可能是任何类型的文件系统甚至网络套接字上的文件,所以它基本上分叉到整个内核的位置。

您链接到的 wiki 页面是开始了解 FreeBSD 系统调用的正确位置。 write 可能不是用来理解它们的最佳系统调用,如果那是你想要做的。

write 系统调用的实现(来自 FreeBSD 10.0-RELEASE):

/usr/src/sys/kern/sys_generic.c:358

#ifndef _SYS_SYSPROTO_H_
struct write_args {
    int fd;
    const void *buf;
    size_t  nbyte;
};
#endif
int
sys_write(td, uap)
    struct thread *td;
    struct write_args *uap;
{
    struct uio auio;
    struct iovec aiov;
    int error;

    if (uap->nbyte > IOSIZE_MAX)
        return (EINVAL);
    aiov.iov_base = (void *)(uintptr_t)uap->buf;
    aiov.iov_len = uap->nbyte;
    auio.uio_iov = &aiov;
    auio.uio_iovcnt = 1;
    auio.uio_resid = uap->nbyte;
    auio.uio_segflg = UIO_USERSPACE;
    error = kern_writev(td, uap->fd, &auio);
    return(error);
}

【讨论】:

  • 顺便说一句,虽然系统调用有时在 libc 中有包装器,但原始系统调用不在 libc 内部,而是在内核本身中。
  • 你的猜测是对的,我试图了解系统调用是如何工作的。我只是随机选择了puts,因为我猜 IO 需要一个系统调用。我知道在 x86 上它最终将使用int $0x80,如libc/i386/SYS.h 中定义的那样,在系统调用的那一刻,所有参数都将在堆栈中,SYS_write 在寄存器中,但我找不到在哪里系统调用实际上已经完成,我的意思是,使用中断的代码在哪里?另外,我猜系统调用最终会在i386/i386/trap.c结束,对吗?
  • 在我的手机上,所以我无法查看 src,但听起来不错。 getpid() 系统调用通常是跟踪内核的最佳第一个系统调用。它进入内核,获取一个值,然后将其交还给用户空间。 I/O 很丑陋,我尽量避免它
猜你喜欢
  • 1970-01-01
  • 2014-06-01
  • 2013-04-05
  • 1970-01-01
  • 2021-09-07
  • 2013-04-09
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多