UNIX环境高级编程-第4章- 文件和目录 - 二

4.8 umask函数

当创建新文件是可以通过umask函数指定文件的访问权限。以下是文件权限值对应的数字:

读R——数字4;

写W——数字2;

执行X——数字1;

 

/************************** 
 * 函数功能:为进程设置文件模式创建屏蔽字,并返回以前的值; 
 * 函数原型: 
 * 
 * mode_t umask (mode_t cmask); 
 * 参数说明 
 * cmask是前面介绍的文件权限的9个值的若干个按位“或”构成,9个权限如下所示: 
 **/  
/***************************** 
 * 文件访问权限 
 * st_mode屏蔽    意义 
 * S_IRUSR       用户-读 
 * S_IWUSR       用户-写 
 * S_IXUSR       用户-执行 
 ***************************** 
 * S_IRGRP       组-读 
 * S_IWGRP       组-写 
 * S_IXGRP       组-执行 
 ***************************** 
 * S_IROTH       其他-读 
 * S_IWOTH       其他-写 
 * S_IXOTH       其他-执行 
 ***************************** 
 */  
/* umask的主要作用是在创建文件时设置或者屏蔽文件的某些权限; 
 * 下面举例子,在创建文件时指定文件的权限属性:mode &(~cmask); 
 * 其中mode 是open或者creat函数的属性参数 
 */  

#include "apue.h"  
#include <fcntl.h>  
  
#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)  
  
int main(void)  
{  
    umask(0);//set the first umask  
    //此时cmask值为000  
    if(creat("umask",RWRWRW) < 0)//creat参数的mode权限值为666  
        err_sys("creat error for umask.");  
    //最后创建成功的文件umask权限属性为mode &(~cmask),即为666  
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);//set the second umask  
    //此时cmask权限值为066  
    if(creat("bar",RWRWRW) < 0)//creat参数mode权限值依然为666  
        err_sys("creat error for bar.");  
    //成功创建的文件bar权限属性为mode &(~cmask),即为600  
    exit(0);  
}  

若成功创建了文件umask和bar,则通过ls-l查看这两个文件的权限属性如下:

-rw-------   bar  

-rw-rw-rw-  umask  


4.9 chmod和fchmod函数

这两个函数是改变文件的权限。

/************************ 
 * 以下的操作必须保证进程的有效用户ID必须等于文件的所有者ID,或者进程必须具有超级用户权限; 
 * 函数功能:改变现有文件的访问权限; 
 * 函数原型: 
 * 
 * int chmod(const char *pathname, mode_t mode); 
 * int fchmod(int filedes, mode_t mode); 
 * 说明: 
 * chmod函数是在指定的文件pathname进行操作; 
 * fchmod 函数是在已打开的文件进行操作; 
 * 参数说明: 
 * mode 为以下权限值: 
 * 
 *********************************** 
 * S_ISUID          设置用户ID 
 * S_ISGID          设置组ID 
 * S_ISVTX          保存正文(粘住性) 
 * ********************************* 
 * S_IRWXU          用户读、写和执行 
 *      S_IRUSR       用户-读 
 *      S_IWUSR       用户-写 
 *      S_IXUSR       用户-执行 
 *********************************** 
 * S_IRWXG          组读、写和执行 
 *      S_IRGRP       组-读 
 *      S_IWGRP       组-写 
 *      S_IXGRP       组-执行 
 *********************************** 
 * S_IRWXO          其他读、写和执行 
 *      S_IROTH       其他-读 
 *      S_IWOTH       其他-写 
 *      S_IXOTH       其他-执行 
 ***************************** 
 */  
//其中缩进的9个权限是前面介绍的文件权限  

下面利用前面创建的文件umask和bar进行权限改变:

#include "apue.h"  
  
