了解Linux命令打開

概要

#include << A HREF =“file:/usr/include/sys/types.h”> sys / types.h> #include << A HREF =“file:/usr/include/sys/stat.h”> sys / stat.h> #include << A HREF =“file:/usr/include/fcntl.h”> fcntl.h> int open(const char * pathname ,int flags ); int open(const char * pathname ,int flags ,mode_t mode ); int creat(const char * pathname ,mode_t mode );

描述

open()系統調用linux 命令用於將路徑名轉換為文件描述符(用於後續I / O的小型非負整數,如讀取寫入等)。 當調用成功時,返回的文件描述符將是當前未打開的最低文件描述符。 此調用會創建一個新的打開文件,不會與任何其他進程共享。 (但共享打開的文件可能通過fork (2)系統調用產生)。新的文件描述符被設置為在exec函數中保持打開狀態(請參閱fcntl (2))。 文件偏移量被設置為文件的開頭。

參數標誌O_RDONLYO_WRONLYO_RDWR中的一個, 它們分別請求以只讀,只寫或讀/寫方式打開文件,按位 'd分別具有以下零個或多個:

O_CREAT

如果文件不存在,它將被創建。 文件的所有者(用戶標識)被設置為進程的有效用戶標識。 組所有權(組ID)設置為進程的有效組標識或父目錄的組標識(取決於文件​​系統類型和安裝選項,以及父目錄的模式,請參閱,例如,安裝如mount (8)中所述,選擇ext2文件系統的bsdgroupssysvgroups )。

O_EXCL

當與O_CREAT一起使用時,如果該文件已經存在,則是錯誤,並且打開將失敗。 在這種情況下,存在一個符號鏈接,無論它指向何處。 O_EXCLNFS文件系統上被破壞,依靠它執行鎖定任務的程序將包含競爭條件。 使用lockfile執行原子文件鎖定的解決方案是在同一個fs上創建一個唯一文件(例如,包含hostname和pid),使用link (2)創建一個到lockfile的鏈接。 如果link()返回0,則鎖定成功。 否則,在唯一文件上使用stat (2)來檢查其鏈接計數是否增加到2,在這種情況下,鎖定也是成功的。

O_NOCTTY

如果路徑名指的是終端設備,請參見tty (4)---即使進程沒有控制終端,它也不會成為進程的控制終端。

O_TRUNC

如果文件已經存在並且是一個常規文件,並且打開模式允許寫入(即,是O_RDWR或O_WRONLY),則它將被截斷為長度0.如果文件是FIFO或終端設備文件,則忽略O_TRUNC標誌。 否則,O_TRUNC的效果未指定。 (在許多Linux 版本中 ,它將被忽略;在其他版本上,它將返回一個錯誤。)

O_APPEND

該文件以附加模式打開。 在每次寫入之前,文件指針位於文件的末尾,就像使用lseek一樣 。 如果多個進程一次將數據附加到文件,則O_APPEND可能會導致NFS文件系統上的文件損壞。 這是因為NFS不支持附加到文件,因此客戶端內核必須對其進行模擬,這在沒有競爭條件的情況下不能完成。

O_NONBLOCKO_NDELAY

如果可能,文件以非阻塞模式打開。 對於返回的文件描述符的開放或後續操作都不會導致調用進程等待。 有關FIFO(命名管道)的處理,另請參閱fifo (4)。 此模式不需要對除FIFOs以外的文件有任何影響。

O_SYNC

該文件為同步I / O打開。 結果文件描述符上的任何操作都會阻止調用進程,直到數據被物理寫入底層硬件。 儘管如此,請參閱下面的限制。

O_NOFOLLOW

如果路徑名是符號鏈接,則打開失敗。 這是一個FreeBSD擴展,它在2.1.126版本中加入了Linux。 路徑名早期組件中的符號鏈接仍將被遵循。 glibc 2.0.100及更高版本的頭文件包含此標誌的定義; 如果使用的話,2.1.126之前的內核將忽略它

O_DIRECTORY

如果路徑名不是目錄,則導致打開失敗。 該標誌是特定於Linux的標誌,並在內核版本2.1.126中添加,以避免在FIFO或磁帶設備上調用opendir (3)時出現拒絕服務問題,但不應在opendir的實現之外使用。

O_DIRECT

盡量減少I / O對這個文件的緩存效應。 一般而言,這會降低性能,但在特殊情況下非常有用,例如應用程序執行自己的緩存時。 文件I / O直接進入/來自用戶空間緩衝區。 I / O是同步的,即在完成讀取 (2)或寫入 (2)系統調用時,保證數據已被傳輸。 傳輸大小以及用戶緩衝區和文件偏移的對齊方式都必須是文件系統邏輯塊大小的倍數。
這個標誌在許多類Unix系統上受到支持; 在內核版本2.4.10的Linux下添加了支持。
原始 (8)中描述了用於塊設備的語義上相似的接口。

