20145306《信息安全系统设计》第九周学习总结
教材内容总结
Unix I/O
一个Unix文件就是一个m个字节的序列,所有的I/O设备,都被模型化为文件,而所有的输入输出都被当作对相应文件的读和写来执行,Unix内核引出一个简单、低级的应用接口:Unix I/O。
所有的输入输出都能以一种统一且一致的方式来执行: 打开文件:一个应用程序想访问I/O设备时会要求内核打开相应的文件,内核返回一个小的非负整数,叫做描述符。 它在后续对此文件的所有操作中标识这个文件。内核记录有关这个文件的所有信息,应用程序只需记住描述符。 每个进程开始时都有三个打开的文件:标准输入(描述符为0)、标准输出(描述符为1)、标准错误(描述符为2)
改变当前的文件位置:对于每个打开的文件,内核保持着一个文件位置k,初始为0,文件位置是从文件开头起始的字节偏移量。 应用程序能够通过执行seek操作,显示的设置文件的当前位置为k。
读写文件:读操作是从文件拷贝n>0个字节到存储器,从当前位置k开始,将k增加到k+n 当k>=m时执行读操作会触发一个称为end-of-file(EOF)的条件,应用程序能检测到这个条件。 写操作就是从存储器拷贝n>0个字节到一个文件,从当前位置k开始,然后更新k。
关闭文件:当应用完成对文件的访问,会通知内核关闭文件。 作为响应,内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中。 无论进程因何种原因终止,内核都会关闭所有打开的文件并释放他们的存储器资源。
打开和关闭文件
通过调用open函数来打开一个已存在的文件或创建一个新文件:
#include #include #include
int open(char *filename,int flags,mode_t mode);
返回:若成功则为新文件描述符,若出错为-1 open函数将filename转换为一个文件描述符并返回。
flags指明了进程打算如何访问这个文件:
O_RDONLY:只读 O_WRONLY:只写 O_RDWR:可读可写
flags参数也可以是一个或更多位掩码的或:
O_CREAT:如果文件不存在就创建一个截断的(空)文件 O_TRUNC:如果文件已经存在,就截断它。 O_APPEND:每次写操作前,设置文件位置到文件的结尾处。
每个进程都有一个umask,是通过调用umask函数来设置的。当进程通过带某个mode参数的open函数调用来创建一个新文件时,文件的访问权限位被设置为mode & ~umask
进程通过调用close函数关闭一个打开的文件:
#include
int close(int fd);
返回:若成功则为0,若出错则为-1
读和写文件
应用程序是通过分别调用read和write函数来执行输入输出的:
#include
ssize_t read(int fd,void *buf,size_t n);
返回:若成功则为读的字节数,若EOF则为0,若出错为-1
ssize_t write(int fd,const void *buf,size_t n);
返回:若成功则为写的字节数,若出错则为-1
read函数从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。
write函数从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。
在某些情况下,read和write传送的字节比应用程序要求的要少,这些不足值不表示有错误,原因如下:
读时遇到EOF
从终端读文本行
读和写网络套接字(socket)
遇到的问题和解决过程:
找不到csapp.h:csapp.h是一堆头文件的打包,将其换成stdio.h unistd.h fcntl.h就可以编译了。