4.文件与目录
4.1stat簇函数
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
int fstatat(int dirfd, const char *pathname, struct stat *buf,int flags);
stat():该函数通过对path的文件属性进行判断,然后将其存储于buf指向的结构体中。
fstat();该函数获得打开的文件描述符fd上的有关信息,存储于buf指向的结构体中。
lstat():如果path是一个符号链接,那么buf所指向的是有关符号链接的有关信息,而不是该符号链接引用的文件信息
fstatat():如果fd参数是AT_FDCWD,并且pathname是一个相对路径名,fstatat会计算相当于当前目录的pathname参数;如果pathname是一个绝对路径,那么fstatat会忽略fd的参数。这两种情况和stat或lstat一样。
如果fd是AT_SYMLINK_NOFOLLOW时,fstatat不会跟随符号链接,只是返回符号链接本身的信息;默认,返回的是符号链接所指向的实际文件的信息。
下面是strut stat的基本形式 ,供大家学习参考。
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
4.2文件类型
常见的文件类型大致有以下几种:
(1)普通文件
(2)目录文件
(3)块特殊文件:提供对设备带缓冲的访问。
(4)字符特殊文件:提供对设备不带缓冲的访问。
(5)FIFO:用于进程间通信。
(6)套接字:用于进程间的网络通信。
(7)符号链接:这种类型的文件指向另一个文件。
如下是stat结构中st_mode的文件类型的宏定义的成员:
4.3设置用户ID和设置组ID
用户ID和组ID
#include <sys/types.h>
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
两个函数分别是设置调用进程的有效uid和gid,如果调用者是root,那么真实的uid和保存的设置用户id也会被设置。
通常,有效用户ID等于实际用户ID,有效组ID等于实际组ID。
可以通过stat函数设置用户id和组id,这两位可分别用常量S_ISUID和S_ISGID。
4.4文件访问权限
st_mode值包含的对文件的访问权限位:
chmod命令用于修改这9个权限位,u表示用户,g表示组,o表示其他。
对于各种权限的实例详解:
1)当为了打开层层目录下的某个文件时,那么该用户必须对层层目录具有执行权限;
2)目录的读权限是允许读目录,获得该目录下的所有文件名的列表;
3)文件的读权限决定了我们是否能打开现有文件进行读操作,这与open函数的O_RDONLY和O_RDWR标志相关;
4)文件的写权限决定了我们是否能打开现有文件进行写操作,这与open函数的O_WRONLY和O_RDWR标志相关;
5)指定open函数的O_TRUNC标志,必须具有写权限;
6)在一个目录下创建一个新文件,那么必须对该目录具有写权限和执行全限;
7)删除一个文件,则必须对包含该文件的目录具有写权限和执行权限;
8)使用exec函数时,必须对该文件具有执行权限。
4.5新文件和目录的组ID
1)新文件的组ID可以是进程的有效组ID;
2)新文件的组ID可以是它所在的目录的组ID.
4.6使用实际用户进行权限测试
#include <unistd.h>
int access(const char *pathname, int mode);
#define _ATFILE_SOURCE
#include <fcntl.h> /* Definition of AT_* constants */
#include <unistd.h>
int faccessat(int dirfd, const char *pathname, int mode, int flags);
其中如果测试文件是否已经存在,mode为F_OK;否则mode是4-7图所列常量的按位或。
下面两种情况上述两个函数相同:
1)pathname参数为绝对路径;
2)dirfd取值为AT_FDCWD,而pathname为相对路径;否则faccessat计算相对于打开目录的pathname。
如果flag设置为AT_EACCESS,访问检查用的是调用进程的有效用户ID和有效组ID。
4.7创建屏蔽字umask
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
umask函数为进程设置文件模式创建屏蔽字,并返回之前的值。
umask默认值为022,因此创建一个新文件的默认权限是0644,其计算公式是
0666 & ~022 = 0644,umaks值是一个八进制数,其umask文件访问权限位如下表所示:
更改打印umask:
4.8更改文件权限
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
chmod():在指定的文件上进行权限操作。
fchmod():对已经打开的文件进行操作。
fchmodat():在以下两种情况和chmod相同:
1)当pathname为绝对路径;
2)dirfd为AT_FDCWD,pathname为相对路径
否则fchmodat计算相对于打开目录的pathname,当flag为AT_SYMLINK_NOFOLLOW标志时,fchmodat不会跟随符号链接。
参数mode的值如下,其是下表所示常量的按位或: