Advanced Programming in UNIX Environment Episode 15

来源:互联网 发布:半身裙淘宝店好一点 编辑:程序博客网 时间:2024/06/05 05:40

函数stat、fstat、fstatat和lstat

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 *buf);int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);

一旦给出pathname,stat函数将返回与此命名文件有关的信息结构。fstat函数获得已在描述符fd上打开文件的有关信息。lstat函数类似于stat,但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用的文件的信息。
fstatat函数为一个相对于当前打开目录(由fd参数指向)的路径名返回文件统计信息。
文件类型
(1)普通文件

二进制可执行文件是一个例外。为了执行程序,内核必须理解其格式。所有二进制可执行文件都遵循一种标准化的格式,这种格式是内核能够确定程序文本和数据的加载位置。

(2)目录文件
(3)快特殊文件
(4)字符特殊文件
(5)FIFO
(6)套接字
(7)符号链接

#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_ISLINK(buf.st_mode))            ptr="symbolic link";        else if(S_ISSOCK(buf.st_mode))            ptr="socket";        else            ptr="** unknown mode **";        printf("%s\n",ptr);    }    return 0;}

对每个命令行参数打印文件类型
内核进行的测试如下:
(1)若进程的有效用户ID是0(超级用户),则允许访问。
(2)若进程的有效用户ID等于文件所有者ID(也就是进程拥有此文件),那么如果所有者适当的访问权限位被设置,则允许被访问;否则拒绝被访问。
(3)若进程的有效组ID或进程的附属组ID之一等于文件的组ID,那么如果适当的访问权限位被设置,则允许访问;否则拒绝访问。
(4)若其他用户适当的访问权限位被设置,则允许访问;否则拒绝访问。
关于组ID,POSIX.1允许实现选择下列之一作为新文件的组ID。
(1)新文件的组ID可以是进程的有效组ID。
(2)新文件的组ID可以是它所在目录的组ID。
access和faccessat函数是按实际用户ID和实际组ID进行访问权限测试的。

#include <unistd.h>int acess(const char *pathname, int mode);int faccessat(int fd, const char *pathname, int mode, int flag);

如果测试文件是否已存在,mode就为F_OK;否则mode按所示常量的按位或。

mode 说明 R_OK 测试读权限 W_OK 测试写权限 R_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");    }    return 0;}

access函数实例
umask函数为进程设置文件模式创建屏蔽字,并返回之前的值。

#include <sys/stat.h>mode_t umask(mode_t cmask);
#include "apue.h"#include <fcntl.H>#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)int main(int argc, char *argv[]){    umask(0);    if(creat("foo",RWRWRW)<0)    {        err_sys("creat error for foo");    }    umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);    if(creat("bar",RWRWRW)<0)    {        err_sys("creat error for bar");    }    return 0;}

umask函数实例
chmod、fchmod和fchmodat这3个函数是我们可以更改现有文件的访问权限。

#include <sys/stat.h>int chmod(const char *pathname, mode_t mode);int fchmod(int fd, mode_t mode);int fchmodat(int fd, const char *pathname, mode_t mode, int flag);
#include "apue.h"int main(void){    struct stat statbuf;    if(stat("foo",&statbuf)<0)    {        err_sys("stat error for foo");    }    if(chmod("foo",(statbuf.st_mode & ~S_IXGRP)|S_ISGID)<0)    {        err_sys("chmod error for foo");    }    if(chmod("bar", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))    {        err_sys("chmod error for bar");    }    return 0;}

chmod函数实例

原创粉丝点击