linux C之stat函式
阿新 • • 發佈:2019-02-16
- 之前寫過一篇關於stat命令的部落格,介紹了stat命令的使用和輸出資訊表示,今天又見到了stat函式,因為輸出原因,準備整理一下。
stat函式介紹
根據《UNIX環境高階程式設計》中對於stat函式的解釋,stat函式和stat命令一樣,都是返回該檔案的詳細資訊。
函式定義為:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *buf);
其中pathname是檔案的路徑名,支援絕對路徑和相對路徑,buf是一個結構體儲存檔案的資訊,這個結構體的構造如下:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
資料型別 | 變數名 | 實際資料型別 | 輸出方式 | 表示含義 |
---|---|---|---|---|
mode_t | st_mode | unsigned int | %u | 檔案型別和許可權 |
dev_t | st_dev | long long int | %lu | 檔案的主、次裝置資訊 |
dev_t | st_rdev | long long int | %lu | 如果是字元裝置和塊裝置會有這個欄位 |
ino_t | st_ino | unsigned long int | %lu | inode編號 |
nlink_t | st_nlink | unsigned long int | %lu | 硬連結的個數 |
uid_t | st_uid | unsigned int | %u | uid編號 |
git_t | st_gid | unsigned int | %u | gid編號 |
blksize_t | st_blksize | long int | %ld | 佔用區塊的大小,一般和頁表大小相同 |
blkcnt_t | st_blocks | long int | %ld | 佔用幾個頁表或區塊 |
off_t | st_size | long int | %ld | 檔案的大小 |
另外,注意結構體中的三個巨集定義,本來st_mtime,st_atime,st_ctime三個都是一個timespac的結構體,但是經過巨集定義後,直接可以輸出,這個如果不細心的話還是很容易搞亂的。
與之對應的還有幾個巨集定義,需要了解一下,對於stat結構體中的st_mode,有幾個巨集定義一顆根據st_mode的值判斷開啟檔案的型別:
函式 | 引數 | 使用 | 返回值型別 | 含義 |
---|---|---|---|---|
S_ISREG() | st_mode | S_ISR EG(st_mode) | bool | 是否為普通檔案 |
S_ISDIR() | st_mode | S_ISDIR(st_mode) | bool | 是否為目錄 |
S_ISCHR() | st_mode | S_ISCHR(st_mode) | bool | 是否為字元特殊檔案 |
S_ISBLK() | st_mode | S_ISBLK(st_mode) | bool | 是否為塊檔案 |
S_ISFIFO() | st_mode | S_ISFIFO(st_mode) | bool | 是否為管道 |
S_ISLINK() | st_mode | S_ISLINK(st_mode) | bool | 是否為符號連結 |
S_ISSOCK() | st_mode | S_ISSOCK(st_mode) | bool | 是否為套接字 |
S_TYPEISMQ() | &st_mode | S_TYPEISMQ(st_mode) | bool | 是否為訊息佇列 |
S_TYPEISSEM() | &st_mode | S_TYPEISSEM(st_mode) | bool | 是否為訊號量 |
S_TYPEISSHM() | &st_mode | S_TYPEISSHM(st_mode) | bool | 是否為共享記憶體 |
- 資料型別可以在
/usr/include/x86_64-linux-gnu/sys/types.h
中找到,發現又是
不想看這些條條串串的,可以直接看最後的表格
#ifndef __mode_t defined
typedef __mode_t mode_t;
#define __mode_t_defined
#endif
- 根據標頭檔案
bits/types.h(/usr/inlcude/x86_64-linux-gnu/bits/types.h)
查詢,此時找到的是:
# define __STD_TYPE typedef
__STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */
__STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */
__STD_TYPE __GID_T_TYPE __gid_t; /* Type of group identifications. */
__STD_TYPE __INO_T_TYPE __ino_t; /* Type of file serial numbers. */
__STD_TYPE __MODE_T_TYPE __mode_t; /* Type of file attribute bitmasks. */
__STD_TYPE __NLINK_T_TYPE __nlink_t; /* Type of file link counts. */
__STD_TYPE __OFF_T_TYPE __off_t; /* Type of file sizes and offsets. */
//還有很多,自己看吧。
typesizes.h
中是這麼定義的
#define __DEV_T_TYPE __UQUAD_TYPE
#define __UID_T_TYPE __U32_TYPE
#define __GID_T_TYPE __U32_TYPE
#define __INO_T_TYPE __SYSCALL_ULONG_TYPE
#define __MODE_T_TYPE __U32_TYPE
#ifdef __x86_64__
# define __NLINK_T_TYPE __SYSCALL_ULONG_TYPE
# define __FSWORD_T_TYPE __SYSCALL_SLONG_TYPE
#else
# define __NLINK_T_TYPE __UWORD_TYPE
# define __FSWORD_T_TYPE __SWORD_TYPE
#endif
#define __OFF_T_TYPE __SYSCALL_SLONG_TYPE
- 繞了一圈又回去了。。。傷腦筋。
然後對照資訊,終於發現定義,基本是這樣:
目標資料型別 | 檔案sys/types.h |
檔案/bits/types.h |
檔案typesizes.h |
檔案sys/types.h |
---|---|---|---|---|
mode_t | __mode_t | __MODE_T_TYPE | __U32_TYPE | unsigned int |
dev_t | __dev_t | __DEV_T_TYPE | __UQUAD_TYPE | __u_quad_t –> long long int |
ino_t | __ino_t | __INO_T_TYPE | __SYSCALL_ULONG_TYPE | unsigned long int |
nlink_t | __nlink_t | __NLINK_T_TYPE | __SYSCALL_ULONG_TYPE | unsigned long int |
uid_t | __uid_t | __UID_T_TYPE | __U32_TYPE | unsigned int |
git_t | __git_t | __GID_T_TYPE | __U32_TYPE | unsigned int |
blksize_t | __blksize_t | __BLKSIZE_T_TYPE | __SYSCALL_SLONG_TYPE | long int |
blkcnt_t | __blkcnt_t | __BLKCNT_T_TYPE | __SYSCALL_SLONG_TYPE | long int |