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 一樣
- pathname 用 Absolute Path 決定
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);