文件系统除了基本的I/O操作外,还有很多特征和性质,比如文件读、写、执行权限,文件所有者、所属组等等。
1. 函数stat、fstat、fstatat、lstat
1.1 定义:
(位于 /usr/include/sys/stat.h,四个函数成功返回0,出错返回-1)
/* Get file attributes for FILE and put them in BUF. */
int stat (const char *__restrict __file,struct stat *__restrict__buf);
/* Get file attributes for the file, device, pipe, or socket
that file descriptor FD is open on and put them in BUF. */
int fstat (int __fd, struct stat *__buf);
/* Similar to stat, get the attributes for FILE and put them in BUF.
Relative path names are interpreted relative to FD unless FD is
AT_FDCWD. */
int fstatat (int __fd, const char *__restrict __file, struct stat *__restrict __buf, int __flag);
/* Get file attributes about FILE and put them in BUF.
If FILE is a symbolic link, do not follow it. */
extern int lstat (const char *__restrict __file, struct stat *__restrict __buf);
1.2 使用:
stat函数的第一个参数为文件的带路径名,stat函数返回此文件的属性-struct stat ,并传递给第二个参数 buf.
fstat函数获得在文件描述符fd上打开文件的属性-struct stat,并传递给第二个参数buf.
fstatat函数为一个相对于当前打开目录(__fd参数指向)的路径名返回文件属性.
lstat函数获取文件属性–struct stat,并传递给参数buf.
1.2.1 结构体stat的定义:
(位于/usr/bits/stat.h,文件权限和文件类型位于st_mode中,由于兼容32位和64位平台原因结构体中多了很多宏)
struct stat
{
__dev_t st_dev; /* Device. */
#ifndef __x86_64__
unsigned short int __pad1;
#endif
#if defined __x86_64__ || !defined __USE_FILE_OFFSET64
__ino_t st_ino; /* File serial number. */
#else
__ino_t __st_ino; /* 32bit file serial number. */
#endif
#ifndef __x86_64__
__mode_t st_mode; /* File mode. */
__nlink_t st_nlink; /* Link count. */
#else
__nlink_t st_nlink; /* Link count. */
__mode_t st_mode; /* File mode. */
#endif
__uid_t st_uid; /* User ID of the file's owner. */
__gid_t st_gid; /* Group ID of the file's group.*/
#ifdef __x86_64__
int __pad0;
#endif
__dev_t st_rdev; /* Device number, if device. */
#ifndef __x86_64__
unsigned short int __pad2;
#endif
#if defined __x86_64__ || !defined __USE_FILE_OFFSET64
__off_t st_size; /* Size of file, in bytes. */
#else
__off64_t st_size; /* Size of file, in bytes. */
#endif
__blksize_t st_blksize; /* Optimal block size for I/O. */
#if defined __x86_64__ || !defined __USE_FILE_OFFSET64
__blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
#ifdef __USE_XOPEN2K8
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
identifier 'timespec' to appear in the <sys/stat.h> header.
Therefore we have to handle the use of this header in strictly
standard-compliant sources special. */
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
# define st_atime st_atim.tv_sec /* Backward compatibility. */
# define st_mtime st_mtim.tv_sec
# define st_ctime st_ctim.tv_sec
#else
__time_t st_atime; /* Time of last access. */
__syscall_ulong_t st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
__syscall_ulong_t st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
__syscall_ulong_t st_ctimensec; /* Nsecs of last status change. */
#endif
#ifdef __x86_64__
__syscall_slong_t __glibc_reserved[3];
#else
# ifndef __USE_FILE_OFFSET64
unsigned long int __glibc_reserved4;
unsigned long int __glibc_reserved5;
# else
__ino64_t st_ino; /* File serial number. */
# endif
#endif
};
2. 文件类型
文件类型包含在stat结构的st_mode成员中。
文件类型 | 宏 |
---|---|
S_ISREG() | 普通文件 |
S_ISDIR() | 目录文件 |
S_ISCHR() | 字符特殊文件 |
S_ISBLK() | 块特殊文件 |
S_ISFIFO() | 管道或FIFO |
S_IFLINK() | 符号链接 |
S_ISSOCK() | 套接字 |
2.1 打印文件类型demo
fileflags.c
#include "apue.h"
int main(int argc, char *argv[])
{
int i;
struct stat buf;
char *ptr;
for(i=1; i<argc;++i){
printf("%s: ",argv[i]);
if (lstat(argv[i], &buf )<0){
err_ret("lstat error");
continue;
}
if (S_ISREG(buf.st_mode))
ptr = "regular";
else if (S_ISDIR(buf.st_mode))
ptr = "directory";
else if ( S_ISCHR(buf.st_mode))
ptr = "character special";
else if (S_ISBLK(buf.st_mode))
ptr = "block special";
else if (S_ISFIFO(buf.st_mode))
ptr = "fifo";
else if( S_ISLNK(buf.st_mode))
ptr = "symbolic link";
else if (S_ISSOCK(buf.st_mode))
ptr = "socket";
else
ptr="** unkown mode **";
printf("%s\n", ptr);
}
exit(0);
}
4. 文件访问权限
st_mode值也包含了对文件的访问权限位,每个文件有9个访问权限位。
st_mode屏蔽 | 含义 |
---|---|
S_IRUSR | 用户读 |
S_IWUSR | 用户写 |
S_IXUSR | 用户执行 |
S_IRGRP | 组读 |
S_IWGRP | 组写 |
S_IXGRP | 组执行 |
S_IROTH | 其他读 |
S_IWOTH | 其他写 |
S_IXOTH | 其他执行 |
5. 函数access和faccessat
用于验证实际用户能否访问给定的文件
5.1 定义
(两个函数的返回值:成功,返回0.出错返回 -1)
#include <unistd.h>
int access(const char *path, int amode);
int faccessat(int fd, const char *path, int amode, int flag);
faccessat与access函数在下面2中情况下是相同的:一种是path参数为绝对路径,另一种是fd参数取值位AT_FDCWD而path参数为相对路径,否则,faccessat计算相对于打开目录(fd参数指向)的path
5.1.2 参数mode取值说明
mode | 说明 |
---|---|
R_OK | 测试读权限 |
W_OK | 测试写权限 |
X_OK | 测试执行权限 |
### 5.2 access函数的使用demo
“`
#include “apue.h”