8第八章 系统调用
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
打开文件的内核数据结构
第八章 系统调用----文件 文件I/O 系统调用 文件
进程文件描述符表 打开标志 fd 0: : fd 1: : fd 2: : fd 3: :
...
内核文件表
v节点表 节点表
文件指针 打开方式 读写指针 V节点指针 打开方式 读写指针 V节点指针 i节点信息 V节点信息 文件长度等 i节点信息 V节点信息 文件长度等
第八章 系统调用----文件属性和目录 文件属性和目录 系统调用
文件的权限
9个普通权限位
S_IRUSER, S_IWUSER, S_IXUSER //用户权限位 S_IRGRP, S_IWGRP, S_IXGRP //用户组权限位 S_IROTH, S_IWOTH, S_IXOTH //其他用户权限位
st_nlink; //链接数 st_uid; st_gid; //文件所有者的用户ID //文件所有者的组ID
第八章 系统调用----文件属性和目录 文件属性和目录 系统调用
off_t time_t time_t time_t } st_size; //文件长度(字节数),普通文件
st_atime; //最后一次访问的时间 st_mtime; //最后一次修改文件内容的时间 st_ctime; //最后一次修改文件属性的时间
open(pathname, O_WRONLY|O_CREAT|O_TRUNC, mode) 语义上creat简单,涉及原子操作,应当使用open.
第八章 系统调用----文件 文件I/O 系统调用 文件
close
#include <unistd.h> int close(int filedes) 返回值:若成功,返回0,出错返回-1 filedes,文件描述符 filedes 进程终止时,内核自动关闭其打开的所有文件
第八章 系统调用----文件 文件I/O 系统调用 文件
write
将数据写入已打开的文件,自动移动文件读写指针. #include <unistd.h> ssize_t write(int filedes, void *buff, size_t nbytes) ssize_t 通常是整型,size_t通常是无符号整型. size_t filedes 文件描述符 buff 存放数据的缓冲区 nbytes 需要写入的字节数 返回值:实际写入的字节数.正常写入时,返回值等于nbytes; 磁盘空间满时,小于nbytes(这种情况也可以认为是出错); 出错返回-1
第八章 系统调用
第八章 系统调用----文件 文件I/O 系统调用 文件
一,文件I/O
1.1引言
基本文件I/O函数:open,creat,read,write,lseek,close 术语:不带缓冲的I/O(指每一个read,write都调用内核中的 一个系统调用),低级例程.
1.2文件描述符
一个非负的整数,一个结构数组的下标,进程打开的文件表项 的下标. open,creat函数会返回一个文件描述符
函数
#include <sys/stat.h> int stat(const char *pathname, struct stat *buf) int fstat(int filedes, struct stat *buf)
第八章 系统调用----文件属性和目录 文件属性和目录 系统调用
文件类型
3个特殊权限位(针对可执行文件)
S_ISUID 执行时设置有效用户ID,如passwd命令文件 S_ISGID 执行时设置有效用户组ID S_SVTX 第一次执行时,保存正文,即常驻内存.
函数
int chmod(const char *pathname, mode_t mode) int fchmod(int filedes, mode_t mode)
fd 0: : fd 1: : fd 2: : fd 3: : fd 4: :
...
不同进程打开相同文件的情况
第八章 系统调用----文件 文件I/O 系统调用 文件
进程文件描述符表 打开标志 fd 0: : fd 1: : fd 2: : fd 3: :
...
内核文件表
v节点表 节点表
文件指针 打开方式 读写指针 V节点指针 打开方式 读写指针 V节点指针 i节点信息 V节点信息 文件长度等 i节点信息 V节点信息 文件长度等
二,文件属性和目录
文件属性
属性结构
struct stat { mode _t ino_t dev_t dev_t nlink_t uid_t gid_t st_mode; //文件类型和权限 st_ino; st_dev; st_rdev; //i节点号 //文件系统设备号(磁盘和分区) //设备文件的设备号
第八章 系统调用----文件 文件I/O 系统调 文件
read
从已打开的文件中读取数据,自动移动文件读写指针. #include <unistd.h> ssize_t read(int filedes, void *buff, size_t nbytes) ssize_t 通常是整型,size_t通常是无符号整型. size_t filedes 文件描述符 buff 存放数据的缓冲区 nbytes 需要读取的字节数 返回值:实际读取的字节数.正常读取时,返回值等于nbytes; 遇到文件结束时,小于nbytes;出错返回-1
第八章 系统调用----文件 文件I/O 系统调用 文件
creat
#include <fcntl.h> int creat(const char *pathname, mode_t mode) 返回值:若成功,返回非负整数,即文件描述符.出错返回-1 pathname,常量,文件名,绝对路径或相对路径均可. pathname mode,指定新建文件的访问权限. 若原有文件存在,则原有文件的属性和内容将会被覆盖. 等价于
第八章 系统调用----文件 文件I/O 系统调用 文件
进程文件描述符表 打开标志 fd 0: : fd 1: : fd 2: : … 读写指针 V节点指针 文件指针 打开方式 读写指针 V节点指针 打开方式 i节点信息 V节点信息 文件长度等 i节点信息 V节点信息 文件长度等 内核文件表 v节点表 节点表
#include <sys/stat.h> mode_t umask(mode_t mode)
umask函数设置当前屏蔽字,返回以前的屏蔽字.
第八章 系统调用----文件属性和目录 文件属性和目录 系统调用
普通文件操作函数
# include <unistd.h> int link(const char *existingpath, const char *newpath) 创建 一个新的目录项newpath,指向一个现有的文件existingpath. int unlink(const char *pathname) 删除一个目录项,对应文件 的链接数减1. #include <stdio.h> int remove(const char *pathname) 删除一个文件或目录的链 接. int rename(const char *oldname, const char *newname) 文 件或目录更名
例2 多个进程创建可能重名的临时文件
有问题的代码:
if (open(tmpfile, O_WRONLY)<0) creat(tmpfile, mode)
正确的做法:
open(tmpfile, O_CREAT|O_WRONLY|O_TRUNC, mode)
做好的做法是保证没有重名的临时文件.
第八章 系统调用----文件属性和目录 文件属性和目录 系统调用
第八章 系统调用----文件 文件I/O 系统调用 文件
进程文件描述符表 打开标志 fd 0: : fd 1: : fd 2: : … 文件实体 文件指针 文件实体 内核文件表
----简单理解 简单理解
惯例:文件描述符0,1,2默认打开,分别对应于标准输入 (键盘),标准输出(显示器),标准错误输出(显示器)文 件.在<unistd.h>中定义为STDIN_FILENO,STDOUT_FILENO, STDERR_FILENO
重定向
dup2(3,0) 将文件描述符表中的表项3复制给表项0 ----标准输入重 定向 dup2(3,1) 将文件描述符表中的表项3复制给表项1 ----标准输出重 定向
第八章 系统调用----文件 文件I/O 系统调用 文件
dup2
#include <unistd.h> int dup2(int filedes1, int filedes2) 将文件描述符filedes1的表项复制给filedes2的表项.如果 filedes2已经打开,则先将其关闭. 返回值:正常返回filedes2,出错返回-1
fd 0: : fd 1: : fd 2: : fd 3: :
...
进程复制自己(fork)之后的情况
第八章 系统调用----文件 文件I/O 系统调用 文件
进程文件描述符表 打开标志 fd 0: : fd 1: : fd 2: : fd 3: :
...
内核文件表
v节点表 节点表
文件指针 打开方式 读写指针 V节点指针 i节点信息 V节点信息 文件长度等
第八章 系统调用----文件 文件I/O 系统调用 文件
lseek
移动文件"读写指针"(或称"文件偏移量").读写操作会 自动移动文件读写指针. #include <unistd.h> off_t lseek(int filedes, off_t offset, int whence) off_t 与系统有关,通常是长整型 filedes 文件描述符 whence 移动偏移量的方式.0:绝对方式;1:相对方式;2: 相对文件尾部 offset 移动的距离,非绝对方式移动时,可以为负. 返回值:新的文件偏移量.
第八章 系统调用----文件 文件I/O 系统调用 文件
原子操作
例1 多个进程添写同一个日志文件
有问题的代码:
lseek(fd, 0L, 2) write(fd, buf, nbytes)
正确的做法:
open时,使用O_APPEND选项 write时,不需要调用lseek,直接写.
第八章 系统调用----文件 文件I/O 系统调用 文件
类型:普通文件,目录文件,字符设备文件,块设备文件, FIFO,符号链接,套接字 判断文件类型
S_ISREG(mode_t mode) //是否普通文件 S_ISDIR(mode_t mode) //是否目录文件
S_ISCHR(mode_t mode) //是否字符设备文件 S_ISBLK(mode_t mode) //是否块设备文件 S_ISFIFO(mode_t mode) //是否管道文件 S_ISLNK(mode_t mode) //是否符号链接 S_SOCK(mode_t mode) //是否套接字
第八章 系统调用----文件 文件I/O 系统调用 文件
open
#include <fcntl.h> int open(const char *pathname, int oflag, [mode_t mode]) 返回值:若成功,返回非负整数,即文件描述符.一定是当前 "进程文件描述符表"中最小未使用的描述符.出错返回-1. pathname,常量,文件名,绝对路径或相对路径均可. oflag,打开方式选项.O_RDONLY,O_WRONLY,O_RDWR 三者必须选其一.O_CREAT,O_APPEND,O_TRUNC等任意 选择.多个选项进行"或"运算构成oflag选项. mode,仅当oflag具有O_CREAT选项时,需要此参数,用于指 定新建文件的访问权限.
第八章 系统调用----文件属性和目录 文件属性和目录 系统调用
第八章 系统调用----文件属性和目录 文件属性和目录 系统调用
创建新文件
新文件的用户ID,组ID等于创建进程的有效用户ID和组ID 新文件的权限由指定权限和屏蔽字共同决定.
指定权限,open和creat函数中给出的权限. 屏蔽字(umask值),被umask屏蔽的权限位即使在open或creat 中指定了也会被屏蔽掉.