本节是记录文件的基本属性,下面给出描述文件属性的三个基本函数:stat,lstat,fstat函数。
/*********************** * 函数功能: * stat函数返回与pathname命名文件的相关信息结构; * fstat函数获取已在描述符filedes上打开的文件信息; * lstat函数获取符号连接的相关信息; * * 返回值:若成功则返回0,若出错则返回-1; * 函数原型: */ int stat(const char *pathname, struct stat *buf); int lstat(const char *pathname, struct stat *buf); int fstat(int filedes, struct stat *buf); /************************** * 参数说明 * pathname 文件名 * filed 文件描述符 * buf 指向buffer的指针 * */
struct stat{ mode_t st_mode; /* file type */ ino_t st_ino; /* i-node number */ dev_t st_dev; /* device number */ dev_t st_rdev; /* device number for special file */ nlink_t st_nlink; /* number of hard link */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group Id of owner */ off_t st_size; /* total size in bytes for regular files */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of 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 change */ };
测试程序:
#include "apue.h" #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> void stat_buf(char*,struct stat *); int main(int argc, char *argv[]) { struct stat buf; if(argc != 2) err_quit("usage: a.out <pathname>"); if(stat(argv[1],&buf) != -1) { stat_buf(argv[1],&buf); } else err_ret("error"); exit(0); } void stat_buf(char *fname,struct stat *buf) { printf("mode: %o\n", buf->st_mode); /*显示文件模式字段*/ printf("links:%d\n", buf->st_nlink); /*显示链接数*/ printf("user : %d\n", buf->st_uid); /*显示用户名ID*/ printf("group : %d\n", buf->st_gid); /*显示组ID*/ printf("size: %d\n", buf->st_size); /*显示文件大小*/ printf("modtime: %d\n", buf->st_mtime); /*显示文件的最后修改时间*/ printf("name:%s\n", fname); /*显示文件名*/ }st_mode 文件类型有以下七种:
/* * S_ISREG 普通文件; * S_ISBLK 块特殊文件; * S_ISCHR 字符特殊文件; * S_ISDIR 目录文件; * S_ISLNK 符号链接; * S_ISFIFO 命令管道; * S_ISSOCK 套接字; */我们可以根据课本给出的例子进行测试,如下:
#include "apue.h" /* * S_ISREG 普通文件; * S_ISBLK 块特殊文件; * S_ISCHR 字符特殊文件; * S_ISDIR 目录文件; * S_ISLNK 符号链接; * S_ISFIFO 命令管道; * S_ISSOCK 套接字; */ 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("last error."); continue; } if(S_ISREG(buf.st_mode)) ptr = "regular file."; else if(S_ISDIR(buf.st_mode)) ptr = "directory file."; else if(S_ISCHR(buf.st_mode)) ptr = "character special file"; else if(S_ISBLK(buf.st_mode)) ptr = "block special file"; else if(S_ISFIFO(buf.st_mode)) ptr = "FIFO file"; else if(S_ISLNK(buf.st_mode)) ptr = "symbolic link file"; else if(S_ISSOCK(buf.st_mode)) ptr = "sock file"; else ptr ="** unknown mode **"; printf("%s\n",ptr); } exit(0); }
/***************************** * 文件访问权限 * st_mode屏蔽 意义 * S_IRUSR 用户-读 * S_IWUSR 用户-写 * S_IXUSR 用户-执行 ***************************** * S_IRGRP 组-读 * S_IWGRP 组-写 * S_IXGRP 组-执行 ***************************** * S_IROTH 其他-读 * S_IWOTH 其他-写 * S_IXOTH 其他-执行 ***************************** */ /***************************** * 新文件和目录的所有权 * 新文件的用户ID设置为进程的有效用户ID; * 新文件的组ID为以下之一: * (1)可以是进程的有效组ID; * (2)可以是所在目录的组ID; * *************************** */
/* access 函数 */ /****************** *功能:按照实际用户ID和实际组ID进行访问权限测试。 * 返回值:若成功则返回0,若出错则返回-1; * 函数原型: * int access(const char *pathname,int mode); **********************/ /********************** *参数说明 *pathname是文件名 *mode是一下常量 *(1)R_OK 测试读权限 *(2)W_OK 测试写权限 *(3)X_OK 测试执行权限 *(4)F_OK 测试文件是否存在 * *********************/ #include "apue.h" #include <fcntl.h> int main(int argc, char*argv[]) { if(argc != 2) err_quit("usage: a.out <pathname>"); if(access(argv[1],R_OK) < 0) err_ret("access error for %s",argv[1]); else printf("read access ok.\n"); if(open(argv[1],O_RDONLY) < 0) err_ret("open error for %s",argv[1]); else printf("open for reading ok.\n"); exit(0); }
《unix高级环境编程》