麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統 > Unix > 正文

UNIX高級環境編程(3)Files And Directories

2024-06-28 13:21:57
字體:
來源:轉載
供稿:網友
UNIX高級環境編程(3)Files And Directories - stat函數,文件類型,和各種ID

在前面的兩篇,我們了解了IO操作的一些基本操作函數,包括open、read和write。

在本篇我們來學習一下文件系統的其他特性和一個文件的屬性,涉及的函數功能包括:

  • 查看文件的所有屬性;
  • 改變文件所有者;
  • 改變文件權限;
  • 操作文件夾。

我們還會了解一些文件系統相關的數據結構和符號鏈接(symbolic link)。

1 函數stat、fstat、fstatat、lsat函數
#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 *restrict buf );int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);//All four return: 0 if OK, −1 on error

函數功能:

stat返回pathname指定文件的信息;

fstat獲取在文件描述符fd上打開的文件信息;

lstat的功能和stat函數類似,只是有一種情況有區別,當pathname指定的文件是一個符號鏈接的時候,lstat函數獲取的文件信息是該符號鏈接的信息,而不是符號鏈接所指向文件的信息,在后面我們會了解更多關于符號鏈接的相關內容;

fstatat:文件描述符fd表示一個父目錄,pathame指定父目錄下得一個子目錄,fstatat函數返回該子目錄下的文件統計數。flag用來設置是否查詢符號鏈接所指向的文件,如果flag設置為AT_SYMLINK_NOFOLLOW,則fstatat函數只返回該符號鏈接的相關信息,如果不設置該標志位,則返回該符號鏈接指向的文件的相關信息。

是一個關鍵的輸出參數,上面的參數將文件屬性填充值該結構體內。結構體如下圖所示:

NewImage

結構體中得每個成員都代表文件的某一個屬性,我們會逐個了解屬性的具體含義。

2 文件類型(File Type)

目前我們了解了兩種文件:常規文件(regular files)和文件夾(directory)。

常見的幾種文件類型包括:

  1. 常規文件(Regular File):包含某種組織形式的數據的文件,linux并不關心數據是文本或是二進制(有一個例外,就是二進制可執行文件,內核必須知道該類型的格式才能執行),對數據的解析由應用程序負責。
  2. 目錄文件(Directory):包含其他文件的名字,和指向這些文件信息的指針。進程可以讀取目錄文件的內容,但是只有內核才又寫該類型文件的權限,進程通過調用本篇介紹的一些函數才操作修改目錄文件,本質上仍然是內核修改。
  3. 塊文件(Block Special File):如硬盤驅動,提供了固定大小緩存用于IO的文件類型。
  4. 字符文件(Charactor Special File):無緩存的對可變大小單元進行操作的文件類型。操作系統所有的設備都是塊設備文件或字符設備文件。
  5. 先入先出隊列(FIFO):進程間通信使用的文件類型。
  6. 套接字(Socket):網絡或單機中的兩個進程之間的通信使用的文件類型。
  7. 符號鏈接(Symbolic File):指向另一個文件的文件類型。

stat結構體中得st_mode制定了文件的類型。

Example:

#include "apue.h"intmain(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_ISLNK(buf.st_mode))            ptr = "symbolic link";        else if (S_ISSOCK(buf.st_mode))            ptr = "socket";        else            ptr = "** unknown mode **";        printf("%s/n", ptr);    }    exit(0);}

運行截圖:

NewImage

3 設置用戶Id(User ID)和組Id(Group ID)

每個進程6個甚至更多的ID和它關聯。如下表所示:

NewImage

簡要介紹ID的區別:

  • real user ID和real group ID:當前登陸用戶的ID和該用戶所屬的組ID;
  • effective user ID、effective group ID和supplementary group IDs:文件的訪問權限。
  • saved set-user-ID和saved set-group-ID:當一個程序運行時,會拷貝effective user ID和effective group ID到這兩個變量中,這兩個ID和函數setuid相關。

一般情況下,effective user ID = real user ID,effective group ID = real group ID.

每個文件都由一個所有者,和一個組所有者,分別對應stat數據結構中得字段:st_uid和st_gid。

如果執行程序時,希望effective user(group) ID != real user(group) ID,即希望改變進程的訪問資源的權限為文件所有者的訪問權限,而不是真實用戶的訪問權限,可以通過設置mode中兩個bit來實現將effective user(group) ID設置為文件所有者(組),這兩個bit叫做:set-user-ID位和set-group-ID位。這兩個位包含在stat數據結構中得st_mode字段中,可以通過函數S_ISUID和S_ISGID來測試。

4 文件訪問權限(File access Permissions)

stat數據結構中的st_mode字段中同樣包含文件訪問權限位。

每個文件有9中權限位:

NewImage

