這些文件的詳細信息是存放在一個結構體stat裡面的,當文件系統運行起來後,它從磁盤裡面將文件詳細信息加載到內核空間內存裡,用戶空間可以通過系統調用函數stat(),fstat()來取得這個結構體的信息。
Stat結構體:
struct stat {
dev_t st_dev; /* 文件系統設備號 */
ino_t st_ino; /* i結點號 */
mode_t st_mode; /* 文件類型,權限位 */
nlink_t st_nlink; /* 硬鏈接數 */
uid_t st_uid; /* 主人用戶ID */
gid_t st_gid; /* 主人組ID */
dev_t st_rdev; /* 特殊文件設備號 */
off_t st_size; /* 文件字節大小 */
blksize_t st_blksize; /* 塊大小 */
blkcnt_t st_blocks; /* 文件所占塊個數 */
time_t st_atime; /* 上次訪問時間 */
time_t st_mtime; /* 上次修改時間 */
time_t st_ctime; /* 上次文件狀態修改時間 */
};
首先,其類型被typedef過了,因此看不出其類型來,可以通過grep命令來查看(具體操作看第一節),我們對比著上圖文件信息來看,基本上這一個結構體,將整個的文件的基本信息都包含了,通過讀取這個結構體,就能實現一個簡單的ls –l的shell命令了。
Stat函數
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
功能:查看文件或目錄屬性
參數:path是文件的路徑, buf就是stat結構體的指針。
返回值:成功返回0,錯誤返回-1
現在通過這個函數我們可以取得stat結構體了,那麼通過讀結構體就能得到ls –l 一樣的效果了。
我們來看一個例子:
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char * argv[])
{
if(argc != 2) {
printf("Usage: <pathname>\n");
}
int i = 0;
struct stat buf;
if(stat(argv[1], &buf) < 0) {
perror("stat");
}
printf("%d %d %d %d %d %d %s\n", buf.st_mode,
buf.st_nlink, buf.st_uid, buf.st_gid,
buf.st_size, buf.st_atime, argv[1]);
return 0;
}
運行結果:
我們發現,除了硬鏈接數,文件大小,文件名一樣,其它全部都不一樣。
看來還有很多東西要處理下,我們來分析下。
首先是st_mode,它是一個int型的成員,而ls –l顯示出來是字符串
st_uid, st_gid這兩個也是int型成員,而ls是用戶名