APUE读书笔记: 文件和目录

stat, fstat, fstatat 和 lstat函数:

  1. stat函数返回与pathname命名文件相关的信息结构;
  2. fstat函数返回已在文件描述符fd打开文件的相关信息;
  3. lstat函数与stat函数类似,但当命名文件是一个符号链接时,返回该符号链接的相关信息;
  4. fstatat函数为相对于当前打开目录(有fd参数指向)的路径名返回文件统计信息。
  5. struct stat 的具体定义如下图:

文件类型:

  1. 文件类型包括:普通文件,目录文件,块特殊文件,字符特殊文件,FIFO,套接字和符号链接,文件类型由stat结构中的st_mode表示;
  2. 对每个命令行参数打印文件类型:

 1 #include "apue.h"
 2
 3 int main(int argc, char *argv[])
 4 {
 5     int                i;
 6     struct stat        buf;
 7     char             *ptr;
 8
 9     for (i = 1; i < argc; i++)
10     {
11         printf("%s: ", argv[i]);
12         if (lstat(argv[i], &buf) < 0)
13         {
14             err_ret("lstat error");
15             continue;
16         }
17
18         if (S_ISREG(buf.st_mode))
19         {
20             ptr = "regular";
21         }
22         else if (S_ISDIR(buf.st_mode))
23         {
24             ptr = "directory";
25         }
26         else if (S_ISCHR(buf.st_mode))
27         {
28             ptr = "character special";
29         }
30         else if (S_ISBLK(buf.st_mode))
31         {
32             ptr = "block special";
33         }
34         else if (S_ISFIFO(buf.st_mode))
35         {
36             ptr = "fifo";
37         }
38         else if (S_ISLNK(buf.st_mode))
39         {
40             ptr = "symbolic link";
41         }
42         else if (S_ISSOCK(buf.st_mode))
43         {
44             ptr = "socket";
45         }
46         else {
47             ptr = "** unknown mode **";
48         }
49
50         printf("%s\n", ptr);
51     }
52
53     exit(0);
54 }

设置用户ID和设置组ID:

  1. 实际用户ID和实际组ID登陆时取自登陆口令;有效用户ID和有效组ID以及附属组ID决定文件访问权限;保存的设置用户ID和保存的设置组ID在执行程序时包含了有效用户ID和有效组ID的副本;
  2. 通常,有效用户ID等于实际用户ID,有效组ID等于实际组ID;
  3. 设置用户ID(set-user-id):当执行此文件时,将进程的有效用户ID设置为文件所有者的用户ID;设置组ID(set-group-id):当执行此文件时,将进程的有效组ID设置为文件所有者的组ID。

新文件和目录的所有权:

  1. 新文件的用户ID设置为进程的有效用户ID;
  2. 对于Linux 3.2.0,默认情况下,新文件的组ID取决于它所在的目录的设置组ID位是否被设置,如果被设置,新文件组ID设置为目录的组ID,否则设置为进程的有效组ID。

函数access和faccessat:

  1. access和faccessat函数是按实际用户ID和实际组ID进行访问权限测试的;
  2. access函数实例:

 1 #include "apue.h"
 2 #include <fcntl.h>
 3
 4 int main(int argc, char *argv[])
 5 {
 6     if (argc != 2)
 7     {
 8         err_quit("usage: a.out <pathname>");
 9     }
10
11     if (access(argv[1], R_OK) < 0)
12     {
13         err_ret("access error for %s", argv[1]);
14     }
15     else
16     {
17         printf("read access ok\n");
18     }
19
20     if (open(argv[1], O_RDONLY) < 0)
21     {
22         err_ret("open error for %s", argv[1]);
23     }
24     else
25     {
26         printf("open for reading ok\n");
27     }
28
29     exit(0);
30 }

 函数umask:

  1. umask函数为进程设置文件模式创建屏蔽字;
  2. 在文件模式创建屏蔽字中为1的位,在文件mode中相应位一定被关闭(异或);
  3. umask函数实例:

 1 #include "apue.h"
 2 #include <fcntl.h>
 3
 4 #define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
 5
 6 int main(void)
 7 {
 8     umask(0);
 9     if (creat("foo", RWRWRW) < 0)
10     {
11         err_sys("creat error for foo");
12     }
13
14     umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
15     if (creat("bar", RWRWRW) < 0)
16     {
17         err_sys("creat error for bar");
18     }
19
20     exit(0);
21 }

 函数chmod, fchmod和fchmodat:

  1. chmod, fchmod和fchmodat用于更改文件的访问权限;
  2. chmod实例函数:

 1 #include "apue.h"
 2
 3 int main(void)
 4 {
 5     struct stat statbuf;
 6
 7     if (stat("foo", &statbuf) < 0)
 8     {
 9         err_sys("stat error for foo");
10     }
11
12     if (chmod("foo", (statbuf.st_mode & ~S_IXGRP | S_ISGID)) < 0)
13     {
14         err_sys("chmod error for foo");
15     }
16
17     if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
18     {
19         err_sys("chmod error for bar");
20     }
21
22     exit(0);
23 }

