start 2017/01/09
Introduction:
文件系统的特性和文件的属性:查询/修改,学习链接,操作文件夹。
4.1 stat, fstat, fstatat and lstat Functions // 很重要
#include< sys/stat.h>
int stat( const char* restrict pathname, struct stat* restrict buf);
int fstat( int fd, struct stat* buf);
int lstat(const char* restrict pathname, struct stat* restrict buf);
int fstatat( int fd, const char* restrict pathname, struct state*
restrict buf, int flag);
RETURN 0 OK -1 ON ERROR
state/lstat:lstat 返回符号链接的信息。
stat/fsat: fstat 需要已经打开的文件描述符
fstatat : flag : 默认是会跟随符号链接, AT_SYSLINK_NOFLLOW 设置后,不会跟踪,返回符号链接的信息。
当fd 设置为AT_FDCWD 而且 文件路径使相对时,相对于当前目录,或者相对于fd所代表的目录。当路径使绝对是fd被忽略。
struct stat
{
mode_t st_mode /* 文件类型 和mode( permissions )*/
ino_t st_ino; /* inode number -inode节点号*/
dev_t st_dev; /* ID of device containing file -文件所在设备的ID*/
dev_t st_rdev; /* device ID (if special file) -设备号,针对设备文件*/
nlink_t st_nlink; /* number of hard links -链向此文件的连接数(硬连接)*/
uid_t st_uid; /* user ID of owner -user id*/
gid_t st_gid; /* group ID of owner - group id*/
off_t st_size; /* total size, in bytes -文件大小,字节为单位*/
struct timespec st_atime; /* time of last access -最近存取时间*/
struct timespec st_mtime; /* time of last modification -最近修改时间*/
struct timespec st_ctime; /* time of last status change - */
blksize_t st_blksize; /* blocksize for filesystem I/O -系统块的大小*/
blkcnt_t st_blocks; /* number of blocks allocated -文件所占块数*/
};
4.6 ownership of new files and directories
USER ID is set to the effective user id of the process. GROUP ID is the effective group id of process or the directory which is being created
4,7 acess and facessat functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<unistd.h>
int access(const char *pathname, int mode); mode={R_OK, W_OK, X_OK}
int faccessat()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.8 umask Function
#include<sys/stat.h>
mode_t umask(mode_t cmask) 返回上次文件模式掩码(previous file mode creation mask)
cmask 被 9 个 常量 按位与(bitwise OR) 比如: S_IRUSR, S_IWUSR。任何在掩码置位都在文件模式被off。
下面是各个Mask bit 位的作用
------------------------------------------------------------------------------------------
Mask bit Meaning
--------------------------------------------------------------------------------------------
0400 user-read / S_IRUSR
0200
0100
0040
0020 group-write / S_IWGRP
0010
0004
0002
0001 other-execute / S_IXOTH
--------------------------------------------------------------------------------
同时 umask 命令直接 umask -S, 输出支持的模式,而octal format 输出否定的模式。
4.9 chmod, fchmod, and fchmodat Function
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<sys/stat.h>
int chmod(const char *pathname, mode_t mode); //默认是AT_SYMLINK_FOLLOW
int fchmod(int fd, mode_t mode); //默认是AT_SYMLINK_FOLLOW
int fchmodat(int fd, const char *pathname, mode_t mode, int flag); 正确执行返回 0, 错误返回 -1
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
主要是fchmodat :1)当fd 被设置为 AT_FDCWD 和pathname是相对位置时 AND pathname 是绝对路径 LIKE chmod
2) 当fd是有效值,并且pathname 是相对位置时, pathname 是相对于fd。
3)flag 是针对 符号链接 默认是FOLLOW。
权限: 当effective user ID 一定要等于 文件所有者 ID, AND 超级用户
所有能改变的模式: 可以用过 逻辑 OR 来实现
-------------------------------------------------------------------------------
mode Description
-------------------------------------------------------------------------------
S_ISUID set-user-ID on execution
S_ISGID set-group-ID on execution
S_ISVTX save-text (sticky bit)
--------------------------------------------------------------------------------
S_IRWXU
S_IRUSR
S_IWUSR
S_IXUSR
S_IRWXG
S_IRGRP
S_IWGRP
S_IXGRP
S_IRWXO
S_IROTH
S_IWOTH
S_IXOTH
-------------------------------------------------------------------------------------------
chmod comand
: 用户可以使用chmod指令去变更文件与目录的权限,设置方式采用文字或数字代号皆可。符号连接的权限无法变更,如果用户对符号连接修改权限,其改变会作用在被连接的原始文件.
-c (changes)/ -v(verbose) : 显示指令的执行过程。
-R 递归处理,将指令目录下的所有文件及子目录一并处理。
--reference = filename: 将指定文件和目录的所属群组全部设成和参考文件和目录的所属群组相同。
chmod -c -- reference=filename filename
NOTE:
在某些系统下,chmod fuction 不能设置 黏贴键。比如 Sofia FreeBSD。必须要有surperusr privileges
当你新创建一个文件的时候,你可以指定新创建文件的组ID,如果组ID不等于有效ID或者user没有超级权限,则它不可以设置组ID
4.11 chown lchown fchown fchownat Functions
#include <unistd.h>
int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int fchownat(int fd, const char *pathname, uid_t owner, gid_t group,
int flag);
int lchown(const char *pathname, uid_t owner, gid_t group); All four return: 0 if OK, -1 on error s
-----------------------------------------------------------------------------------------------
当uid_t 或者 gid_t 等于 -1 的时候 不改变。
chown command:
usage:
-c/-v
--reference=filename
-R
-h 对符号链接的文件做修改,而不更改相关文件 (-dereference 与 -h 相反)
------------------------------------------------------------------------------------------------------::::::::::::::::::::::::::::::::: 上面所述的都是stat->st_mode 的前16位。
4.12 File size
只对普通文件、目录和符号链接有用,普通文件大小可以为零,文件夹是一个数目的整数倍,符号链接的大小是 链接的文件 路径的大小,不带null字符。
保存在st_size。
4.13 hole in a file
普通文件存在空洞,当执行read的时候,当读到空洞的时候(这些都没实际写到磁盘),read返回的是0,正常的I/O读写是通过文件的大小一直读写的
例: wc -c show the number of characters (byte) in the file. cat core > core.copy 被copy的文件存在空洞,但复制过来的文件把空洞的字节写入磁盘并且空洞部分补0。
4.14 file truncation
------------------------------------------------------------------------------------------------
#include<unistd.h>
int truncate(const char *pathname, off_t length)
int ftruncate(int fd, off_t length); return 0 if OK, -1 on error
---------------------------------------------------------------------------------------------------
4.15 File Systems
summary : 理解文件系统结构,知道i - node 和目录条目的区别。
1. 每个i-node 都有很多目录条目指向它,当你删除文件的时候,这个计数等于零的时候删除文件。这个计数用st_nlink表示,最大数被POSIX.1 常量 LINK_MAX表示。ulink 和 delete的区别。这种文件条目被称为硬链接。 hard link.
2. 还有一种称为符号链接,实际存储的时文件的名字(文件类型在i-node 一定是 S_IFLNK)
3. i-node 包含所有文件的信息:文件类型、文件的权限位(bits)、文件的大小、指针(指向实际的文件数据块)等等。大部分stat 结构体信息都被包含在i-node。只有两样被包含在目录条目中:文件名和i-node number, i-node的数据类型 是 ino_t。
4.因为I-node number 指向的是同一系统下的i-node,一个目录条目不能指向一个不是同一个文件系统的i-node节点。COmmand: ln
5.对文件重命名(不改变文件系统),实际的文件内容不必移动,只有添加一个目录条目指向存在的i-node,删除旧的文件条目。Command: mv
以上所说的是针对普通文件。对于diretory.刚开始创建时文件类型是“directory” 和一个连接计数。每一个subdirectory都会造成link count++.
4.16 link linkat ulink ulinkat and remove Functions
1.
---------------------------------------------------------------------------------------------------------------------
#include<unistd.h>
int link(const char *existingpath, const char *newpath);
int linkat(int efd, const char *existingpath, int nfd, const char* newpath, int flag); return 0 if ok -1 on error
------------------------------------------------------------------------------------------------------------------------
几点注意:1.创建新的文件条目引用已存的文件。2. 如果newpath 已经存在,则 an error is return. 2. 只有newpath路径最后一个文件名才会被创建,其他必须要存在。3. 创建新的文件条目和增加link count 的数目必须是原子操作。3. 要求路径都在同一文件系统下,尽管POSIX.1允许一种实现支持跨文件系统。如果允许支持创建文件夹硬链接,则权限只能是root
2. unlink unlinkat
--------------------------------------------------------------------------------------------------------------------------
#include<unistd.h>
int unlink(const char *pathname);
int unlink(int fd, const char *pathname, int flag); return 0 if ok -1 on error
------------------------------------------------------------------------------------------------------------------------------------
当有错误返回时候,文件不会改变。正如前面所提及的,当我们要删除一个文件的时候,我们要有这个文件所处的文件夹的写和执行的权利。当sticky键被设置的时候,我们有写的权限,同时也要符合以下标准:1.拥有这个文件,2.拥有这个文件夹,3.有超级权限。
只有当link count 等于零的时候,文件内容才会被删除,一种例外,当一些进程打开了文件。先检查有几个进程拥有file id ,然后在检查 link count。
通过案例发现我正在删除的进程没有close fd,则文件不会删除,等到进程被终结了才会删除文件。因为close fd 和终结进程都会让内核关闭文件,只有内核关闭所有打开的文件,才会删除文件。
当文件是一个符号链接时,ulink只会删除符号链接,不会删除符号链接的文件内容,也没有一个函数会删除一个符号链接引用的文件。
超级用户可以ulink一个文件夹,当文件系统支持这个特性。当时可以用 rmdir 代替 unlink 函数
3. 我们可以使用remove去ulink 一个文件和文件夹,对于一个文件,remove = unlink, 对于一个文件夹,remove = rmdir
-----------------------------------------------------------------------------------------------------------------------------------------------------------
#include<stdio.h>
int remove(const char *pathname); return 0 if ok -1 on error
---------------------------------------------------------------------------------------------------------------------------------------------------------------
4.17 rename renameat //处理file, symbol file, directory。ISO C 只支持file, POSIX.1扩展了。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<stdio.h>
int rename(const char* oldname, const char* newname);
int rename(int oldfld, const char *oldname, int newfd, const char* oldname);
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Condition:当我们rename一个文件或者文件夹的时候,如果newname存在,且newname不是指向一个文件夹的时候,这个newname的文件是被remove,the oldname 被重名为newname。权限:我们必须要有new和old文件夹写的权限。
Condition:当rename一个文件夹的时候,如果newname存在,且必须指向一个文件夹,并且文件夹是空的(only contain dot and dot-dot), remove newname ; oldname is rename to newname。Additionally, the newname cannot contain a path prefix that names oldname.
Condition:不管newname或者oldname指向一个符号链接,then the link itself is processed not the file to which it resolves.
4.18 symbol links
突破硬链接的限制,可以跨文件系统
4.19 file time
主要介绍了last - access time , last - modification time, last - change time of i -node status
4.20 futimens utimesat utimes functions
主要是修改acess time 和 modification time.
4.21 mkdir, mkdirat, and rmdir functions
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<sys/stat.h>
int mkdir(const char *pathname, mode_t mode);
int mkdirat(int fd, const char *pathname, mode_t mode);
int rmdir(const char *pathname); //移除空文件夹 return 0 if ok -1 on error
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.22 reading directories
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<dirent.h>
DIR *opendir(const char *pathname);
DIR *fdopendir(int fd); // return pointer if ok NULL on error
struct dirent * readdir(DIR *dp); // return pointer if OK, NULL at end of directory or error
void rewinddir(DIR *dp);
int closedir(DIR *dp);
long telldir(DIR *dp);
void seekdir(DIR *dp, long loc);
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
详情请见案例
4.23 chdir, fchdiir and getcwd functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<unistd.h>
int chdir(const char *pathname);
int fchdir(int fd); return 0 if ok -1 on error
char *getcwd(const char* buf, size_t size) return buf if ok -1 on error
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在程序中被调用,但是不会改变shell的当前工作路径。并且chidr 跟踪 符号链接。
4.24 device special files
在第18.9章时,我们写ttyname function 时,我们会使用 st_dev 和 st_rdev。
主要介绍了不同文件系统挂载在不同设备上,设备major and minor device numbers
4.26 Summary of file access permission bits
总结之前学过的几个结构:
struct stat stat function get
mode_t st_mode
sticky bit: (mode_t )删除一个文件要有它的写权限(包含关系,你拥有文件夹的写权限,就有对目录项的删除权限,一种包含关系)。sticky bit 是使用户有对文件夹的写权限,
同时取消掉用户对文件夹下的文件删除的权限。必须要有文件目录的写权限同时还拥有该文件。或者拥有文件夹(很容易理解,文件夹包含文件),和超级用户
file type: 7中文件类型, S_IFMT & st_mode 判断是那种文件类型
set-usr-id
set-group-id: 有效用户flag chmod
st_uid , st_gid 为用户的实际用户id和组id
st_nlink 硬链接数量