基本的stat结构体的大体组成成员如下:
struct stat
{
mode_t st_mode; //文件类型或文件模式
ino_t st_ino; //目录进入点的inode节点
dev_t st_dev; //系统文件设备
dev_t st_rdev; //特殊文件设备
nlink_t st_nlink; //连接该文件的硬件连接数,刚创建的文件默认为1
uid_t st_uid; //用户id
gid_t st_gid; //用户所在组id
off_t st_size; //文件的大小
time_t st_atime; //文件最后访问时间
time_t st_mtime; //最近修改时间
time_t st_ctime; //i节点状态最后改变时间
blksize_t st_blksize;
blkcnt_t st_blocks;
};
上面结构体包含了文件状态信息。下面看三个获取文件状态信息的函数:
#include <sys/stat.h>
int stat(const char *restrict pathname,struct stat *restrict buf);
int fstat(int fileds,struct stat *buf);
int lstat(const char *restrict pathname,struct stat *restrict buf);
函数成功返回0,失败返回-1;
三者定义上可义看出,fstat是获取已在文件描述符fileds上打开的文件信息。
而lstat可以获取一个符号链接的相关信息,而stat不能。
stat相关函数以及stat结构体在ls -l命令中起了很重要的作用。
文件类型:
linux下包含了很多的文件类型:普通文件、目录文件、块特殊文件、字符特殊文件、FIFO文件、套接字、符号链接。文件类型包含在stat结构体的st_mode成员中。可以用下面的宏确定文件类型,这些宏的参数都是stat结构体中的st_mode成员。
sys/stat.h文件中的宏定义:
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG )
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR )
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK )
#define S_ISCHR (mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK )
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
S_ISREG:普通文件
S_ISDIR:目录文件
S_ISBLK:块设备文件
S_ISCHR:字符特殊文件
S_ISFIFO:管道或FIFO文件
S_ISLNK:符号链接
S_ISSOCK:套接字文件
下面应用这些宏判断输入的文件的文件类型:
int judge_file(const char *pathname)
{
struct stat buf;
char *ptr = NULL;
if (stat(pathname,&buf) < 0)
{
printf("stat failer!\n");
return -1;
}
if (S_ISREG(buf.st_mode))
ptr = "普通文件";
else if (S_ISDIR(buf.st_mode))
ptr = "目录文件";
else if (S_ISCHR(buf.st_mode))
ptr = "字符特殊文件";
else if (S_ISBLK(buf.st_mode))
ptr = "块设备问文件";
else if (S_ISFIFO(buf.st_mode))
ptr = "管道或FIFO文件";
else if (S_ISLNK(buf.st_mode))
ptr = "符号链接";
else if (S_ISSOCK(buf.st_mode))
ptr = "套接字"
else
ptr = "error!";
printf("%s\n",ptr);
return 0;
}
设置用户ID和组ID
实际用户ID、实际组ID标识我们究竟是谁;
有效用户ID、有效组ID以及附加组ID决定了文件的访问权限。
每个文件都有一个所有者,所有者由stat结构中的st_uid表示,组所有者则由st_gid表示。可以用常理S_ISUID和S_ISGID测试。
文件访问权限:
每个文件都有9个访问权限位,分为三类,u表示用户,g表示组,o表示其他。
摘自sys/stat.h
st_mode屏蔽 意义 屏蔽位
S_IRUSR 用户读 0400
S_IWUSR 用户写 0200
S_IXUSR 用户执行 0100
S_IRDRP 组读 0040
S_IWGRP 组写 0020
S_IXGRP 组执行 0010
S_IROTH 其他读 0004
S_IWOTH 其他写 0002
S_IXOTH 其他执行 0001
下面看一个具体的获取文件权限的函数
int get_file_mode(int mode,char *str)
{
strcpy(str, "----------"); /* default=无参数 */
/*获取文件类型*/
if (S_ISDIR(mode))
str[0] = 'd'; /* 目录 */
if (S_ISCHR(mode))
str[0] = 'c'; /* 字符设备 */
if (S_ISBLK(mode))
str[0] = 'b'; /* 块设备 */
/* 用户权限 */
if (mode & S_IRUSR)
str[1] = 'r';
if (mode & S_IWUSR)
str[2] = 'w';
if (mode & S_IXUSR)
str[3] = 'x';
/* 组权限 */
if (mode & S_IRGRP)
str[4] = 'r';
if (mode & S_IWGRP)
str[5] = 'w';
if (mode & S_IXGRP)
str[6] = 'x';
/* 其人的权限 */
if (mode & S_IROTH)
str[7] = 'r';
if (mode & S_IWOTH)
str[8] = 'w';
if (mode & S_IXOTH)
str[9] = 'x';
}
chmod和fchmod函数:更改现有文件的权限:
#include <sys/stat.h>
int chmod(const char *pathname,mode_t mode);
int fchmod(int fileds,mode_t mode);
函数中的mode参数为上面所说的9个类型再加上S_IRWXU、S_IRWXG、S_IRWXO.
S_IRWXU = S_IRUSR | S_IWUSR | S_IXUDR
S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP
S_IRWXO = S_IROTH | S_IWOTH | S_I
读目录:
#include <dirent.h>
DIR *opendir(const char *pathname);成功返回指针
struct dirent *readdir(DIR *dp);
int closedir(DIR *dp)
dirent结构体的定义如下:
struct dirent
{
ino_t d_ino;
char d_name[NAME_MAX+1];
}