C - open & flock & lseek

 

open 宣告及用法


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

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

flags 可代入的常用參數:
    O_RDWR (可讀可寫)
    O_WRONLY (只寫)
    O_RDONLY (唯讀)
    O_CREAT (不存在就建立)
        mode 可代入的參數:
                S_IRWXU 00700 user (file owner) has read, write, and execute permission
                S_IRUSR 00400 user has read permission
                S_IWUSR 00200 user has write permission
                S_IXUSR 00100 user has execute permission
                S_IRWXG 00070 group has read, write, and execute permission
                S_IRGRP 00040 group has read permission
                S_IWGRP 00020 group has write permission
                S_IXGRP 00010 group has execute permission
                S_IRWXO 00007 others have read, write, and execute permission
                S_IROTH 00004 others have read permission
                S_IWOTH 00002 others have write permission
                S_IXOTH 00001 others have execute permission
                According to POSIX, the effect when other bits are set in mode is unspecified. On Linux, the following bits are also honored in mode:
                S_ISUID 0004000 set-user-ID bit
                S_ISGID 0002000 set-group-ID bit (see inode(7)).
                S_ISVTX 0001000 sticky bit (see inode(7)).
    O_APPEND (以附加方式開啟)
    O_NOCTTY (這個程式不控制TTY介面)
    O_NONBLOCK (非阻塞式, 讀到檔尾回傳0, 讀失敗回傳-1並設定errnoEAGAIN)
    O_SYNC (同步相關,每次寫入都等待物理 IO 結束)

lags 可代入的其他參數:
    O_NDELAY (非阻塞式, 讀到檔尾回傳0, 讀失敗回傳0)
    O_ASYNC (同步相關, 使用信號驅動的IO)
    O_DSYNC (同步相關, 每次寫入都等待物理 IO 結束。但不含元信息, 僅保證文件內容寫入完畢)
    O_DIRECT (Direct IO 方式開啟)
    O_EXCL (檔案已存在就回傳失敗。需包含 O_CREATE 一併使用)
    O_DIRECTORY (開啟目錄,如果不是目錄會回傳失敗)
    O_NOFOLLOW (如果開啟的是 link 就回傳失敗)
    O_NOATIME(進行讀取操作時,不更新 access time)
    O_LARGEFILE (可開啟 2G 以上大檔,在 64bit 平台已是預設)
    O_CLOEXEC (執行 exec 函數族後,自動關閉此 fd)
    O_TRUNC (檔案開啟後,清空檔案內容)
    O_TMPFILE (建立臨時檔案,close後自動刪除,此時 pathname 要代入的是目錄路徑。可使用 linkat 建立檔名,造成保留效果)
        如:linkat(fd, "", AT_FDCWD, "Name", AT_EMPTY_PATH) or linkat(fd, path, AT_FDCWD, "Name", AT_SYMLINK_FOLLOW)
    O_PATH (只回傳文件描述符。回傳的fd可給close、fchdir、fstat...等使用,不可給read、write使用)

O_RDWR、O_WRONLY、O_RDONLY 這三個一定要選擇一項


flock 宣告及用法


#include <sys/file.h>

int flock(int fd, int operation);

operation 可代入參數:
    LOCK_SH (共用鎖。不需等待呼叫 LOCK_UN 也可在不同地方同時執行多次 LOCK_SH)
    LOCK_EX (獨佔鎖。先前已呼叫過 LOCK_SH or LOCK_EX 會在此等待呼叫 LOCK_UN 後,才繼續執行)
    LOCK_UN (解鎖)



lseek 宣告及用法


#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

whence 可代入參數:
    SEEK_SET (從頭開始加減 offset)
    SEEK_CUR (從目前位置開始加減 offset)
    SEEK_END (從尾開始加減 offset)
    SEEK_DATA (移動到 offset 的下一個 data 的位置, 版本 3.1 後才支援)
    SEEK_HOLE (移動到 offset 的下一個 hold 的位置, 版本 3.1 後才支援)

The SEEK_HOLE and SEEK_DATA operations are supported for the following filesystems:
    * Btrfs (since Linux 3.1)
    * OCFS (since Linux 3.2)
    * XFS (since Linux 3.5)
    * ext4 (since Linux 3.8)
    * tmpfs(5) (since Linux 3.8)
    * NFS (since Linux 3.18)
    * FUSE (since Linux 4.5)



範例


#include <sys/file.h>
#include <unistd.h>

int main(int argc, char **argv) {
int fd, offset = 0;
if ((fd = open("/var/data/.hs", O_CREAT | O_RDWR | O_NOCTTY | O_NDELAY)) > 0) {
flock(fd, LOCK_EX);
sleep(10);

lseek(fd, offset, SEEK_SET);
flock(fd, LOCK_UN);
sleep(10);

close(fd);
}
return 0;
}




沒有留言:

張貼留言