用户空间实现系统调用的两种方式

一种是间接的系统调用: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 ...  ] ]