每次写入调用都会切换到内核模式吗?

时间:2018-02-05 13:15:00

标签: linux linux-kernel glibc


我知道打电话给glibc"写"函数调用转到sys_call写函数,这是一个内核函数。
因为sys_call是一个内核函数,所以CPU必须将环更改为零,以存储进程寄存器等等。
但它总是切换到内核模式吗?例如,如果我这样做

write(-1,buffer,LENGTH)

它仍然试图在文件描述符数组中找到它吗? 我在glibc源代码中看到它确实检查了fd> 0但是我没有看到任何跳转到sys_call那里(看起来main()的baracks在调用alias_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)
#include <stub-tag.h>

所以问题是:

  1. glibc实际上在哪里调用sys_write
  2. 如果fd&lt; 0?
  3. ,glibc不会调用sys_write这是真的吗?

1 个答案:

答案 0 :(得分:0)

  

我在glibc源代码中看到它确实检查了fd&gt; 0但是我没有看到任何跳转到那里的sys_call

您正在查看错误的代码。

在不同条件下使用的__libc_write有多种定义。你看过的那个是io/write.c

在Linux上使用实际的那个是从sysdeps/unix/syscall-template.S生成的,而实际上执行切换到内核模式(并返回到用户模式)即使fd==-1等等。