1. 程式人生 > >linux C之stat函式

linux C之stat函式

  • 之前寫過一篇關於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
* 所以查詢東西真的很累,有沒有人給我推薦一個軟體或一種方法*