程序15-8 linux/lib/open.c


  1 /*

  2  *  linux/lib/open.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #define __LIBRARY__

  8 #include <unistd.h>       // Linux标准头文件。定义了各种符号常数和类型,并声明了各种函数。

                              // 如定义了__LIBRARY__,则还含系统调用号和内嵌汇编_syscall0()等。

  9 #include <stdarg.h>       // 标准参数头文件。以宏的形式定义变量参数列表。主要说明了-

                              // 类型(va_list)和三个宏(va_start, va_argva_end),用于

                              // vsprintfvprintfvfprintf函数。

 10

    //// 打开文件函数。

    // 打开并有可能创建一个文件。

    // 参数:filename - 文件名;flag - 文件打开标志;...

    // 返回:文件描述符,若出错则置出错码,并返回-1

    // 13行定义了一个寄存器变量res,该变量将被保存在一个寄存器中,以便于高效访问和操作。

    // 若想指定存放的寄存器(例如eax),那么可以把该句写成“register int res asm("ax");”。

 11 int open(const char * filename, int flag, ...)

 12 {

 13         register int res;

 14         va_list arg;

 15

    // 利用va_start()宏函数,取得flag后面参数的指针,然后调用系统中断int 0x80,功能open进行

    // 文件打开操作。

    // %0 - eax(返回的描述符或出错码)%1 - eax(系统中断调用功能号__NR_open)

    // %2 - ebx(文件名filename)%3 - ecx(打开文件标志flag)%4 - edx(后随参数文件属性mode)

 16         va_start(arg,flag);

 17         __asm__("int $0x80"

 18                 :"=a" (res)

 19                 :"" (__NR_open),"b" (filename),"c" (flag),

 20                 "d" (va_arg(arg,int)));

    // 系统中断调用返回值大于或等于0,表示是一个文件描述符,则直接返回之。

 21         if (res>=0)

 22                 return res;

    // 否则说明返回值小于0,则代表一个出错码。设置该出错码并返回-1

 23         errno = -res;

 24         return -1;

 25 }

 26