用户空间实现系统调用的两种方式
一种是间接的系统调用:syscall(SYS_xxx); 其中 SYS_xxx 是系统调用号;
另一种是通过API函数,API函数一般会自动调用内核空间中同名的系统调用函数。
举例如下:
#include <syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(void)
{
long ID1,ID2;
ID1=syscall(SYS_getpid);
printf("syscall(SYS getpid)=%ld\n",ID1);
ID2=getpid();
printf("getpid()=%ld\n",ID2);
return(0);
}
编译:[[email protected] linux]# gcc -o syscall.o syscall.c
运行:[[email protected] linux]# ./syscall.o
syscall(SYS getpid)=4710
getpid()=4710
系统调用执行过程示意图如下:
API库函数完全运行在用户空间,很多是由编译器提供的,但库函数归根结底还是要由内核态的系统调用来具体执行和实现。比如:标准C库函数printf()可以被看做是一个通用的输出语句,但它实际做的是将数据转化为符合格式的字符串并且调用系统调用 write()输出这些字符串。这一点可以用strace命令跟踪到。
strace描述如下:
NAME
strace - trace system calls and signals
SYNOPSIS
strace [ -dffhiqrtttTvxx ] [ -acolumn ] [ -eexpr ] ... [ -ofile ] [ -ppid ] ... [ -sstrsize ] [
-uusername ] [ -Evar=val ] ... [ -Evar ] ... [ command [ arg ... ] ]
strace -c [ -eexpr ] ... [ -Ooverhead ] [ -Ssortby ] [ command [ arg ... ] ]