我一直在用C/C++编写程序,这些程序使用Linux API并进行诸如fork(),read(),write()等系统调用。现在,我开始怀疑这些库函数是否实际上是系统调用,或者它们是某种包装函数。函数调用像read(),write()在linux中的实际系统调用?
当程序调用write()时真的发生了什么? 这个函数如何与内核交互? 如果这是一个包装,那么我们为什么需要它?
我一直在用C/C++编写程序,这些程序使用Linux API并进行诸如fork(),read(),write()等系统调用。现在,我开始怀疑这些库函数是否实际上是系统调用,或者它们是某种包装函数。函数调用像read(),write()在linux中的实际系统调用?
当程序调用write()时真的发生了什么? 这个函数如何与内核交互? 如果这是一个包装,那么我们为什么需要它?
所有这些功能都是您的二进制链接到的libc.so
中的真实用户空间功能。但其中大部分只是系统调用的小包装,它们是用户空间和内核之间的接口(另请参阅syscall(2)
)。
注意,是纯粹的用户空间函数(如fmod(3)
)或做除了用户空间的一些事情,调用内核(如execl(3)
)有自己的联机帮助页在第3节,而功能只是调用内核(如read(2)
)有他们使用这个简单的代码段2
:
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()
系统调用的包装
约assenbly阅读你的编译器发出的代码或使用调试器来跟踪什么如何你的程序呢? – MikeCAT
查找简单系统调用包装器的简单方法是使用'man'。第2节包含系统调用,这样'man 2 read'显示出来表明读取确实是一个包装系统调用。 –