跳轉到內容

C 程式設計/POSIX 參考/sys/stat.h

來自華夏公益教科書,開放書籍,開放世界

<sys/stat.h>C POSIX 庫 中用於 C 程式語言 的標頭檔案,其中包含用於獲取檔案屬性資訊的構造。

成員函式

[編輯 | 編輯原始碼]
名稱 註釋
int stat (const char *filename, struct stat *buf) The stat 函式返回由 filename 指示的檔案的屬性資訊,儲存在 buf 指向的結構中。如果 filename 是一個符號連結的名稱,那麼您獲得的屬性將描述連結指向的檔案。如果連結指向一個不存在的檔名,則 stat 會失敗並報告不存在的檔案。如果操作成功,則返回值為 0,否則為 -1。當原始碼使用 _FILE_OFFSET_BITS == 64 編譯時,此函式實際上是 stat64,因為 LFS 介面透明地替換了正常的實現。

errno 錯誤:ENOENT 表示由 filename 指示的檔案不存在。

int stat64 (const char *filename, struct stat64 *buf) 此函式類似於 stat,但它也能在 32 位系統上處理大於 2^31 位元組的檔案。為了實現這一點,結果儲存在一個型別為 struct stat64 的變數中,buf 必須指向該變數。當原始碼使用 _FILE_OFFSET_BITS == 64 編譯時,此函式在 32 位機器上以 stat 的名稱可用,因此透明地替換了小型檔案介面。

errno 錯誤:ENOENT 表示由 filename 指示的檔案不存在。

int fstat (int filedes, struct stat *buf) fstat 函式類似於 stat,只是它接受一個開啟的檔案描述符 (filedes) 作為引數,而不是檔名。與 stat 一樣,fstat 在成功時返回 0,在失敗時返回 -1。當原始碼使用 _FILE_OFFSET_BITS == 64 編譯時,此函式實際上是 fstat64,因為 LFS 介面透明地替換了正常的實現。

errno 錯誤:EBADF 表示 filedes 引數不是有效的檔案描述符。

int fstat64 (int filedes, struct stat64 *buf) 此函式類似於 fstat,但能夠在 32 位平臺上處理大型檔案。對於大型檔案,檔案描述符 filedes 應該透過 open64 或 creat64 獲取。buf 指標指向一個型別為 struct stat64 的變數,該變數能夠表示更大的值。當原始碼使用 _FILE_OFFSET_BITS == 64 編譯時,此函式在 32 位機器上以 fstat 的名稱可用,因此透明地替換了小型檔案介面。

errno 錯誤:EBADF 表示 filedes 引數不是有效的檔案描述符。

int lstat (const char *filename, struct stat *buf) lstat 函式類似於 stat,只是它不跟蹤符號連結。如果 filename 是一個符號連結的名稱,則 lstat 返回有關連結本身的資訊;否則 lstat 類似於 stat。請參閱符號連結。當原始碼使用 _FILE_OFFSET_BITS == 64 編譯時,此函式實際上是 lstat64,因為 LFS 介面透明地替換了正常的實現。
int lstat64 (const char *filename, struct stat64 *buf) lstat 函式類似於 stat,只是它不跟蹤符號連結。如果 filename 是一個符號連結的名稱,則 lstat 返回有關連結本身的資訊;否則 lstat 類似於 stat。請參閱符號連結。當原始碼使用 _FILE_OFFSET_BITS == 64 編譯時,此函式實際上是 lstat64,因為 LFS 介面透明地替換了正常的實現。

成員常量

[編輯 | 編輯原始碼]

以下 POSIX 宏定義用於使用 st_mode 欄位檢查檔案型別

名稱 註釋
S_ISREG(m) 它是一個普通檔案嗎?
S_ISDIR(m) 它是一個目錄嗎?
S_ISCHR(m) 它是一個字元裝置嗎?
S_ISBLK(m) 它是一個塊裝置嗎?
S_ISFIFO(m) 它是一個 FIFO(命名管道)嗎?
S_ISLNK(m) 它是一個符號連結嗎?(在 POSIX.1-1996 中沒有。)
S_ISSOCK(m) 它是一個套接字嗎?(在 POSIX.1-1996 中沒有。)

以下標誌定義用於 st_mode 欄位

名稱 註釋
S_IFMT 0170000 檔案型別位欄位的位掩碼
S_IFSOCK 0140000 套接字
S_IFLNK 0120000 符號連結
S_IFREG 0100000 普通檔案
S_IFBLK 0060000 塊裝置
S_IFDIR 0040000 目錄
S_IFCHR 0020000 字元裝置
S_IFIFO 0010000 FIFO
S_ISUID 0004000 設定 UID 位
S_ISGID 0002000 設定組 ID 位(見下文)
S_ISVTX 0001000 粘滯位(見下文)
S_IRWXU 00700 檔案所有者許可權的掩碼
S_IRUSR 00400 所有者具有讀取許可權
S_IWUSR 00200 所有者具有寫入許可權
S_IXUSR 00100 所有者具有執行許可權
S_IRWXG 00070 組許可權的掩碼
S_IRGRP 00040 組具有讀取許可權
S_IWGRP 00020 組具有寫入許可權
S_IXGRP 00010 組具有執行許可權
S_IRWXO 00007 其他人(不在組中)的許可權掩碼
S_IROTH 00004 其他人具有讀取許可權
S_IWOTH 00002 其他人具有寫入許可權
S_IXOTH 00001 其他人具有執行許可權

