系统调用封装函数
本博客主要结合实例讲解下图六个系统调用函数open()、close()、write()、read()、lseek()、stat()。
用户程序可通过调用特定的I/O函数的方式提出I/O请求。
- 在UNIX/Linux系统中,可以是C标准I/O库函数或系统调用的封装函数,前者如文件I/O函数fopen()、fread()、fwrite()和fclose()或控制台I/O函数printf()、putc()、scanf()和getc()等;后者如open()、read()、write()和close()等。
- 标准I/O库函数比系统调用封装函数抽象层次高,后者属于系统级I/O函数。与系统提供的API函数一样,前者是基于后者实现的。
例Linux 系统中printf()的执行过程
标准库函数实际上是对系统调用封装函数的封装,最终也是通过int 0x80 陷入内核
Unix I/O基本概念:
一个linux文件就是一个m字节的序列,所有的I/O设备(例如网络、磁盘、终端)都被模型化为文件,而所有的输入和输出都被当作对相应文件的读和写来执行。这种将设备优雅地映射为文件的方式,允许Linux内核引出一个简单、低级的应用接口,称为Unix I/O,这使得所有的输入和输出都能以一种统一且一致的方式来执行。
-
打开文件。 一个应用程序通过要求内核打开相应的文件,来宣告它想要访问一个I/O设备。内核返回一个小的非负整数,叫做描述符,它在后续对此文件的所有操作中标识这个文件。内核记录有关这个打开文件的所有信息。应用程序只需记住这个描述符。(返回当前最小整数)
-
Linux shell 创建的每个进程开始都有三个打开的文件:标准输入(描述符为0)、标准输出(描述符为1)和标准错误(描述符为2)。头文件<unistd.h>定义了常量STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO它们可用来代替显式的描述符值
10.3 打开和关闭文件
进程是通过调用open函数来打开一个已存在的文件或创建一个新文件的:
open函数
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcnt1.h>
int open(char *filename, int flags, mode_t mode);
返回:若成功则为返回新文件描述符,若出错为-1.
函数说明
- open函数将filename转换为一个文件描述符,并且返回描述符数字。返回的描述符总是在进程中当前没有打开的最小描述符。
- flags参数指明了进程打算如何访问这个文件
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件。
上面三种是互斥的,即不可同时使用
O_CREAT 如果文件不存在则自动建立该文件
O_TRUNC 如果文件已经存在就截断它。 O_TRUNC| O_WRONLY(O_RDWR)一起使用可清空原文件内容, O_TRUNC|O_RDONLY 一起使用不会起作用
O_APPEND 每次写操作前,设置文件位置到文件的结尾处
例: O_TRUNC| O_WRONLY|O_CREAT:文件存在就清空,不存在就创建
- MODE参数指定了新文件的的访问权限位,创建新文件时用mode参数,否则设为0
S_IRUSR, 400权限,代表该文件所有者具有可读取的权限。
S_IWUSR, 200权限,代表该文件所有者具有可写入的权限。
S_IXUSR, 100权限,代表该文件所有者具有可执行的权限。
S_IRGRP, 040权限,代表该文件用户组具有可读的权限。
S_IWGRP, 020权限,代表该文件用户组具有可写入的权限。
S_IXGRP, 010权限,代表该文件用户组具有可执行的权限。
S_IROTH, 004权限,代表其他用户具有可读的权限
S_IWOTH, 002权限,代表其他用户具有可写入的权限。
S_IXOTH, 001权限,代表其他用户具有可执行的权限。
close函数
#include <unistd.h>
int close(int fd)
返回:若成功则为0,若出错则为-1.
例一:
#include "csapp.h"
int main()
{
int fd1,fd2;
fd1 <