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);
************************************/