本文章將描述文件系統的其他特性和文件的性質。
1 stat、fstat、和lstat函數
獲取文件的信息結構
#include <sys/stat.h>
int stat(const char *restrict pathname, struct stat * restrict buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *restrict pathname, struct stat * restrict buf);
//若成功返回0,失敗返回-1
stat函數獲取與此命名文件有關的信息結構
fstat函數獲取在描述符filedes上打開的文件的有關的信息
lstat與stat類似,但是當命名文件是一個符號鏈接的時候,lstat返回此符號連接的信息,而不是此符號連接所指向的文件的信息
以下是stat結構體的結構
struct stat {
mode_t st_mode; // 文件類型和權限
ino_t st_ino; // 文件的inode號
dev_t st_dev; // 設備號
dev_t st_rdev; // 特殊設備文件號
nlink_t st_nlink; // 鏈接數
uid_t st_uid; // 用戶ID號
gid_t st_gid; // 用戶屬組ID號
off_t st_size; // 普通文件對應的文件字節數
time_t st_atime; // 文件最後被訪問的時間
time_t st_mtime; // 文件最後被修改的時間
time_t st_ctime; // 文件狀態最後被修改的時間
blksize_t st_blksize; // 文件內容對應的塊大小
blkcnt_t st_blocks; // 文件內容對應的塊數量
};
2 文件類型
文件類型包括以下幾種:
(1)普通文件:最常見的類型,包含了某種形式的數據。
(2)目錄文件:包含了其他文件的名字以及指向與這些文件有關的信息的指針。
(3)塊特殊文件:這種類型的文件可以提供對設備帶緩衝的訪問(磁盤)。
(4)字符特殊文件:這種類型的文件提供對設備不帶緩衝的訪問。
(5)FIFO:這種類型的文件用於進程間通信,有時將其稱爲命名管道。
(6)套接字:這種類型的文件用於進程間的網絡通信。
(7)符號鏈接:這種文件類型指向一個文件。
文件類型的信息保存在stat結構體的st_mode中,可以通過以下宏確定文件的類型
S_ISREG() //普通文件
S_ISDIR() //目錄文件
S_ISCHR() //字符特殊文件
S_ISBLK() //塊特殊文件
S_ISFIFO() //管道或FIFO
S_ISLNK() //符號鏈接
S_ISSOCK() //套接字
POSIX.1允許實現進程間對象(IPC)。以下宏可以確定IPC對象的類型,這些宏的參數是指向stat結構的指針
S_TYPEISMQ //消息隊列
S_TYPEISSEM //信號量
S_TYPEISSHM //共享存儲對象
3 用戶ID和組ID
一個進程通常包含多個ID
實際用戶ID和實際組ID標識我們究竟是誰,這兩個字段在登錄的時候取自口令文件中的登錄項。
有效用戶ID、有效組ID以及附加組ID決定了我們的文件訪問權限。
保存的設置用戶ID和保存的組ID在執行一個程序時包含了有效用戶ID和組有效組ID的副本。
在stat函數中,設置用戶ID位及設置組ID位都包含在st_mode值中。可以用S_ISUID()和S_ISGID()來測試。
2.4 文件的訪問權限
所有的文件類型的文件都有訪問權限(access Permission)
每個文件都有9個訪問權限
S_IRUSR //用戶-讀
S_IWUSR //用戶-寫
S_IXUSR //用戶-執行
S_IRGRP //組-讀
S_IWGRP //組-寫
S_IXGRP //組-執行
S_IROTH //其他-讀
S_IWOTH //其他-寫
S_IXOTH //其他-執行
我們用名字打開任一類型的文件時,對該名字中包含的每一個目錄,包括它可能隱含的當前工作目錄都應具有執行權限。
這就是爲什麼對於目錄其執行權限位常被稱爲搜索位的原因。
進程在每次打開,創建和刪除一個文件的時候,內核就進行文件訪問權限的測試:
1.若進程的有效用戶ID是0,則允許訪問。
2.若進程的有效用戶ID等於文件的所有者ID,那麼,若所有者適當的訪問權限位被設置,則允許訪問,否則拒絕訪問。
3.若進程的有效組ID或進程的附加組ID之一等於文件的組ID,那麼,若所有者適當的訪問權限位被設置,則允許訪問,否則拒絕訪問。
4.若其他用戶適當的訪問權限位被設置,則允許訪問,否則拒絕訪問。
5 access函數
按實際的用戶ID和實際組ID進行訪問權限測試
#include <unistd.h>
int access(const char *pathname, int mode);
//成功返回0,失敗返回-1
6 umask函數
爲進程設置文件模式創建屏蔽字
#include <sys/stat.h>
mode_t umask(mode_t cmask);
//返回以前的文件模式創建屏蔽字,沒有出錯返回
cmask是9個訪問權限位
7 chmod和fchmod函數
改變文件的訪問權限
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int filedes, mode_t mode);
//成功返回0,失敗返回-1
8 粘住位
S_ISVTX位在早期的UNIX尚未使用分頁技術的早期版本中,被該位被稱之爲粘住位,當程序運行結束的時候,
其程序的正文部分的一個副本仍被保存在交換區內,下一次執行該程序的時候,可以較快的裝入內存。
現今的粘住位稱爲保存正文位,如果對一個目錄設置了粘住位,則只有滿足以下條件之一,纔可將其刪除:
1.擁有此文件
2.擁有此目錄
3.是超級用戶
9 chown、fchown和lchown
用於更改文件的用戶ID和組ID
#include <unistd.h>
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);
//成功返回0,失敗返回-1
10 文件長度
在unix環境下,文件長度只是文件的一個屬性,並不表徵佔用多少磁盤空間
stat結構成員st_size表示以字節文單位的文件長度,此字段只針對與普通文件,目錄文件和符號鏈接有意義。
11 文件截短
在文件尾端處截去一些數據以縮短文件。
#include <unistd.h>
int truncate(const char *pathname, off_t length);
int ftruncate(int filedes, off_t length);
//成功返回0,失敗返回-1
以上兩個函數是把現有的文件截短爲length字節。
12 link、unlink、remove和rename
#include <unistd.h>
int link(const char *existingpath, const char *newpath);
//創建一個指向現有文件的鏈接
int unlink(const char *pathname);
//刪除一個現有的目錄項
int remove(const char *pathname);
//解除對一個文件或目錄的鏈接
int rename(const char *oldname, const char *newname);
//對文件或目錄改名
13 symlink和readlink函數
操作符號鏈接
#include <unistd.h>
int symlink(const char *actualpath, const char *sympath);
//創建一個符號鏈接
ssize_t readlink(const char * restrict pathname, char * restrict buf, size_t bufsize);
//讀取一個符號鏈接
14 文件的時間
對每個文件保持三個時間字段
st_atime //文件數據的最後訪問時間(read)
st_mtime //文件數據的最後修改時間(write)
st_ctime //i節點狀態的最後更改時間(chmod, chown)
unix不記錄文件的創建時間
15 utime函數
修改一個文件的訪問和修改時間
#include <utime.h>
int utime(const char *pathname, const struct utimbuf *time);
struct utimbuf{
time_t actime;
time_t modtime;
};
16 mkdir和rmdir函數
創建和刪除目錄
#include <sys/stat.h>
int mkdir(const char * pathname, mode_t mode);
int rmdir(const char * pathname);//只能刪除空目錄,目錄中只包括.和..
17 讀目錄
#include <dirent.h>
DIR *opendir(const char *pathname);
//成功返回指針,失敗返回NULL
struct dirent *readdir(DIR *dp);
//成功返回指針,若在目錄結尾或者出錯返回NULL
void rewinddir(DIR *dp);
int closedir(DIR *dp);
//成功返回0,失敗返回-1
long telldir(DIR *dp);
//返回與dp關聯的目錄中的當前位置
void seekdir(DIR *dp, long loc);
struct dirent {
ino_t d_ino;
char d_name[NAME_MAX + 1];
};
18 chdir、fchdir和getcwd
更改當前工作目錄
#include <unistd.h>
int chdir(const char *pathname);
int fchdir(int filedes);
//成功返回0, 失敗返回-1
獲取當前工作目錄的完整的絕對路徑名
#include <unistd.h>
char * getcwd(char *buf, size_t size);
//成功返回buf, 失敗返回NULL
【APUE】文件和目錄
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
udp服務器端demo
zyw067
2018-08-26 20:47:13
【Linux】存儲映射I/O—mmap
萧-十一
2018-08-26 17:04:39
sem_init
carpediem523
2018-08-26 15:47:15
APUE讀書筆記-第十四章-高級I/O
qiao_yi_fan
2018-08-26 14:22:33
APUE讀書筆記-第十五章-進程間通信
qiao_yi_fan
2018-08-26 14:22:33
TCP IP詳解卷2之mbuf宏與函數
shinichr
2018-08-26 11:14:24
socket阻塞與非阻塞模式區別
shinichr
2018-08-26 11:14:24
TCP-IP詳解 卷2:實現之mbuf存儲器緩存
shinichr
2018-08-26 11:14:18
APUE-文件與目錄:一個LINUX用戶登陸函數
向太阳
2018-08-25 20:00:40
APUE:線程:線程池的實現
向太阳
2018-08-25 20:00:40
APUE-線程:pthread_create的實現與apue2的區別
向太阳
2018-08-25 20:00:40
APUE-文件與目錄:dup與dup2
向太阳
2018-08-25 20:00:40
APUE:進程:wait、waitpid
向太阳
2018-08-25 20:00:40
APUE:線程:讀寫鎖rwlock
向太阳
2018-08-25 20:00:40