Linux系统调用这部分经常出现两个词:libc库和封装函数,不知道你是否清楚它们的含义?
libc
1)libc概念
libc是Stantard C Library的简称,它是符合ANSI C标准的一个标准函数库。libc库提供C语言中所使用的宏,类型的定义,字符串操作符,数学计算函数以及输入输出函数等。正如ANSI C是C语言的标准一样,libc只是一个函数库标准,每个操作系统都会按照该标准对标准库进行具体实现。通常我们所说的libc是特指某个操作系统的标准库,比如:在Linux操作系统下所说的libc即glibc。glibc是类Unix操作系统中使用最广泛的libc库,它的全称是GNU C Library.
2)glibc
类Unix操作系统通常将libc库作为操作系统的一部分,它被视为操作系统与用户程序的接口。libc库不仅实现标准C语言中的函数,而且也包含自己所属的函数接口。比如:在glibc库中,既包含标准C中的fopen(),又包含类Unix系统中的open()。在类Unix操作系统中,如果缺失了标准库,那么整个操作系统将不能正常运转。
3)Window下的libc
与类Unix操作系统不同的是,Windows系统并不将libc库作为整个核心操作系统的一部分。通常,每个编译器都附属自己的libc库,这些libc既可以静态编译到程序中,又可以动态编译到程序中。也就是说,应用程序依赖编译器而不是操作系统。
封装函数
在Linux系统中,glibc库中包含许多API,大多数API都对应一个系统调用,比如:应用程序中使用的接口open(),就对应同名的系统调用open()。在glibc库中,通过封装例程(Wrapper Routine)将API和系统调用关联起来。API是头文件中所定义的函数接口,而位于glibc中的封装例程则是对该API对应功能的具体实现。事实上,我们知道接口open()所要完成的功能是通过系统调用open()完成的,因此封装例程要做的工作就是先将接口open()中的参数复制到相应的寄存器中,然后引发一个异常,从而系统进入内核区执行sys_open(),最后当系统调用执行完毕后,封装例程还要将错误码返回到应用程序中。
需要注意的是,函数库中的API和系统调用并没有一一对应的关系。应用程序借助系统调用可以获得内核所提供的服务,但是,像字符串操作这样的函数并不需要借助内核来实现,因此也就不必与某个系统调用关联。
不过,我们并不是必须通过封装例程才能使用系统调用,syscall()和syscallx()两个函数可以直接调用系统调用。具体的使用方法man手册中已经说明的很清楚了。