int main(void)  
{  
    struct stat buf;  
  
    if(stat("umask",&buf) < 0)  
        err_sys("stat error for umask.");  
    if(chmod("umask",(buf.st_mode & ~S_IXGRP) | S_ISGID) < 0)  
        err_sys("chmod error for umask.");  
  
    if(chmod("bar",S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)  
        err_sys("chmod error for umask.");  
    exit(0);  
}  

最终得到这两个文件的权限如下:

-rw-r--r--  bar  

-rw-rwSrw- umask  

       其中S是ls中组执行权限的表示,修改umask文件时,我们相对于其当前状态设置权限。为此首先要用stat函数获取当前权限属性,然后再进行修改;bar文件不需要stat函数获取当前权限,不管原来的权限如何,都重新设置权限。


4.11 chown、fchown和 lchown函数

更改文件的用户ID和组ID

/******************************************  
 * 函数功能:更改文件用户ID(UID)和组ID(GID)  
 * 返回值:若成功返回0,若出错返回-1;  
 * 函数原型:  
 * int chown(const char *pathname, uid_t owner, gid_t group);  
 * int fchown(int filedes, uid_t owner, gid_t group);  
 * int lchown(const char *pathname, uid_t owner, gid_t group);  
 * 若文件是符号链接时,lchown更改的是符号链接本身的所有者,而不是符号链接所指向的文件;  
 * 其他操作相似;  
 * 若参数owner或group的值为-1时,表示不更改对应的ID;  
 */  

4.12文件长度

     在前面介绍的stat结构体中,其中结构成员st_size表示以字节为单位的文件长度。此字段只对普通文件、目录文件和符号链接有效。

对于普通文件,其长度可为0,读取这种文件时,将得到文件结束(end-of-file)指示。

对于目录文件,其长度通常为一个整数(16或512)的倍数。

对于符号链接,文件长度是文件名中的实际字节数。

4.13 文件截短

      在open函数中有一个参数O_TRUNC是把文件截短为0。这里记录的是另外两种函数:

/********************************* 
 * 函数功能:截短文件长度; 
 * 返回值:若成功则返回0,若出错则返回-1; 
 * 函数原型: 
 * int truncate(const char *pathname, off_t length); 
 * int ftruncate(int filedes, off_t length); 
 * 说明: 
 * length是文件截短后的长度; 
 * 若原始文件长度大于length,则length以外的数据不再访问; 
 * 若原始文件长度小于length,则根据不同的系统增加该文件的长度; 
 *********************************/  

4.14 文件系统

 我们可以把一个磁盘分成一个或多个分区。每个分区可以包含一个文件系统。如下图所示:



上图中三个数据块有相同的inode表面这三个数据互为硬链接。它们存储的数据完全相同,删除其中一个或者两个时,文件仍然存在,除非3个都删除。

关于硬链接和软链接可以参考这一篇文章:http://blog.csdn.net/u012243115/article/details/41983509 。


4.15 link、unlink、remove和rename函数

/********************** 
 * 函数功能:创建一个新目录项newpath,实际上是创建一个硬链接; 
 * 返回值:若成功则返回0,若出错则返回-1; 
 * 函数原型: 
 * int link(const char *existingpath, const char *newpath); 
 * 此函数创建一个新的目录项newpath,引用现有的文件existingpath。 
 * 若newpath已经存在,则返回出错。只创建newpath中的最后一个分量, 
 * 路径中的其他部分应该已经存在。 
 * 

/* 函数功能:删除一个现有的目录项,删除一个硬链接; 
 * 返回值:若成功则返回0,若出错则返回-1; 
 * 函数原型: 
 * int unlink(const char *pathname); 
 * 
 * 此函数删除现有的目录项,并将由pathname所引用文件的链接计数减1(inode减一)。 
 * 如果存在指向该文件的其他链接,则仍然可以通过其他链接访问该文件。 
 * *********************/  

测试:

#include "apue.h"  
#include <fcntl.h>  
  
int main(void)  
{  
    if (open("access.c",O_RDWR) < 0)  
        err_sys("open error.");  
    if (unlink("access.c") < 0)  
        err_sys("unlink error.");  
    printf("file unlink.\n");  
    sleep(15);  
    printf("done.\n");  
    exit(0);  
}  

/******************************* 
 * 函数功能:解除对一个目录或文件的链接,对于文件,remove功能和unlink相同 
 *          对于目录,remove功能和rmdir相同; 
 * 返回值:若成功则返回0,若出错则返回-1; 
 * 函数原型: 
 * int remove(const char *pathname); 
 */ 
 

 /* 函数功能:更改现有文件或目录的名字; 
 * 返回值:若成功则返回0,若出错则返回-1; 
 * 函数原型: 
 * int rename(const char *oldname, const char *newname); 
 ************************************/  


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值