設定組 ID 位 (S_ISGID) 具有多種特殊用途。對於目錄,它表示要對該目錄使用 BSD 語義:在該目錄中建立的檔案將繼承其組 ID,而不是建立程序的有效組 ID,並且在該目錄中建立的目錄也將設定 S_ISGID 位。對於沒有設定組執行位 (S_IXGRP) 的檔案,設定組 ID 位表示強制檔案/記錄鎖定。目錄上的粘滯位 (S_ISVTX) 表示只有檔案的擁有者、目錄的擁有者以及特權程序才能重新命名或刪除該目錄中的檔案。

POSIX 不描述 S_IFMTS_IFSOCKS_IFLNKS_IFREGS_IFBLKS_IFDIRS_IFCHRS_IFIFOS_ISVTX 位,而是要求使用宏 S_ISDIR() 等。S_ISLNK()S_ISSOCK() 宏不在 POSIX.1-1996 中,但都存在於 POSIX.1-2001 中;前者來自 SVID 4,後者來自 SUSv2。

其他系統 - 在各種系統中使用過的(或正在使用過的)值

十六進位制 名稱 ls 八進位制 描述
f000 S_IFMT 170000 檔案型別的掩碼
0000 000000 SCO 停用 inode;BSD 未知型別;SVID-v2 和 XPG2 對於普通檔案都使用 0 和 0100000
1000 S_IFIFO p| 010000 FIFO(命名管道)
2000 S_IFCHR c 020000 字元特殊(V7)
3000 S_IFMPC 030000 多路複用字元特殊(V7)
4000 S_IFDIR d/ 040000 目錄(V7)
5000 S_IFNAM 050000 XENIX 命名特殊檔案,具有兩種子型別,由 st_rdev 值 1、2 區分
0001 S_INSEM s 000001 XENIX 訊號量,IFNAM 的子型別
0002 S_INSHD m 000002 XENIX 共享資料,IFNAM 的子型別
6000 S_IFBLK b 060000 塊特殊(V7)
7000 S_IFMPB 070000 多路複用塊特殊(V7)
8000 S_IFREG - 100000 普通(V7)
9000 S_IFCMP 110000 VxFS 壓縮
9000 S_IFNWK n 110000 網路特殊(HP-UX)
a000 S_IFLNK l@ 120000 符號連結(BSD)
b000 S_IFSHAD 130000 Solaris 陰影 inode,用於 ACL(使用者空間不可見)
c000 S_IFSOCK s= 140000 套接字(BSD;在 VxFS 上也稱為“S_IFSOC”)
d000 S_IFDOOR D> 150000 Solaris 門
e000 S_IFWHT w% 160000 BSD whiteout(不用於 inode)
0200 S_ISVTX 001000 粘滯位:即使在使用後也要儲存交換文字(V7)保留(SVID-v2)。在非目錄上:不要快取此檔案(SunOS)。在目錄上:限制刪除標誌(SVID-v4.2)
0400 S_ISGID 002000 執行時設定組 ID(V7)對於目錄:使用 BSD 語義來傳播 GID
0400 S_ENFMT 002000 SysV 檔案鎖定執行(與 S_ISGID 共享)
0800 S_ISUID 004000 執行時設定使用者 ID(V7)
0800 S_CDF 004000 目錄是上下文相關檔案(HP-UX)

粘滯命令出現在版本 32V AT&T UNIX 中。

成員型別

[編輯 | 編輯原始碼]

<sys/stat.h> 標頭檔案中定義的資料型別包括

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 file system I/O */
  blkcnt_t  st_blocks;  /* number of blocks allocated */
  time_t    st_atime;   /* time of last access */
  time_t    st_mtime;   /* time of last modification */
  time_t    st_ctime;   /* time of last status change */
};

<sys/stat.h> 的一個簡短示例

/**************************************************************
 abstract ls meaning
 **************************************************************/
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
  struct stat  file_stat;

  while (argc-- > 1)
    {
      if (lstat(argv[argc], &file_stat) == -1)
        fprintf(stderr, "%s\n", strerror(errno));
      else
        {
          fprintf(stdout, "Links\tUid\tGid\tSize\tName\n");
          fprintf(stdout, "%u\t%u\t%u\t%u\t%s\n", file_stat.st_nlink,
                  file_stat.st_uid, file_stat.st_gid, file_stat.st_size,
                  argv[argc]);
        }
    }
  return 0;
}

將原始碼放在一個檔案(main.c)中,並編譯它

 gcc main.c -o test

現在,要執行,請鍵入

 ./test main.c
 ./test *

參考資料

[編輯 | 編輯原始碼]
華夏公益教科書