這些標志位的使用需要注意的事項總結如下:

  • 如果要打開某個文件,則該文件全路徑上的所有文件夾都需要有執行權限(execute permission),該文件則需要對應的操作權限。需要可執行權限的原因是可以通過(pass through)它找到下一級目錄或者文件;
  • 讀權限,允許打開某個已存在文件,標志位:O_RDONLY和O_RDWR;
  • 寫權限,允許向某個已存在文件寫入數據,標志位:O_WRONLY和O_RDWR;
  • 調用open函數時,如果要指定標志位O_TRUNC,需要寫權限;
  • 我們無法在某個文件夾下創建文件,除非我們對該文件夾有寫權限(write permission)和執行權限(execute permission);
  • 刪除某個文件,需要該文件所在文件夾的寫權限和執行權限,而不需要對該文件本身有寫權限或讀權限;
  • 如果我們希望使用exec類函數執行某個文件,則必須有可執行權限,并且該文件必須為regular file。

文件訪問權限檢測流程:

  1. 如果進程的effective user ID是0,即超級用戶,則允許訪問;
  2. 如果進程的effective user ID是文件所有者的ID,即該進程是該文件的所有者(owner),并且相應的訪問權限標志位被設置,則允許訪問;
  3. 如果進程的effective group ID或者supplementary group IDs之一是文件所有組的ID,并且相應的訪問權限標志位被設置,則允許訪問;
  4. 如果相應的other訪問權限標志位被設置,則允許訪問。

簡單來說,如果進程是該文件的擁有者,則訪問是否允許取決于用戶訪問權限標志位,忽略組權限標志位;如果進程不是該文件的擁有者,但是該進程屬于某個有訪問權限的組,訪問是否允許取決于組權限標志位的設置,忽略other訪問權限標志位。

5 新文件和目錄的所有權(ownership)

新文件的real user ID為創建該文件的進程的effective user ID。

新文件的real group ID的取值取決于:

  • 新文件的real group ID可以是常見該文件的進程的effective group ID;
  • 新文件的real group ID可以是該文件所在目錄的real group ID。(必須保證該目錄下面的所有文件的real group ID都是該目錄的real group ID)。

6 函數access和faccessat

access和faccessat函數用于測試當前用戶(real user,當前登錄用戶)對某一文件是否有某種操作權限。

函數聲明:

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

mode的可取值,當為F_OK,測試文件是否存在。

NewImage

faccessat函數的相關細節:

  • 當pathname為絕對路徑,或者fd取值為AT_FDCWD并且pathname為相對路徑時,功能和access相同。
  • 否則,faccessat函數指定的工作目錄為pathname指定的相對目錄加上fd描述符指定的父目錄。
  • 當flag的值為AT_EACCESS時,測試時使用進程的effective user和group而不是當前real user ID和group。

Example:

#include "apue.h"#include <fcntl.h>intmain(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");    exit(0);}

測試:

NewImage

由于本地mac環境搞不定,所以直接截書上的例子吧。

該例中,當切換到root用戶,修改了該文件的所有者為root用戶,并且設置了set-user-ID,這樣當切換到別的用戶時,仍可以以RDONLY方式打開文件,但是由于access是測試當前real user的讀權限,當切換到其他用戶時,access測試不通過,顯示Permission denied。

好吧,直接忽略上面這個例子吧,我沒能在自己的機器上重現,只是直接隨便翻譯書上某一段話。如果有某位高手看懂了,請指點。

小結

由于這一章內容比較多,所以打算用三篇來寫,這是第一篇,主要介紹了stat函數,access函數,文件類型和各種令人糊涂的ID。

參考資料:

《Advanced Programming in the UNIX Envinronment 3rd》


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 成人免费国产 | 午夜影院a | 欧美大逼网 | 日美av在线 | 99国产精品欲a | 斗破苍穹在线免费 | 美国黄色毛片女人性生活片 | 经典三级在线视频 | 久久久久久久久久亚洲精品 | 久久另类视频 | 成人国产精品一区 | 免费a级作爱片免费观看欧洲 | 91精品国产成人 | 成人在线观看免费 | 久久精品视频3 | 九九热视频这里只有精品 | 久久国产精品久久久久 | 欧美高清视频一区 | 亚洲精品一区二区三区在线看 | 黄色免费在线电影 | 久国久产久精永久网页 | 久久最新免费视频 | 国产99页 | 国产中文一区 | 国内精品久久久久久久星辰影视 | 欧美电影在线观看 | 国产亚洲黑人性受xxxx精品 | 欧美日韩在线免费观看 | 国产精品久久久久久久久久三级 | 九九热精品在线 | 国产一区二区影视 | 日本欧美一区二区三区在线播 | 一级大片一级一大片 | 黄色片网站免费观看 | 日韩每日更新 | 久久国产乱子伦精品 | 99激情| 日日噜噜噜噜久久久精品毛片 | 国产精品久久久久久久av | 国产毛片毛片 | 国产成人在线一区 |