【问题标题】:How does glibc's write work?glibc 的 write 是如何工作的?
【发布时间】:2017-03-06 19:24:30
【问题描述】:

我尝试用-nostdlib 编译一个名为write 的简单程序,但出现错误:

/path/to/file:3: undefined reference to `write'

我认为write 是 Unix 的东西并且一直存在,但显然不是,结果 libc 具有 write 功能。我找到了源代码:

/* Write NBYTES of BUF to FD.  Return the number written, or -1.  */
ssize_t
__libc_write (int fd, const void *buf, size_t nbytes)
{
    if (nbytes == 0)
        return 0;
    if (fd < 0)
    {
        __set_errno (EBADF);
        return -1;
    }
    if (buf == NULL)
    {
        __set_errno (EINVAL);
        return -1;
    }

    __set_errno (ENOSYS);
    return -1;
}
libc_hidden_def (__libc_write)
stub_warning (write)

weak_alias (__libc_write, __write)
libc_hidden_weak (__write)
weak_alias (__libc_write, write)

这一切似乎都是在设置errno__libc_write如何写入文件描述符?

【问题讨论】:

  • 嗯,stub_warning 让我觉得这个源代码只是一个 stub 函数...你在哪里找到的?

标签: c unix glibc


【解决方案1】:

您对Cunix 有一些误解。

我认为write 是 Unix 的东西

毫无疑问,writesyscall,它是 POSIX 标准的一部分。 POSIX 是与unix(一个非常古老的操作系统)兼容的标准。

这意味着名为write系统调用 存在于任何unix 或POSIX 兼容(如Linux)操作系统中。但是,如果您没有 C 标准库的实现(如 Linux 中的 glibc 或 Android 中的仿生) - 您将如何进行系统调用(即要求操作系统的内核做某事)?系统调用依赖于体系结构(SPARC、Intel、ARM、PowerPC 等将有不同的实现) - 并且由 C 标准库实现。如果您没有(例如,当您遵守-nostdlib 时,您明确要求不要有 C 标准库) - 您不能调用 write,该函数不存在。但是,您可以使用程序集自己实现它。

您提供的代码用于__libc_write,与write 不同。在glibcgcc 之间发生了一些巫术,这与存根有关,我不完全理解。

简单的实现是这样的:

ssize_t write(int fd, const void *buf, size_t count)
{
    return __set_errno(syscall(__NR_write, fd, buf, count));
}

(在bionic,Android 的 libc 实现中,您可以在此处查看源代码https://searchcode.com/codesearch/view/34924443/ - 看到它是在汇编中实现的)

syscall 函数在 glibc(以及其他任何地方)的汇编中实现:http://code.metager.de/source/xref/gnu/glibc/sysdeps/unix/sysv/linux/x86_64/syscall.S(对于 x86_64)

但是,如果您在致电write 时必须真正知道glibc 中发生了什么,那就有点复杂了。据我了解,它调用_IO_new_file_write(实现here)。 _IO_new_file_write 使用write_not_cancel 宏定义herea macro for INLINE_SYSCALL (write, 3, fd, buf, len),即the implementation 用于调用系统调用并设置errno。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
  • 2012-05-25
  • 2013-12-30
  • 1970-01-01
相关资源
最近更新 更多