open

Header Files

#include <sys/types>
#include <sys/stat.h>
#include <fcntl.h>

Function Prototype

int open(const char*pathname, int oflag,/* mode_t mode */)
  • 回傳 file descriptor

Parameters

pathname

可以是 Absolute Path 或是 Relative Path

oflag

oflag 告訴系統:「我想要在這些檔案上做什麼操作?」

基本存取權限:

  • O_RDONLY - 只能讀取
  • O_WRONLY - 只能寫入
  • O_RDWR - 可讀可寫
  • O_EXEC - 可執行

檔案建立選項:

  • O_CREAT - 如果檔案不存在就建立它,如果存在就將其開啟
  • O_TRUNC - 開啟時將檔案內容清空
  • O_EXCL - 與 O_CREAT 配合使用,確保建立新檔案,如果檔案已存在變回傳-1表示打開失敗

特殊操作選項:

  • O_APPEND - 每次寫入都會自動移到檔案末端
  • O_NONBLOCK - 非阻塞模式,不會讓程式等待

資料同步

  • O_SYNC - 讓每次 write 都表現地像 fsync()
  • O_DSYNC - 讓每次 write 表現像 fdatasync()(不會管 metadata 的同步)
  • O_RSYNC - 在每次 read 之前,都確認 write 都已經 synchronize 了再 read

這些 oflag 被設計成可以用 OR 操作疊加

…/* mode_t mode */

當創建檔案我們就會需要指定這個,它代表這個新檔案的權限,跟 chmod 指定權限的方式相同

Example

int fd2 = open("new_file.txt", O_WRONLY | O_CREAT, 0644);
  • 如果在 cwd 下不存在 new_file.txt ,建立 new_file.txt
  • new_file.txt 的權限設為 644
  • 此次開啟我們要有讀和寫能力

0644的 0 只是表示後面數值為八進位


openat

Function Prototype

int openat(int dirfd, const char*pathname, int oflag,)
  • 除了 dirfd 都和 open 一樣

Parameters

dirfd

dirfd 是一個指向 Directory 的 file descriptor,我們的 pathname 如果是 relative path,就會從 dirfd 指向的 Directory 開始往下找

open = openat

有兩個狀況 open 會和 openat 一樣

  1. pathname 用 Absolute Path 決定
  2. dirfd == AT_FDCWD

Time-of-check-to-time-of-use (TOCTTOU)

open 中,我們需要一步步按照 pathname 的路徑尋找我們要的檔案,但在尋找過程中路徑可能被其他並行的 Process 更改,造成我們出現 error,而 file descriptor 可以保證我們訪問的是當時 open 的那個 directory,所以 openat 透過 dirfd 矛定一個 directory 讓我們可以安全的操作

Example

// 假設你需要在同一個目錄中處理多個檔案
int data_dir = open("/var/app/data", O_RDONLY);
 
// 在同一個目錄中進行多個操作,都相對於穩定的 data_dir
int input_fd = openat(data_dir, "input.txt", O_RDONLY);
int output_fd = openat(data_dir, "output.txt", O_WRONLY | O_CREAT, 0644);