O_ASYNC

當輸入或輸出成為可能時,生成一個信號(默認為SIGIO,但可以通過fcntl (2)更改此文件描述符。 該功能僅適用於終端,偽終端和套接字。 有關更多詳細信息,請參閱fcntl (2)。

O_LARGEFILE

在支持大文件系統的32位系統上,允許打開其大小不能用31位表示的文件。

文件打開後,可以使用fcntl修改其中一些可選標誌。

參數模式指定在創建新文件的情況下使用的權限。 它以通常的方式被進程的umask修改:創建的文件的權限是(mode&〜umask) 。 請注意,此模式僅適用於新創建的文件的未來訪問; 創建只讀文件的公開調用可能會返回讀/寫文件描述符。

模式提供以下符號常量:

S_IRWXU

00700用戶(文件所有者)具有讀取,寫入和執行權限

S_IRUSR(S_IREAD)

00400用戶具有讀取權限

S_IWUSR(S_IWRITE)

00200用戶有寫入權限

S_IXUSR(S_IEXEC)

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其他人有執行權限

模式必須在O_CREAT位於標誌中時指定,否則將被忽略。

creat等同於使用等於O_CREAT | O_WRONLY | O_TRUNC的 標誌 打開

返回值

opencreat返回新的文件描述符,如果發生錯誤,則返回-1(在這種情況下,適當地設置errno )。 請注意, open可以打開設備專用文件,但creat不能創建它們 - 請改用mknod (2)。

在啟用了UID映射的NFS文件系統上, open可能會返回一個文件描述符,但例如read (2)請求會被EACCES拒絕。 這是因為客戶端通過檢查權限來執行打開操作,但UID映射是由服務器在讀取和寫入請求時執行的。

如果該文件是新創建的,則其atime,ctime,mtime字段將設置為當前時間,父目錄的ctime和mtime字段也將設置為當前時間。 否則,如果文件由於O_TRUNC標誌而被修改,則它的ctime和mtime字段被設置為當前時間。

錯誤

EEXIST

路徑名已經存在,並且使用了O_CREATO_EXCL

EISDIR

路徑名指的是一個目錄,並且所請求的訪問涉及寫入(即設置了O_WRONLYO_RDWR )。

EACCES

不允許請求訪問該文件,或路徑名中的某個目錄不允許搜索(執行)權限,或該文件尚不存在,並且不允許對父目錄執行寫入訪問。

ENAMETOOLONG

路徑名太長。

ENOENT

O_CREAT未設置,並且指定的文件不存在。 或者, 路徑名中的目錄組件不存在,或者是懸掛的符號鏈接。

ENOTDIR

用作路徑名中目錄的組件實際上不是目錄,或者指定了O_DIRECTORY ,而路徑名不是目錄。

ENXIO

O_NONBLOCK | O_WRONLY被設置,指定的文件是一個FIFO並且沒有進程打開文件讀取。 或者,該文件是設備專用文件,並且不存在相應的設備。

ENODEV

路徑名是指設備專用文件,不存在相應的設備。 (這是一個Linux內核錯誤 - 在這種情況下,必須返回ENXIO。)

EROFS

路徑名是指只讀文件系統上的一個文件,並要求寫訪問。

ETXTBSY

路徑名是指當前正在執行的可執行映像,並請求寫入訪問權限。

EFAULT

您可訪問的地址空間之外的路徑名點。

ELOOP

在解析路徑名時遇到過多符號鏈接,或者指定了O_NOFOLLOW ,但路徑名是符號鏈接。

ENOSPC

路徑名被創建,但包含路徑名的設備沒有空間存放新文件。

ENOMEM

內核內存不足可用。

EMFILE

該過程已經打開了最大數量的文件。

ENFILE

系統上打開的文件總數已達到限制。

符合

SVr4,SVID,POSIX,X / OPEN,BSD 4.3 O_NOFOLLOWO_DIRECTORY標誌是特定於Linux的標誌。 可能需要定義_GNU_SOURCE宏來獲取它們的定義。

限制

基於NFS的協議有許多不足之處,其中包括O_SYNCO_NDELAY

POSIX提供了三種不同的同步I / O變量,對應於標誌O_SYNCO_DSYNCO_RSYNC 。 目前(2.1.130)這些在Linux下都是同義詞。