7、函数umaskshell
umask函数为进程设置文件模式建立屏蔽字,并返回以前的值,这是少数几个没有出错返回函数中的一个。其中cmask是9个常量(S_IR/W/XUSR、S_IR/W/XGRP、S_IR/W/XOTH)中的若干个按位“或”构成的。函数
#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(void) { umask(0); if(creat("foo", RWRWRW) < 0) { err_sys("create error for foo"); } umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if(creat("bar", RWRWRW) < 0) { err_sys("create error for bar"); } exit(0); }
4-9 umask函数实例ui
UNIX系统的大多数用户从不处理他们的umask值,一般在登陆时,由shell的启动文件设置一次,而后再不改变。用户能够设置umask值以控制他们所建立文件的默认权限。umask的经常使用值:000(任何用户都能读写文件)、002(阻止其余用户写入你的文件)、022(阻止同组成员和其余成员写入你的文件)、027(阻止同组成员写你的文件和其余用户读、写或执行你的文件)。spa
8、函数chmod、fchmod和fchmodatunix
#include <sys/stat.h> int chmod(const char *pathname, mode_t mask); int fchmode(int fd, mode_t mask); int fchmodeat(int fd, char *pathname, mode_t mask); //若成功,返回0;若出错,返回-1
这三个函数使咱们能够更改现有文件的访问权限,为了改变一个文件的权限位,进程的有效用户ID必须等于文件的全部者ID,或者该进程必须具备超级用户权限。还须要注意的是chmode函数更新的知识i节点最近一次被更改的时间。按时间默认方式,ls -l列出的是最后修改文件内容的时间指针
#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("chmode error for foo"); } if(chmod("bar", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { err_sys("chmode error for bar"); } exit(0); }
4-12 chmode函数实例code
9、函数chown、fchown、fchownat和lchownblog
#include <unistd.h> int chown(const char *pathname, uid_t owner, gid_t group); int fchown(int fd, uid_t owner, gid_t group); int fchownat(int fd, const char *pathname, uid_t owner, gid_t group, int flag); int lchown(const char *pathname, uid_t owner, gid_t group);
这四个函数都是用于更改文件的用户ID和组ID,若是两个参数ower和group中的任意一个为-1,则对应的ID不变。lchown和fchownat(设置了AT_SYNLINK_NOFOLLOW)更改符号链接自己,而不是更改符号链接所指向的文件的全部者。进程
10、文件长度和文件截断rem
stat结构成员st_size表示以字节为单位的文件的长度,此字段只对普通文件、目录文件和符号链接有意义。对于普通文件,长度能够为0;对于符号链接,文件长度实在文件名中的实际字节数。现今大多数现代的unix系统提供字段st_blksize和st_blocks。第一个是对文件I/O较合适的快长度;第二个是所分配的实际512字节块块数。咱们说起普通文件能够包含空洞,其实际分配块数可使用du -s来进行查看。
将一个文件截断为0能够在打开时使用O_TRUNC标志,为了阶段文件能够调用函数truncate和ftruncate。若length小于当前文件的长度,则截断;若大于当前文件的长度,则填充0。
#include <unistd.h> int truncate(const char *pathname, off_t length); int ftruncate(int fd, off_t length); //若成功,返回0;若失败,返回-1
11、文件系统
4-13 磁盘、分区和文件系统
咱们能够把一个磁盘分红一个或多个分区。每一个分区能够包含一个文件系统。i节点是固定长度的记录项,它包含大部分信息。
4-14 较详细的柱面组的i节点和数据块
1.途中有两个目录项指向同一个ijiedian。每一个i节点都有一个链接计数,其值是指向该i节点的目录项数,只有当链接计算减小至0时,才可删除该文件。这就是为何解除对一个文件的链接操做并不老是意味着释放该文件占用的磁盘块的缘由。这也是为何删除一个目录项的函数被称之为unlink而不是delete的缘由。
2.另一种链接类型称为符号链接(symbolic link)。符号链接文件的实际内容(在数据块中)包含了该富豪连接所指向的文件的名字。
3.i节点包含了文件有关的全部信息:文件类型、文件访问权限为、文件的长度和只想文件数据块的指针等。可是有两项重要数据存放在目录项中:文件名和i节点编号。
4.i节点编号是指向同一文件系统中相应i节点,一个目录项不能只想另外一个文件系统的i节点,这就是为何lb命令不能跨越文件系统的缘由。
5.当在不更新文件系统地状况下为一个文件重命名时,该文件的实际内容并未移动,只须要构造一个指向现有i节点的新目录项,并删除老目录项,链接技术不会改变。
12、函数link、linkat、unlin、unlinkat和remove
#include <unistd.h> int link(const char *existingpath, const char *newpath); int linkat(int efd, const char *existingpath, int nfd, const char *newpath, int flag); //若成功,返回0;若失败,返回-1
建立一个只想现有文件的链接方法是使用link和linkat函数。当现有文件是符号链接时,有falg参数来控制linkat函数是建立指向现有符号链接的链接仍是建立指向现有符号链接所指向的文件的链接。若是在flag参数中设置了AT_SYMLINK_FOLLOW标志,就建立指向符号链接目标的链接。建立新目录项和增长链接计数应当是一个原子操做。
#include <unistd.h> int unlink(const char *pathname); int unlinkat(int fd, const char *pathname, int flag);
上面两个用于接触对文件的链接,其权限要求:拥有该文件、拥有该目录或者具备超级用户权限。
#include <apue.h> #include <fcntl.h> int main(void) { if(open("tempfile", O_RDWR) < 0) { err_sys("open error"); } if(unlink("tempfile") < 0) { err_sys("unlink error"); } printf("file unlinked\n"); sleep(15); printf("done\n"); exit(0); }
4-16 打开一个文件,而后unlink
unlink的这种特性常常被程序用来确保即便是在程序崩溃时,它所建立的临时文件也不会遗留下来。进程用open或creat建立一个文件,而后当即调用unlink,由于该文件仍旧是打开的,因此不会将其内容删除。只有当进程关闭或终止时,该文件的内容才会被删除。若是pathname是符号链接,那么unlink删除该符号链接,而不是删除由该链接所引用的文件。
咱们也能够用remove函数接触对一个文件或目录的连接。对于文件,remove的功能与unlink相同;对于目录,remove的功能与rmdir相同。
#include<stdio.h> int remove(const char *pathname);