时间: 2024-10-13 11:44:18

APUE读书笔记: 文件和目录的相关文章

apue读书笔记之apue.h的设置

apue读书笔记之apue.h的设置 学习apue时,程序都有一个共同的头文件apue.h.那么该如何设置呢?本文是apue版本为第三版. 首先去图书官方网址下载对应的源码tar包.地址为:http://www.apuebook.com/code3e.html 解压tar包. cp  apue.3e/include/apue.h  /usr/include cp  apue.3e/lib/error.c     /usr/include

《UNIX环境高级编程》读书笔记 —— 文件 I/O

一.打开或创建一个文件 #include <fcntl.h> int open(const char *pathname, int oflag, .../*mode_t mode*/); 返回值:若成功则返回文件描述符,若出错则返回-1 oflag选项: O_RDONLY O_WRONLY O_RDWR 以上三个常量中必须指定一个,且只能指定一个. 以下常量都是可选的: O_APPED     每次写时追加到文件尾 O_CREAT     若文件不存在,则创建 O_EXCL      若同时指

APUE读书笔记:关于sigsuspend

sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型. int sigsuspend(const sigset_t *mask); 先忽略参数,sigsuspend完成的操作是阻塞进程的运行,直到有信号的产生.这样来看与另一个函数的作用相同.pause() 加上参数来理解,sigsuspend完成的操作是阻塞进程的运行,如果信号是mask参数设置的信号集,那么该信号是pending状态,而不会影响进程的阻塞状态,意思是进程仍然在阻塞中,直到不在信号集中的信号出现,进

APUE读书笔记-第四章 文件和目录

到第四章了,不知什么时候才能把这本书看完,耽误的时间太多了. 第四章是在第三章的基础上,主要描述文件系统的其他性质和文件的性质. 4.2 stat.fstat.fstatat.lstat函数 首先来看看这四个函数的原型: #include <sys/stat.h> ///usr/include/x86_64-linux-gnu/sys/ int stat (const char *__restrict __file, struct stat *__restrict __buf) int fst

APUE读书笔记-第三章 文件I/O

今天看得挺快的,一下子就把第二章看完了,不过第二章也确实看得不仔细,这一章其实在程序设计中还是非常重要的,因为这一章的内容决定了程序的可移植性. 好了,回到这一章的主题文件I/O. 3.2节主要对文件描述符的概念进行了简单的介绍.根据APUE:文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符.我也简单地翻了一下LKD和<深入理解linux内核>,其中对于文件描述符的讲解不是很多,所以对于文件描述符也谈不出来太深入理解,各大家还是分享一篇blog吧.

APUE读书笔记-第六章 系统数据文件和信息

昨天看完了,今天来看看第六章.感觉第六章的内容不是非常重要.简单看看吧 6.2 口令文件 口令文件其实就是/etc文件夹下的passwd文件,但处于安全性的考虑,我们无法直接读取它.就是通过直接限制权限的方式对其进行保护,passwd文件具体权限如下: -rw-r--r-- 1 root root 可以看到只有root用户具有读写权限,与root同组的用户与其他用户仅具有读权限. 不过为了解决以上问题,Linux中给出了一系列数据结构与函数帮助我们操纵口令文件,首先是关键数据结构,定义位于/in

APUE读书笔记:File I/O

文件描述符: 进程通过文件描述符来操作文件,文件描述符可以通过open, openat, creat系统调用返回; shell和其他应用默认打开标准输入(STDIN_FILENO),标准输出(STDOUT_FILENO),标准错误(STDERR_FILENO)三个文件描述符. open和openat函数: 文件可以通过调用open或者openat函数打开或者创建: 新文件描述符使用最小未使用原则: TOCTTOU(time of check of time of use)的基本含义:程序是脆弱的

APUE读书笔记:进程控制

重点函数:fork,exit,_exit 一.fork 函数原型: #include <unistd.> pid_t fork(void) 函数说明:fork函数将创建一个子进程,该函数调用一次,但是有两次返回.子进程返回值为0,父进程的返回值是该子进程的进程ID. 小技巧:父进程能够拿到该次fork生成的子进程的ID,这是唯一的机会.而子进程不需要关心自己的进程ID.通过是否关心子进程id,就能明确地区分是父进程还是子进程. 相关的函数: 获取自己的进程ID:getpid() 获取父进程ID

apue读书笔记-第14章 高级IO

多路I/O转接 与select函数不同,poll不是为每个状态(可读性.可写性和异常状态)构造一个描述符集,而是构造一个pollfd结构数组,每个数组元素指定一个描述符编号以及其所关心的状态 readv和writev函数 作用:在一次函数调用中读.写多个非连续缓存区 总结:应当用尽量少的系统调用次数来完成任务.如果只写少量的数据,会发现自己复制数据然后使用一次write会比用writev更合算.但也可能发现,这样获得的性能提升并不值得,因为管理中间缓冲区会增加程序复杂度. readn和write