#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);
stat函數返回pathname文件有關的信息結構,lstat返回符號鏈接有關信息,而不是符號鏈接應用的文件
Unix中一切皆爲對象,文件信息結構如下:
struct stat
{
mode_t st_mode;//文件類型,模式字
ino_t st_ino;//i節點號
dev_t st_dev;//設備號(文件系統)
dev_t st_rdev;//特殊文件設備號,SUS XSI擴展
nlink_t st_nlink;//i節點連接計數,硬鏈接
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;//文件狀態最後訪問時間
time_t st_blksize;//SUS XSI擴展
time_t st_blocks;//SUS XSI擴展
}
文件類型:ls命令 測試宏;POSIX.1允許將IPC對象(如消息隊列,信號量)表示爲文件,但是Linux,FreeBSD,Solaris,MacOS都不將這些對象表示爲文件。
1)普通文件 - S_ISREG(stat.st_mode)
2)目錄文件 d S_ISDIR()
3)塊文件 b S_ISCHR() 這種文件提供對設備(如磁盤)帶緩衝的訪問,每次訪問以固定長度爲單位進行。
4)字符文件 c S_ISBLK() 提供對設備不帶緩衝的訪問,訪問長度可變。
5)FIFO f S_ISFIFO() 命名管道(named pipe),用於IPC
6)套接字 s S_ISSOCK()
7)符號鏈接 l S_ISLNK()
重要問題(用戶和組)
弄清楚的概念,
與進程相關聯的ID
1) 實際用戶ID 登錄時取自口令文件/etc/passwd
2)實際組ID 登錄時取自口令文件/etc/passwd
3)有效用戶ID
4)有效組ID
5)附加組ID
6)保存的設置用戶ID 在執行程序是包含了有效用戶ID和有效組ID的副本,setuid函數
7)保存的設置組ID
通常有效用戶ID等於實際用戶ID,有效組ID等於實際組ID。但是當執行一個文件程序(可執行文件)時,文件模式自的兩位:設置用戶ID位,
設置組ID位。當他們設置時,其含義是,當執行此文件時,將進程的有效用戶ID(有效組ID)設置爲文件所有者的用戶ID(組ID)。
運行設置用戶ID程序的進程通常得到額外的權限。
文件訪問權限(九位)
文件所有者owner/user 文件所有者所在的組成員group 其他成員other
owner:S_IRUSR S_IWUSR S_IXUSR
group:S_IRGRP S_IWGRP S_IXGRP
other:S_IROTH S_IWOTH S_IXOTH
目錄的執行權限位常被稱爲搜索位:要打開文件a,則包含a的目錄用戶都必須具有可執行權限。
目錄的讀權限和執行權限.
注意:
打開文件權限位(O_RDONLY,O_WRONLY,O_RDWR)
對文件指定O_TRUNC標誌,文件必須具有寫權限
在目錄中創建文件,該目錄必須具有寫權限和執行權限
使用open或creat創建新文件時,新文件的用戶ID爲進程的有效用戶ID;新文件的組ID可以是進程的有效組ID,可以使他所在目錄的組ID。
當open打開文件時,內核以進程的有效用戶ID和有效組ID爲基礎執行其訪問權限測試。
#include <unistd.h>
int access(const char *pathname, int mode);//按照實際用戶ID和實際組ID進行訪問權限測試。
mode的值:
R_OK:測試讀權限
W_OK:測試寫權限
X_OK:測試執行權限
F_OK:測試文件是否存在
#include <sys/stat.h>
mode_t umask(mode_t cmask);--設置文件模式創建屏蔽字,返回以前的值,無出錯返回
文件模式創建屏蔽字,與每個進程相關聯。cmask是9個常量的按位或。
文件模式創建屏蔽字爲1的位,文件的mode相應位關閉。
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);//更改現有文件的訪問權限
int fchmod(int fd, mode_t mode);
mode_t的位(除了文件訪問權限位9位,以外還有六位)
S_IRWXU 用戶讀寫執行
S_IRWXG 組讀寫執行
S_IRRWXO 其它讀寫執行
S_ISUID 執行時設置用戶ID
S_ISGID 執行時設置組ID
S_ISVTX 保存正文(站住位)
/* 改變文件的用戶ID和組ID */
#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 lchown(const char *pathname, uid_t owner, gid_t group);
/* 文件截短,將文件截斷爲length */
#include <unistd.h>
int truncate(const char *pathname, off_t length);
int truncate(int fd, off_t length);
文件空洞,由所設置的偏移量超過文件尾端,並寫了某些數據後造成的。du命令,查看文件佔用的磁盤塊數。
下面是個重要問題!——文件系統
Unix文件系統(Unix file system),BSD快速文件系統
磁盤0號扇區稱爲主引導記錄(Master Boot Record,MBR),MBR的結尾是分區表(給出每個分區的起始地址和結束地址)。
表中的一個分區被標記爲活動分區。計算機被引導時,BIOS讀入並執行MBR,MBR確定活動分區,讀入其第一個塊,稱爲引
導塊並執行。引導塊中的程序將裝載該分區的操作系統,保留引導塊,可以保證以後可以安裝操作系統。
超級塊,保存文件系統重要參數。
文件系統空閒塊,位圖形式或指針列表
分區(引導塊,超級塊,文件系統空閒塊,其它)
一個磁盤分成幾個分區,每個分區包含一個文件系統。文件系統格式:
自舉塊(引導塊) 超級塊 柱面組0 柱面組1 ... 柱面組n
i節點,包含了大多數與文件有關的信息:文件類型,文件訪問權限位,文件長度,指向該文件所佔用的數據塊的指針。
目錄項,存放文件名和i節點編號。
每個文件系統對它們的i節點進行編號,目錄項中的i節點指向同一文件系統中相應的i節點,不能使一個目錄項指向另一個文件系統的i節點。
ln命令不能跨越文件系統。
普通文件鏈接計數和目錄文件的鏈接計數
mkdir test
當前目錄 . 鏈接計數2 任何一個頁目錄(不含任何子目錄和文件的目錄)的鏈接計數總是2 test/. ; test/..
上級目錄 .. 鏈接計數3 不解釋 ../. ; ../.. ; ../test
創建指向現有文件的鏈接(硬鏈接)
#include <unistd.h>
int link(const char *path, const char *newpath);
int unlink(const char *pathname);//刪除一個現有的目錄項
int remove(const char *pathname);//對文件unlink,對於目錄與rmdir
POSIX.1 允許實現支持跨文件系統的鏈接,但是多實現要求六個路徑名在同一文件系統中。
如果實現支持創建指向一個目錄的硬鏈接,也僅限於root用戶。理由是可能在文件系統中形成循環,而大多數處理文件系統的
程序都不能處理這種情況,很多文件系統實現不允許目錄硬鏈接。
爲了避開硬鏈接的限制,引入符號鏈接。(文件系統限制,目錄限制)
每個文件保持有時間
st_atime:文件數據的最後訪問時間
st_mtime:文件數據的最後修改時間
st_ctime:i節點狀態的最後更改狀態
i節點狀態(文件的訪問權限,用戶ID,鏈接數)
#include <utime.h>
int utime(const char *pathname, const struct utimbuf *times);//改變一個文件的訪問和修改時間
struct utimbuf
{
time_t actime;//訪問時間
time_t modtime;//修改時間
}