Unix基本系统数据类型和stat结构体
Unix基本系統數據類型
歷史上,某些UNIX變量已與某些C數據類型聯系在一起,例如,歷史上主、次設備號存放在一個1 6位的短整型中, 8位表示主設備號,另外8位表示次設備號。但是,很多較大的系統需要用多于256個值來表示其設備號,于是,就需要有一種不同的技術。(確實, SVR4用32位表示設備號:14位用于主設備號,18位用于次設備號。) 頭文件<sys/types.h >中定義了某些與實現有關的數據類型,它們被稱之為基本系統數據類型(primitive system data type)。有很多這種數據類型定義在其他頭文件中。在頭文件中這些數據類型都是用C的typedef設施來定義的。它們絕大多數都以_t 結尾。用這種方式定義了這些數據類型后,在編譯時就不再需要考慮隨系統不同而變的實施細節
caddr_t 內存地址( 1 2 . 9節)
clock_t 時鐘滴答計數器(進程時間)
comp_t 壓縮的時鐘滴答
dev_t 設備號(主和次)
fdse_t 文件描述符集
fpos_t 文件位置
gid_t 數值組ID
ino_t i節點編號
mode_t 文件類型,文件創建方式
nlink_t 目錄項的連接計數
off_t 文件長度和位移量(帶符號的)(lseek)
pid_t 進程I D和進程組I D(帶符號的)
ptrdiff_t 兩個指針相減的結果(帶符號的)
rlim_t 資源限制
sigatomic_t 能原子地存取的數據類型
sigset_t 信號集
size_t 對象(例如字符串)長度(不帶符號的)
ssize_t 返回字節計數的函數(帶符號的)(read, write)
time_t 日歷時間的秒計數器
uid_t 數值用戶ID
wchar_t 能表示所有不同的字符碼
?
用這種方式定義了這些數據類型后,在編譯時就不再需要考慮隨系統不同而變的實施細節,在本書中涉及到這些數據類型的地方,我們會說明為什么使用它們。
struct stat結構體
?stat,lstat,fstat1 函數都是獲取文件(普通文件,目錄,管道,socket,字符,塊()的屬性。函數原型#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);連接文件描述命,獲取文件屬性。2 文件對應的屬性
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; //文件所有者
gid_t st_gid; //文件所有者對應的組
off_t st_size; //普通文件,對應的文件字節數
time_t st_atime; //文件最后被訪問的時間
time_t st_mtime; //文件內容最后被修改的時間
time_t st_ctime; //文件狀態改變時間
blksize_t st_blksize; //文件內容對應的塊大小
blkcnt_t st_blocks; //偉建內容對應的塊數量
};
----------------------------------------------------------------------------------------
#include <unsitd.h>
#inlcude <sys/stat.h>
#include <sys/types.h>
int fstat(int filedes,struct stat *buf);
int stat(const char *path,struct stat *buf);
int lstat(const char *path,struct stat *buf);
這三個系統調用都可以返回指定文件的狀態信息,這些信息被寫到結構struct stat的緩沖區中。通過分析這個結構可以獲得指定文件的信息。
void report(struct stat *ptr)
{
printf("The major device no is:%d\n",major(ptr->st_dev));//主設備號
printf("The minor device no is:%d\n",minor(ptr->st_dev));//從設備號
printf("The file's node number is:%d\n",ptr->st_ino);//文件節點號
printf("The file's access mode is:%d\n",ptr->st_mode);//文件的訪問模式
printf("The file's hard link number is:%d\n",ptr->st_nlink);//文件的硬鏈接數目
printf("The file's user id is:%d\n",ptr->uid);//文件擁有者的ID
printf("The file's group id is:%d\n",ptr->gid);//文件的組ID
printf("The file's size is:%d\n",ptr->st_size);//文件的大小
printf("The block size is:%d\n",ptr->blksize);//文件占用的塊數量
printf("The number of allocated blocks is:%d\n",ptr->st_blocks);//文件分配塊數量
struct tm*accesstime,*lmodifytime,*lchangetime;//訪問時間,修改時間,最后一個改變時間(屬性)
accesstime=localtime(&(ptr->st_atime));
accesstime=localtime(&(ptr->st_mtime));
accesstime=localtime(&(ptr->st_ctime));
printf("The last access time is: %d::%d::%d\n",accesstime->hour,accesstime->min,accesstime->sec);
printf("The last modify time is:%d::%d::%d\n",lmodifytime->hour,lmodifytime->min,lmodifytime->sec);
printf("The last change time is:%d::%d::%d\n",lchangetime->hour,lchangetime->min,lchangetime->sec);
}
結構time_t可用用localtime轉換成tm結構,獲得本地時間。
?
?
使用stat結構體的三個系統調用(stat, fstat, lstat)
stat系統調用系列包括了fstat、stat和lstat,它們都是用來返回“相關文件狀態信息”的,三者的不同之處在于設定源文件的方式不同。
1
首先隆重介紹的是一個非常重要的”VIP”人物,他是fstat, stat和lstat三者都要用到的一個結構體類型,名字叫做struct stat。可以說,沒有這個struct stat的支持,上述三個系統調用將寸步難行。
?
這個struct stat結構體在不同的UNIX/Linux系統中的定義是有小的區別的,但你完全不用擔心,這并不會影響我們的使用。
在struct stat結構體中我們常用的且各個平臺都一定有的域是:
st_mode 文件權限和文件類型信息 (記住這個黑體橘紅色)
st_ino 與該文件關聯的inode
st_dev 保存文件的設備
st_uid 文件屬主的UID號
st_gid 文件屬主的GID號
st_atime 文件上一次被訪問的時間
st_ctime 文件的權限、屬主、組或內容上一次被修改的時間
st_mtime 文件的內容上一次被修改的時間。(和st_ctime的不同之處顯而易見)
st_nlink 該文件上硬連接的個數
我分別提取了solaris(UNIX)和fedora(Linux)的struct stat結構體的原始定義:大家可以自己比對一下便可以發現兩者確實有所不同,但主要的域是完全相同的。
solaris的struct stat定義:
struct stat { dev_t st_dev; ino_t st_ino; mode_t st_mode; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; dev_t st_rdev; off_t st_size; timestruc_t st_atim; timestruc_t st_mtim; timestruc_t st_ctim; blksize_t st_blksize; blkcnt_t st_blocks; char st_fstype[_ST_FSTYPSZ]; };
fedora的struct stat定義:
struct stat { __dev_t st_dev; unsigned short int __pad1; __ino_t st_ino; __mode_t st_mode; __nlink_t st_nlink; __uid_t st_uid; __gid_t st_gid; __dev_t st_rdev; unsigned short int __pad2; __off_t st_size; __blksize_t st_blksize; __blkcnt_t st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; unsigned long int __unused4; unsigned long int __unused5; };
2
大家一定注意到了,在上面列舉域的時候,我在st_mode處使用了黑體橘紅色標識,原因在于這個域不像其他域那么容易使用,其他的域的值顯而易見,而 st_mode域是需要一些宏予以配合才能使用的。其實,通俗說,這些宏就是一些特定位置為1的二進制數的外號,我們使用它們和st_mode進行”&”操作,從而就可以得到某些特定的信息。
文件類型標志包括:
S_IFBLK:文件是一個特殊的塊設備
S_IFDIR:文件是一個目錄
S_IFCHR:文件是一個特殊的字符設備
S_IFIFO:文件是一個FIFO設備
S_IFREG:文件是一個普通文件(REG即使regular啦)
S_IFLNK:文件是一個符號鏈接
其他模式標志包括:
S_ISUID:文件設置了SUID位
S_ISGID:文件設置了SGID位
S_ISVTX:文件設置了sticky位
用于解釋st_mode標志的掩碼包括:
S_IFMT:文件類型
S_IRWXU:屬主的讀/寫/執行權限,可以分成S_IXUSR, S_IRUSR, S_IWUSR
S_IRWXG:屬組的讀/寫/執行權限,可以分成S_IXGRP, S_IRGRP, S_IWGRP
S_IRWXO:其他用戶的讀/寫/執行權限,可以分為S_IXOTH, S_IROTH, S_IWOTH
還有一些用于幫助確定文件類型的宏定義,這些和上面的宏不一樣,這些是帶有參數的宏,類似與函數的使用方法:
S_ISBLK:測試是否是特殊的塊設備文件
S_ISCHR:測試是否是特殊的字符設備文件
S_ISDIR:測試是否是目錄(我估計find . -type d的源代碼實現中就用到了這個宏)
S_ISFIFO:測試是否是FIFO設備
S_ISREG:測試是否是普通文件
S_ISLNK:測試是否是符號鏈接
S_ISSOCK:測試是否是socket
3
我們已經學習完了struct stat和各種st_mode相關宏,現在就可以拿它們和stat系統調用相互配合工作了!
int fstat(int filedes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
聰明人一眼就能看出來fstat的第一個參數是和另外兩個不一樣的,對!fstat區別于另外兩個系統調用的地方在于,fstat系統調用接受的是一個“文件描述符”,而另外兩個則直接接受“文件全路徑”。文件描述符是需要我們用open系統調用后才能得到的,而文件全路經直接寫就可以了。
stat和lstat的區別:當文件是一個符號鏈接時,lstat返回的是該符號鏈接本身的信息;而stat返回的是該鏈接指向的文件的信息。(似乎有些暈吧,這樣記,lstat比 stat多了一個l,因此它是有本事處理符號鏈接文件的,因此當遇到符號鏈接文件時,lstat當然不會放過。而 stat系統調用沒有這個本事,它只能對符號鏈接文件睜一只眼閉一只眼,直接去處理鏈接所指文件嘍)
?
轉載于:https://www.cnblogs.com/soaringEveryday/p/3520494.html
總結
以上是生活随笔為你收集整理的Unix基本系统数据类型和stat结构体的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于jsp中jstl-core标签循环遍
- 下一篇: Syntax error, parame