2016-02-28 63 views
8

我一直在用C/C++编写程序,这些程序使用Linux API并进行诸如fork(),read(),write()等系统调用。现在,我开始怀疑这些库函数是否实际上是系统调用,或者它们是某种包装函数。函数调用像read(),write()在linux中的实际系统调用?

当程序调用write()时真的发生了什么? 这个函数如何与内核交互? 如果这是一个包装,那么我们为什么需要它?

+1

约assenbly阅读你的编译器发出的代码或使用调试器来跟踪什么如何你的程序呢? – MikeCAT

+2

查找简单系统调用包装器的简单方法是使用'man'。第2节包含系统调用,这样'man 2 read'显示出来表明读取确实是一个包装系统调用。 –

回答

6

所有这些功能都是您的二进制链接到的libc.so中的真实用户空间功能。但其中大部分只是系统调用的小包装,它们是用户空间和内核之间的接口(另请参阅syscall(2))。

注意,是纯粹的用户空间函数(如fmod(3))或做除了用户空间的一些事情,调用内核(如execl(3))有自己的联机帮助页在第3节,而功能只是调用内核(如read(2))有他们使用这个简单的代码段2

+0

这是相反的方式。纯粹的包装函数在第2节中。第3节是其余部分。见例如execl(3)和execve(2)。 – a3f

+0

@ a3f这就是他所说的。第2节中的系统调用包装,第3节中的纯用户空间函数。 – EJP

+2

@EJP有人可能会认为第3节中的条目不会调用内核。否则,他们将不得不在第2节中,因为答案当前陈述了“在第2节中调用内核的函数”。 – a3f

1

int main() 
{ 
    int f = open("/tmp/test.txt", O_CREAT | O_RDWR, 0666); 
    write(f, "hello world", 11); 
    close(f); 

    return 0; 
} 

可以使用strace找到二进制文件中使用系统调用:

gcc test.c -o test 
strace ./test 

的结果是这样的:

. 
. 
. 
open("/tmp/test.txt", O_RDWR|O_CREAT, 0666) = 3 
write(3, "hello world", 11)    = 11 
close(3)        = 0 
exit_group(0)       = ? 

fork(),它实际上是围绕clone()系统调用的包装