1、引言網絡
上一章執行I/O的基本函數(打開文件、讀文件和寫文件),本章將描述文件系統的其餘特徵和文件的性質,咱們將從stat函數開始,並逐個說明stat結構的每個成員以瞭解文件的全部屬性。在此過程當中,咱們將說明修改這些屬性的各個函數。socket
2、函數stat、fstat、fstatat和lstat函數
#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); //若成功,返回0;若失敗,返回-1
若pathname給出絕對路徑,則buf返回stat對應文件的信息;須要注意兩點:lstat返回該符號鏈接的有關信息,而不是由該符號鏈接引用的文件的信息;fstatat當AT_SYMLINK_NOFOLLOW被設置時,不會跟隨符號鏈接,而是同lstat同樣,返回符號鏈接自己的有關信息,當AT_FDCWD被設置時,而且pathname是一個相對路徑時,會從當前路徑開始計算pathname。stat結構的基本形式以下:測試
struct stat { mode_t st_mode; ino_t st_ino; dev_t st_dev; dev_t st_rdev; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; off_t st_size; struct timespec st_atime; struct timespec st_mtime; struct timespec st_ctime; blksize_t st_blksize; blkcn_t st_blocks; };
3、文件類型ui
1.普通文件 :最經常使用的文件類型spa
2.目錄文件 :這種文件包含了其餘文件的名字以及指向與這些文件有關信息的指針。命令行
3.塊特殊文件 :每次訪問以固定長度爲單位指針
4.字符特殊文件 :這種類型的文件提供對設備不帶緩衝的訪問。系統中的設備要麼是字符特殊文件,要麼是塊特殊文件rest
5.FIFO :用於進程間通訊,也稱爲命名管道code
6.套接字 :用於進程間網絡通訊
7.符號鏈接 :這種類型的文件指向另外一個文件
#include "apue.h" int main(int argc, char *argv[]) { int i; char *ptr; struct stat buf; for(i = 1; i < argc; i++) { printf("%s:", argv[i]); if(lstat(argv[1], &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); } }
4-3 對每一個命令行參數打印文件類型
4、設置用戶ID和設置組ID
與一個進程相關聯的ID有6個或更多:實際用戶ID和實際組ID:咱們其實是誰?有效用戶ID和有效組ID和附屬組ID:用於文件訪問權限檢查;保存的設置用戶ID和保存的設置組ID:用於exec函數保存。
每一個文件有一個全部者和組全部者,由st_uid和st_gid指定。
5、文件訪問權限
全部文件類型都有訪問權限,不少人認爲只有普通文件有訪問權限,這是一種誤解。一個文件的權限分爲三部分:用戶、組和其餘,分別由讀、寫和執行組成。文件的權限有如下規則:
1.咱們用名字打開任一類型文件時,對更名字中包含的每個目錄,包括他可能隱含的當前工做目錄都應具備執行權限,這也是爲何對於目錄執行權限位常備稱做搜索位的緣由。對於目錄而言:讀權限意味得到在該目錄中全部文件名的列表;執行權限意味進入該目錄。
2.爲了在目錄中建立一個新文件,咱們必須具備該目錄的寫權限和執行權限
3.爲了刪除目錄中的一個文件,咱們必須具備該目錄的寫權限和執行權限,而對於該具體文件而言,則不須要讀、寫權限。
6、函數access和faccessat
當用open函數打開一個文件時,內核以進程的有效用戶ID和有效組ID爲基礎執行其訪問權限的測試。有時進程也但願按其實際用戶ID和實際組ID來測試其訪問能力,access和faccessat就是爲了實現這種功能,無論有效用戶ID和有效組ID是什麼,都是以實際用戶ID和實際組ID來進行訪問權限測試。
#include <unistd.h> int access(const char *pathname. int mode); int faccessat(int fd, const char *pathname. int mode); //成功返回0;失敗返回-1
#include <apue.h> #include <fcntl.h> int main(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 %s\n", argv[1]); } exit(0); }
4-8 access函數實例