open(2)

Från Wiki.linux.se
Version från den 22 november 2024 kl. 08.47 av Admin (diskussion | bidrag) (→‎O_PATH (sedan Linux 2.6.39))
(skillnad) ← Äldre version | Nuvarande version (skillnad) | Nyare version → (skillnad)
Hoppa till navigering Hoppa till sök

open(2) — Linux Manual

NAMN

open, openat, creat – öppna och eventuellt skapa en fil

BIBLIOTEK

Standard C-bibliotek (libc, -lc)

SYNOPSIS

#include <fcntl.h>

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

int creat(const char *pathname, mode_t mode);

int openat(int dirfd, const char *pathname, int flags, ...
           /* mode_t mode */ );

/* Dokumenterad separat, i openat2(2): */
int openat2(int dirfd, const char *pathname,
           const struct open_how *how, size_t size);

Funktionskrav för glibc (se feature_test_macros(7))

openat():

  • Sedan glibc 2.10:
    • `_POSIX_C_SOURCE >= 200809L`
  • Före glibc 2.10:
    • `_ATFILE_SOURCE`

BESKRIVNING

`open()` systemanropet öppnar filen specificerad av pathname. Om den angivna filen inte finns, kan den eventuellt (om O_CREAT specificeras i flags) skapas av `open()`.

Returvärdet av `open()` är en filbeskrivare, ett litet, icke-negativt heltal som är en index till en post i processens tabell över öppna filbeskrivare. Filbeskrivaren används i efterföljande systemanrop (som `read(2)`, `write(2)`, `lseek(2)`, `fcntl(2)` etc.) för att referera till den öppna filen. Filbeskrivaren som returneras av ett framgångsrikt anrop kommer att vara den lägsta numrerade filbeskrivaren som inte är öppen för processen.

Som standard är den nya filbeskrivaren inställd på att förbli öppen över en `execve(2)` (dvs. `FD_CLOEXEC`-flaggan i filbeskrivaren är initialt inaktiverad); `O_CLOEXEC`-flaggan, beskrivs nedan, kan användas för att ändra detta standardbeteende. Filoffseten är inställd till början av filen (se `lseek(2)`).

Ett anrop till `open()` skapar en ny öppen filbeskrivning, en post i det systemomfattande bordet över öppna filer. Den öppna filbeskrivningen registrerar filoffseten och filstatusflaggorna (se nedan). En filbeskrivare är en referens till en öppen filbeskrivning; denna referens påverkas inte om `pathname` senare tas bort eller ändras för att referera till en annan fil. För ytterligare detaljer om öppna filbeskrivningar, se NOTER.

Argumentet flags måste inkludera en av följande åtkomstlägen: `O_RDONLY`, `O_WRONLY`, eller `O_RDWR`. Dessa begär att filen öppnas som endast läsbar, endast skrivbar, eller läs-/skrivbar, respektive.

Dessutom kan noll eller fler filskapande flaggor och filstatusflaggor bitvis kombineras i flags. Filskapande flaggor inkluderar `O_CLOEXEC`, `O_CREAT`, `O_DIRECTORY`, `O_EXCL`, `O_NOCTTY`, `O_NOFOLLOW`, `O_TMPFILE`, och `O_TRUNC`. Filstatusflaggorna är alla de återstående flaggorna listade nedan. Skillnaden mellan dessa två grupper av flaggor är att filskapande flaggorna påverkar semantiken för själva öppningsoperationen, medan filstatusflaggorna påverkar semantiken för efterföljande I/O-operationer. Filstatusflaggorna kan hämtas och (i vissa fall) ändras; se `fcntl(2)` för detaljer.

Fullständig lista över filskapande flaggor och filstatusflaggor

O_APPEND

Filen öppnas i append-läge. Innan varje `write(2)` placeras filoffseten i slutet av filen, som om med `lseek(2)`. Modifieringen av filoffseten och skrivoperationen utförs som ett enda atomärt steg.

`O_APPEND` kan leda till korrupta filer på NFS-filsystem om mer än en process samtidigt lägger till data i en fil. Detta beror på att NFS inte stöder append-operationer direkt, så klientkärnan måste simulera detta, vilket inte kan göras utan ett race condition.

O_ASYNC

Aktivera signalstyrd I/O: generera en signal (`SIGIO` som standard, men detta kan ändras via `fcntl(2)`) när inmatning eller utmatning blir möjlig på denna filbeskrivare. Denna funktion är endast tillgänglig för terminaler, pseudoterminaler, sockets och (sedan Linux 2.6) pipes och FIFOs. Se `fcntl(2)` för ytterligare detaljer. Se även BUGGAR nedan.

O_CLOEXEC (sedan Linux 2.6.23)

Aktivera `close-on-exec`-flaggan för den nya filbeskrivaren. Att specificera denna flagga tillåter ett program att undvika ytterligare `fcntl(2)` `F_SETFD` operationer för att sätta `FD_CLOEXEC`-flaggan.

Observera att användningen av denna flagga är essentiell i vissa multitrådade program, eftersom användning av en separat `fcntl(2)` `F_SETFD` operation för att sätta `FD_CLOEXEC`-flaggan inte räcker för att undvika race conditions där en tråd öppnar en filbeskrivare och försöker sätta dess `close-on-exec` flagga samtidigt som en annan tråd utför en `fork(2)` plus `execve(2)`. Beroende på exekveringsordningen kan race conditions leda till att filbeskrivaren som returneras av `open()` av misstag läcks till programmet som exekveras av barnprocessen skapad av `fork(2)`. (Denna typ av race är i princip möjlig för alla systemanrop som skapar en filbeskrivare vars `close-on-exec` flagga ska vara inställd, och olika andra Linux-systemanrop tillhandahåller en ekvivalent av `O_CLOEXEC` flaggan för att hantera detta problem.)

O_CREAT

Om pathname inte finns, skapa den som en vanlig fil.

Ägaren (användar-ID) för den nya filen sätts till processens effektiva användar-ID.

Gruppägarskapet (grupp-ID) för den nya filen sätts antingen till processens effektiva grupp-ID (System V-semantik) eller till grupp-ID för överordnad katalog (BSD-semantik). På Linux beror beteendet på om set-group-ID mode-bit är satt på överordnad katalog: om den biten är satt, tillämpas BSD-semantik; annars tillämpas System V-semantik. För vissa filsystem beror beteendet även på `bsdgroups` och `sysvgroups` monteringsalternativen beskrivna i `mount(8)`.

Argumentet mode specificerar filens modibitar som ska tillämpas när en ny fil skapas. Om varken `O_CREAT` eller `O_TMPFILE` specificeras i flags, ignoreras mode (och kan således specificeras som 0, eller helt enkelt utelämnas). mode-argumentet måste ges om `O_CREAT` eller `O_TMPFILE` specificeras i flags; om det inte ges, kommer några godtyckliga bytes från stacken att tillämpas som filens modus.

Den effektiva mode modifieras av processens umask på det vanliga sättet: i frånvaro av ett standard-ACL, är filens mode som skapades `(mode & ~umask)`.

Observera att mode endast gäller för framtida åtkomster av den nyss skapade filen; ett `open()`-anrop som skapar en skrivskyddad fil kan ändå returnera en läs-/skrivbar filbeskrivare.

Följande symboliska konstanter tillhandahålls för mode:

  • `S_IRWXU` 00700 – användaren (filägaren) har läs-, skriv- och exekveringsbehörighet
  • `S_IRUSR` 00400 – användaren har läsbehörighet
  • `S_IWUSR` 00200 – användaren har skrivbehörighet
  • `S_IXUSR` 00100 – användaren har exekveringsbehörighet
  • `S_IRWXG` 00070 – gruppen har läs-, skriv- och exekveringsbehörighet
  • `S_IRGRP` 00040 – gruppen har läsbehörighet
  • `S_IWGRP` 00020 – gruppen har skrivbehörighet
  • `S_IXGRP` 00010 – gruppen har exekveringsbehörighet
  • `S_IRWXO` 00007 – övriga har läs-, skriv- och exekveringsbehörighet
  • `S_IROTH` 00004 – övriga har läsbehörighet
  • `S_IWOTH` 00002 – övriga har skrivbehörighet
  • `S_IXOTH` 00001 – övriga har exekveringsbehörighet

Enligt POSIX är effekten när andra bitar är satta i mode ospecificerad. På Linux respekteras följande bitar också i mode:

  • `S_ISUID` 0004000 – set-user-ID bit
  • `S_ISGID` 0002000 – set-group-ID bit (se `inode(7)`)
  • `S_ISVTX` 0001000 – sticky bit (se `inode(7)`)

O_DIRECT (sedan Linux 2.4.10)

Försök att minimera cacheeffekterna av I/O till och från denna fil. Generellt kommer detta att försämra prestandan, men det är användbart i speciella situationer, som när applikationer gör sin egen caching. Fil-I/O utförs direkt till/från användarutrymmet. `O_DIRECT` flaggan ensam gör ett försök att överföra data synkront, men ger inte garantierna för `O_SYNC` flaggan att data och nödvändig metadata överförs. För att garantera synkron I/O måste `O_SYNC` användas tillsammans med `O_DIRECT`. Se NOTER nedan för vidare diskussion.

En semantiskt liknande (men föråldrad) gränssnitt för blockenheter beskrivs i `raw(8)`.

O_DIRECTORY

Om pathname inte är en katalog, får öppningen att misslyckas. Denna flagga lades till i Linux 2.1.126 för att undvika denial-of-service problem om `opendir(3)` anropas på en FIFO eller bandenhet.

O_DSYNC

Skrivoperationer på filen kommer att slutföras enligt kraven för synkroniserad I/O datasäkerhetskomplettering.

När `write(2)` (och liknande) returnerar har utdata överförts till den underliggande hårdvaran, tillsammans med all filmetadata som krävs för att hämta dessa data (dvs. som om varje `write(2)` följdes av ett anrop till `fdatasync(2)`). Se NOTER nedan.

O_EXCL

Säkerställ att detta anrop skapar filen: om denna flagga specificeras tillsammans med `O_CREAT`, och pathname redan finns, misslyckas `open()` med felet `EEXIST`.

När dessa två flaggor specificeras följs symboliska länkar inte: om pathname är en symbolisk länk, misslyckas `open()` oavsett var den symboliska länken pekar.

Generellt är beteendet för `O_EXCL` ospecificerat om det används utan `O_CREAT`. Det finns ett undantag: på Linux 2.6 och senare kan `O_EXCL` användas utan `O_CREAT` om pathname refererar till en blockenhet. Om blockenheten används av systemet (t.ex. den är monterad), misslyckas `open()` med felet `EBUSY`.

På NFS stöds `O_EXCL` endast när NFSv3 eller senare används på kärna 2.6 eller senare. I NFS-miljöer där `O_EXCL`-stöd inte tillhandahålls, kommer program som förlitar sig på det för att utföra låsningsuppgifter att innehålla en race condition. Portabla program som vill utföra atomisk fil-låsning med hjälp av en låsfil, och behöver undvika beroende av NFS-stöd för `O_EXCL`, kan skapa en unik fil på samma filsystem (t.ex. genom att inkorporera värdnamn och PID) och använda `link(2)` för att länka till låsfilen. Om `link(2)` returnerar 0 är låset lyckat. Annars, använd `stat(2)` på den unika filen för att kontrollera om dess länkantal har ökat till 2, i vilket fall låset också är lyckat.

O_LARGEFILE

(LFS) Tillåt filer vars storlekar inte kan representeras i en `off_t` (men kan representeras i en `off64_t`) att öppnas. Makrot `_LARGEFILE64_SOURCE` måste definieras (före inklusion av några header-filer) för att erhålla denna definition. Att sätta `_FILE_OFFSET_BITS` feature test makrot till 64 (i stället för att använda `O_LARGEFILE`) är den föredragna metoden för att få åtkomst till stora filer på 32-bitars system (se `feature_test_macros(7)`).

O_NOATIME (sedan Linux 2.6.8)

Uppdatera inte filens senaste åtkomsttid (`st_atime` i inode) när filen läses (`read(2)`).

Denna flagga kan endast användas om ett av följande villkor är uppfyllt:

  • Den effektiva UID för processen matchar ägar UID för filen.
  • Den anropande processen har `CAP_FOWNER` kapabiliteten i sitt användarnamnutrymme och ägar UID för filen har en mapping i namnutrymmet.

Denna flagga är avsedd för användning av indexerings- eller backupprogram, där dess användning kan avsevärt minska mängden diskaktivitet. Denna flagga kanske inte är effektiv på alla filsystem. Ett exempel är NFS, där servern hanterar åtkomsttiden.

O_NOCTTY

Om pathname refererar till en terminalenhet—se `tty(4)`—kommer den inte att bli processens styrande terminal även om processen inte har en sådan.

O_NOFOLLOW

Om den sista komponenten (dvs. basename) av pathname är en symbolisk länk, misslyckas öppningen med felet `ELOOP`. Symboliska länkar i tidigare komponenter av pathname kommer fortfarande att följas. (Observera att `ELOOP` felet som kan uppstå i detta fall är odifferentierbart från fallet där en öppning misslyckas eftersom det finns för många symboliska länkar hittade under upplösningen av komponenter i prefixdelen av pathname.)

Denna flagga är en FreeBSD-tillägg, som lades till i Linux 2.1.126 och har sedan standardiserats i POSIX.1-2008.

Se även O_PATH nedan.

O_NONBLOCK eller O_NDELAY

När möjligt öppnas filen i icke-blockerande läge. Varken `open()` eller några efterföljande I/O-operationer på den returnerade filbeskrivaren kommer att få den anropande processen att vänta.

Observera att inställningen av denna flagga inte har någon effekt på operationen av `poll(2)`, `select(2)`, `epoll(7)` och liknande, eftersom dessa gränssnitt endast informerar anroparen om huruvida en filbeskrivare är "redo", vilket innebär att en I/O-operation utförd på filbeskrivaren med `O_NONBLOCK` flaggan avstängd inte skulle blockera.

Observera att denna flagga inte har någon effekt för vanliga filer och blockenheter; det vill säga I/O-operationer kommer (kortvarigt) att blockera när enhetsaktivitet krävs, oavsett om `O_NONBLOCK` är satt. Eftersom `O_NONBLOCK` semantik eventuellt kan implementeras, bör applikationer inte förlita sig på blockerande beteende när de specificerar denna flagga för vanliga filer och blockenheter.

För hantering av FIFOs (nämnda rör), se även `fifo(7)`. För en diskussion om effekten av `O_NONBLOCK` i kombination med obligatoriska fil-lås och med fil-leases, se `fcntl(2)`.

O_PATH (sedan Linux 2.6.39)

Erhåll en filbeskrivare som kan användas för två ändamål: att indikera en plats i filsystemsträdet och för att utföra operationer som endast verkar på filbeskrivarnivå. Filen själv öppnas inte, och andra file-operationer (t.ex. `read(2)`, `write(2)`, `fchmod(2)`, `fchown(2)`, `fgetxattr(2)`, `ioctl(2)`, `mmap(2)`) misslyckas med felet `EBADF`.

Följande operationer kan utföras på den resulterande filbeskrivaren:

  • `close(2)`
  • `fchdir(2)`, om filbeskrivaren refererar till en katalog (sedan Linux 3.5)
  • `fstat(2)` (sedan Linux 3.6)
  • `fstatfs(2)` (sedan Linux 3.12)
  • Duplicera filbeskrivaren (`dup(2)`, `fcntl(2) F_DUPFD` etc.)
  • Hämta och sätta filbeskrivarflaggor (`fcntl(2) F_GETFD` och `F_SETFD`)
  • Hämta öppna filstatusflaggor med `fcntl(2) F_GETFL` operationen: de returnerade flaggorna kommer att inkludera biten `O_PATH`.
  • Passera filbeskrivaren som dirfd argumentet för `openat()` och andra "*at()" systemanrop. Detta inkluderar `linkat(2)` med `AT_EMPTY_PATH` (eller via procfs med `AT_SYMLINK_FOLLOW`) även om filen inte är en katalog.
  • Passera filbeskrivaren till en annan process via en UNIX-domän socket (se `SCM_RIGHTS` i `unix(7)`).

När `O_PATH` specificeras i flags, ignoreras flaggbitar förutom `O_CLOEXEC`, `O_DIRECTORY`, och `O_NOFOLLOW`.

Att öppna en fil eller katalog med `O_PATH` flaggan kräver inga behörigheter på objektet självt (men kräver exekveringsbehörighet på katalogerna i sökvägs-prefix). Beroende på efterföljande operation kan en kontroll av lämpliga filbehörigheter utföras (t.ex. kräver `fchdir(2)` exekveringsbehörighet på katalogen som refereras av dess filbeskrivarargument). I kontrast kräver erhållandet av en referens till ett filsystemobjekt genom att öppna det med `O_RDONLY` flaggan att anroparen har läsbehörighet på objektet, även när den efterföljande operationen (t.ex. `fchdir(2)`, `fstat(2)`) inte kräver läsbehörighet på objektet.

Om pathname är en symbolisk länk och `O_NOFOLLOW` flaggan också specificeras, returnerar anropet en filbeskrivare som refererar till den symboliska länken. Denna filbeskrivare kan användas som dirfd argument i anrop till `fchownat(2)`, `fstatat(2)`, `linkat(2)` och `readlinkat(2)` med en tom sökväg för att få anropen att verka på den symboliska länken.

Om pathname refererar till en automount-punkt som ännu inte har triggas, så att inget annat filsystem är monterat på den, returnerar anropet en filbeskrivare som refererar till automount-katalogen utan att trigga en mount. `fstatfs(2)` kan då användas för att avgöra om det faktiskt är en otriggerad automount-punkt (`.f_type == AUTOFS_SUPER_MAGIC`).

Ett användningsområde för `O_PATH` för vanliga filer är att tillhandahålla ekvivalenten av POSIX.1's `O_EXEC` funktionalitet. Detta tillåter oss att öppna en fil för vilken vi har exekveringsbehörighet men inte läsbehörighet, och sedan exekvera den filen, med steg ungefär som följande:

char buf[PATH_MAX];
fd = open("some_prog", O_PATH);
snprintf(buf, PATH_MAX, "/proc/self/fd/%d", fd);
execl(buf, "some_prog", (char *) NULL);

En `O_PATH` filbeskrivare kan också passeras som argumentet till `fexecve(3)`.

RETURVÄRDE

Vid framgång, returnerar `open()`, `openat()`, och `creat()` den nya filbeskrivaren (ett icke-negativt heltal). Vid fel returneras `-1` och `errno` sätts för att indikera felet.

FEL

`open()`, `openat()`, och `creat()` kan misslyckas med följande fel:

  • EACCES Den begärda åtkomsten till filen är inte tillåten, eller sökbehörighet nekas för en av katalogerna i sökvägs-prefixet av pathname, eller filen existerade inte ännu och skrivåtkomst till föräldrakatalogen är inte tillåten. (Se även `path_resolution(7)`.)
  • EACCES Där `O_CREAT` specificeras, `protected_fifos` eller `protected_regular` sysctl är aktiverat, filen existerar redan och är en FIFO eller vanlig fil, ägaren av filen är varken den aktuella användaren eller ägaren av innehållande katalog, och innehållande katalog är både värld- eller gruppskrivbar och sticky. För detaljer, se beskrivningarna av `/proc/sys/fs/protected_fifos` och `/proc/sys/fs/protected_regular` i `proc_sys_fs(5)`.
  • EBADF (`openat()`) pathname är relativ men dirfd är varken `AT_FDCWD` eller en giltig filbeskrivare.
  • EBUSY `O_EXCL` specificerades i flags och pathname refererar till en blockenhet som används av systemet (t.ex. den är monterad).
  • EDQUOT Där `O_CREAT` specificeras, filen existerar inte, och användarens kvot för diskblock eller inoder på filsystemet har blivit uttömt.
  • EEXIST pathname existerar redan och `O_CREAT` och `O_EXCL` användes.
  • EFAULT pathname pekar utanför din tillgängliga adressutrymme.
  • EFBIG Se `EOVERFLOW`.
  • EINTR Medan den blockerade väntade på att slutföra en öppning av en långsam enhet (t.ex. en FIFO; se `fifo(7)`), avbröts anropet av en signalhanterare; se `signal(7)`.
  • EINVAL Filsystemet stöder inte `O_DIRECT` flaggan. Se NOTER för mer information.
  • EINVAL Ogiltigt värde i flags.
  • EINVAL `O_TMPFILE` specificerades i flags, men varken `O_WRONLY` eller `O_RDWR` specificerades.
  • EINVAL `O_CREAT` specificerades i flags och den sista komponenten ("basename") av den nya filens sökväg är ogiltig (t.ex. den innehåller tecken som inte tillåts av det underliggande filsystemet).
  • EINVAL Den sista komponenten ("basename") av pathname är ogiltig (t.ex. den innehåller tecken som inte tillåts av det underliggande filsystemet).
  • EISDIR pathname refererar till en katalog och den begärda åtkomsten innebar skrivning (dvs. `O_WRONLY` eller `O_RDWR` är satt).
  • EISDIR pathname refererar till en existerande katalog, `O_TMPFILE` och en av `O_WRONLY` eller `O_RDWR` specificerades i flags, men denna kärnversion tillhandahåller inte `O_TMPFILE` funktionaliteten.
  • ELOOP För många symboliska länkar hittades vid upplösning av pathname.
  • ELOOP pathname var en symbolisk länk, och flags specificerade `O_NOFOLLOW` men inte `O_PATH`.
  • EMFILE Den per-process gränsen för antalet öppna filbeskrivare har nåtts (se beskrivning av `RLIMIT_NOFILE` i `getrlimit(2)`).
  • ENAMETOOLONG pathname var för lång.
  • ENFILE Systemomfattande gränsen för totala öppna filer har nåtts.
  • ENODEV pathname refererar till en enhetsfil och ingen motsvarande enhet existerar. (Detta är ett Linux kärnbugg; i detta fall måste `ENXIO` returneras.)
  • ENOENT `O_CREAT` är inte satt och den namngivna filen existerar inte.
  • ENOENT En katalogkomponent i pathname existerar inte eller är en hängande symbolisk länk.
  • ENOENT pathname refererar till en icke-existerande katalog, `O_TMPFILE` och en av `O_WRONLY` eller `O_RDWR` specificerades i flags, men denna kärnversion tillhandahåller inte `O_TMPFILE` funktionaliteten.
  • ENOMEM Den namngivna filen är en FIFO, men minne för FIFO-bufferten kan inte allokeras eftersom den per-användar hårda gränsen för minnesallokering för rör har nåtts och anroparen inte är privilegierad; se `pipe(7)`.
  • ENOMEM Otillräckligt kärnminne var tillgängligt.
  • ENOSPC pathname skulle skapas men enheten som innehåller pathname har inget utrymme för den nya filen.
  • ENOTDIR
    • - En komponent som används som en katalog i pathname är inte, i själva verket, en katalog, eller `O_DIRECTORY` specificerades och pathname var inte en katalog.
    • - (`openat()`) pathname är en relativ sökväg och dirfd är en filbeskrivare som refererar till en fil annan än en katalog.
  • ENXIO
    • - `O_NONBLOCK | O_WRONLY` är satt, den namngivna filen är en FIFO, och ingen process har FIFO:n öppen för läsning.
    • - Filen är en enhetsfil och ingen motsvarande enhet existerar.
    • - Filen är en UNIX-domän socket.
  • EOPNOTSUPP Filsystemet som innehåller pathname stöder inte `O_TMPFILE`.
  • EOVERFLOW pathname refererar till en vanlig fil som är för stor för att öppnas. Den vanliga scenariot här är att en applikation kompilerad på en 32-bitars plattform utan `-D_FILE_OFFSET_BITS=64` försökte öppna en fil vars storlek överstiger `(1<<31)-1` bytes; se även `O_LARGEFILE` ovan. Detta är felet specificerat av POSIX.1; före Linux 2.6.24 gav Linux felet `EFBIG` för detta fall.
  • EPERM
    • - `O_NOATIME` flaggan specificerades, men den effektiva användar-ID:n för anroparen matchade inte ägaren av filen och anroparen var inte privilegierad.
    • - Operationen förhindrades av en filtäckel; se `fcntl(2)`.
  • EROFS pathname refererar till en fil på ett skrivskyddat filsystem och skrivåtkomst begärdes.
  • ETXTBSY
    • - `pathname` refererar till en exekverbar bild som för närvarande exekveras och skrivåtkomst begärdes.
    • - `pathname` refererar till en fil som för närvarande används som en swap-fil, och `O_TRUNC` flaggan specificerades.
    • - `pathname` refererar till en fil som för närvarande läses av kärnan (t.ex. för modul/firmware-laddning), och skrivåtkomst begärdes.
  • EWOULDBLOCK `O_NONBLOCK` flaggan specificerades, och en inkompatibel lease hölls på filen (se `fcntl(2)`).

VERSIONER

Effekten av `O_RDONLY | O_TRUNC` varierar mellan olika implementeringar. På många system trunkeras filen faktiskt.

Synkroniserad I/O

POSIX.1-2008 "synkroniserad I/O" alternativet specificerar olika varianter av synkroniserad I/O, och specificerar `open()` flaggorna `O_SYNC`, `O_DSYNC`, och `O_RSYNC` för att kontrollera beteendet. Oavsett om en implementering stöder detta alternativ, måste den åtminstone stödja användningen av `O_SYNC` för vanliga filer.

Linux implementerar `O_SYNC` och `O_DSYNC`, men inte `O_RSYNC`. Något felaktigt definierar glibc `O_RSYNC` till att ha samma värde som `O_SYNC`. (`O_RSYNC` definieras i Linux headerfilen `<asm/fcntl.h>` på HP PA-RISC, men den används inte.)

`O_SYNC` tillhandahåller synkroniserad I/O filintegritetskomplettering, vilket innebär att skrivoperationer kommer att flush data och all associerad metadata till den underliggande hårdvaran. `O_DSYNC` tillhandahåller synkroniserad I/O datasäkerhetskomplettering, vilket innebär att skrivoperationer kommer att flush data till den underliggande hårdvaran, men endast flush metadatauppdateringar som krävs för att en efterföljande läsoperation ska kunna slutföras framgångsrikt. Datasäkerhetskomplettering kan minska antalet diskoperationer som krävs för applikationer som inte behöver garantierna för filintegritetskomplettering.

För att förstå skillnaden mellan de två typerna av komplettering, överväg två delar av filmetadata: filens senaste ändringstidstämpel (`st_mtime`) och filens längd. Alla skrivoperationer kommer att uppdatera filens senaste ändringstidstämpel, men endast skrivningar som lägger till data i slutet av filen kommer att ändra filens längd. Den senaste ändringstidstämpeln behövs inte för att säkerställa att en läsning slutförs framgångsrikt, men filens längd gör det. Således skulle `O_DSYNC` endast garantera att flush uppdateringar till filens längdmetadata (däras `O_SYNC` skulle också alltid flush senaste ändringstidstämpeln metadata).

Före Linux 2.6.33 implementerade Linux endast `O_SYNC` flaggan för `open()`. Men när den flaggan specificerades, tillhandahöll de flesta filsystemen faktiskt ekvivalenten av synkroniserad I/O datasäkerhetskomplettering (dvs. `O_SYNC` implementerades faktiskt som ekvivalenten av `O_DSYNC`).

Sedan Linux 2.6.33 tillhandahålls korrekt `O_SYNC`-stöd. För att säkerställa bakåtkompatibilitet, definierades `O_DSYNC` med samma värde som den historiska `O_SYNC`, och `O_SYNC` definierades som ett nytt (två-bit) flaggvärde som inkluderar `O_DSYNC` flaggvärdet. Detta säkerställer att applikationer kompilerade mot nya headers får åtminstone `O_DSYNC` semantik före Linux 2.6.33.

C bibliotek/kärnskillnader

Sedan glibc 2.26 använder glibc wrapper-funktionen för `open()` `openat()` systemanropet, istället för kärnans `open()` systemanrop. För vissa arkitekturer är detta också sant före glibc 2.26.

STANDARDER

  • open()
  • creat()
  • openat(): POSIX.1-2008.
  • openat2(2): Linux.

Flaggorna `O_DIRECT`, `O_NOATIME`, `O_PATH`, och `O_TMPFILE` är Linux-specifika. Man måste definiera `_GNU_SOURCE` för att få deras definitioner.

Flaggorna `O_CLOEXEC`, `O_DIRECTORY`, och `O_NOFOLLOW` specificeras inte i POSIX.1-2001, men är specificerade i POSIX.1-2008. Sedan glibc 2.12 kan man få deras definitioner genom att definiera antingen `_POSIX_C_SOURCE` med ett värde större än eller lika med `200809L` eller `_XOPEN_SOURCE` med ett värde större än eller lika med `700`. I glibc 2.11 och tidigare erhåller man definitionerna genom att definiera `_GNU_SOURCE`.

HISTORIA

  • open()
  • creat(): SVr4, 4.3BSD, POSIX.1-2001.
  • openat(): POSIX.1-2008. Linux 2.6.16, glibc 2.4.

NOTER

Under Linux används ibland `O_NONBLOCK` flaggan i fall där man vill öppna men inte nödvändigtvis har för avsikt att läsa eller skriva. Till exempel kan detta användas för att öppna en enhet för att få en filbeskrivare för användning med `ioctl(2)`.

Observera att `open()` kan öppna enhetsfiler, men `creat()` kan inte skapa dem; använd istället `mknod(2)`.

Om filen är nyss skapad, sätts dess `st_atime`, `st_ctime`, `st_mtime` fält (dvs. tid för senaste åtkomst, tid för senaste statusändring, och tid för senaste modifiering; se `stat(2)`) till den aktuella tiden, och så är även `st_ctime` och `st_mtime` fälten för den överordnade katalogen. Annars, om filen modifieras på grund av `O_TRUNC` flaggan, sätts dess `st_ctime` och `st_mtime` fält till den aktuella tiden.

Filerna i `/proc/pid/fd` katalogen visar de öppna filbeskrivarna för processen med PID pid. Filerna i `/proc/pid/fdinfo` katalogen visar ännu mer information om dessa filbeskrivare. Se `proc(5)` för ytterligare detaljer om båda dessa kataloger.

Linux headerfilen `<asm/fcntl.h>` definierar inte `O_ASYNC`; den (BSD-härledda) `FASYNC` synonymen är definierad istället.

Öppna filbeskrivningar

Termen "öppna filbeskrivning" är den som används av POSIX för att referera till posterna i det systemomfattande bordet över öppna filer. I andra sammanhang kallas detta objekt varierande för "öppen filobjekt", "filhandtag", "öppet filbordspost", eller – i kärnutvecklarjargong – en `struct file`.

När en filbeskrivare dupliceras (med `dup(2)` eller liknande), refererar duplicaten till samma öppna filbeskrivning som originalfilbeskrivaren, och de två filbeskrivarna delar således filoffseten och filstatusflaggorna. Sådan delning kan också förekomma mellan processer: en barnprocess skapad via `fork(2)` ärver duplicater av sina förälders filbeskrivare, och dessa duplicater refererar till samma öppna filbeskrivningar.

Varje `open()` av en fil skapar en ny öppen filbeskrivning; således kan det finnas flera öppna filbeskrivningar som motsvarar en filinode.

På Linux kan man använda `kcmp(2)` `KCMP_FILE` operationen för att testa om två filbeskrivare (i samma process eller i två olika processer) refererar till samma öppna filbeskrivning.

NFS

Det finns många oförhönade aspekter i protokollet underliggande NFS, som påverkar bland annat `O_SYNC` och `O_NDELAY`.

På NFS-filsystem med UID-mappning aktiverad, kan `open()` returnera en filbeskrivare men, till exempel, `read(2)`-förfrågningar nekas med `EACCES`. Detta beror på att klienten utför `open()` genom att kontrollera behörigheter, men UID-mappning utförs av servern vid läs- och skrivförfrågningar.

FIFOs

Att öppna läs- eller skrivänden av en FIFO blockerar tills den andra änden också öppnas (av en annan process eller tråd). Se `fifo(7)` för ytterligare detaljer.

Filåtkomstläge

Till skillnad från andra värden som kan specificeras i flags, specificerar åtkomstlägena `O_RDONLY`, `O_WRONLY`, och `O_RDWR` inte individuella bitar. De definierar istället de två lägsta bitarna av flags, och definieras respektive som 0, 1, och 2. Med andra ord är kombinationen `O_RDONLY | O_WRONLY` ett logiskt fel, och har säkert inte samma betydelse som `O_RDWR`.

Linux reserverar det speciella, icke-standardiserade åtkomstläget 3 (binärt 11) i flags för att betyda: kontrollera för läs- och skrivbehörighet på filen och returnera en filbeskrivare som inte kan användas för läsning eller skrivning. Detta icke-standardiserade åtkomstläge används av vissa Linux-drivrutiner för att returnera en filbeskrivare som endast ska användas för enhetsspecifika `ioctl(2)` operationer.

Rationale för openat() och andra katalog filbeskrivare API:er

`openat()` och de andra systemanropen och bibliotekfunktionerna som tar ett katalog filbeskrivare argument (dvs. `execveat(2)`, `faccessat(2)`, `fanotify_mark(2)`, `fchmodat(2)`, `fchownat(2)`, `fspick(2)`, `fstatat(2)`, `futimesat(2)`, `linkat(2)`, `mkdirat(2)`, `mknodat(2)`, `mount_setattr(2)`, `move_mount(2)`, `name_to_handle_at(2)`, `open_tree(2)`, `openat2(2)`, `readlinkat(2)`, `renameat(2)`, `renameat2(2)`, `statx(2)`, `symlinkat(2)`, `unlinkat(2)`, `utimensat(2)`, `mkfifoat(3)`, och `scandirat(3)`) adresserar två problem med de äldre gränssnitten som föregick dem. Här är förklaringen i termer av `openat()` anropet, men rationalen är analog för de andra gränssnitten.

För det första, tillåter `openat()` en applikation att undvika race conditions som kan uppstå när man använder `open()` för att öppna filer i kataloger andra än den aktuella arbetskatalogen. Dessa race conditions beror på att någon komponent av katalogprefixet givet till `open()` kan ändras parallellt med anropet till `open()`. Antag till exempel att vi vill skapa filen `dir1/dir2/xxx.dep` om filen `dir1/dir2/xxx` existerar. Problemet är att mellan existenskontrollen och filskapningssteget kan `dir1` eller `dir2` (vilka kan vara symboliska länkar) ändras för att peka till en annan plats. Sådana raser kan undvikas genom att öppna en filbeskrivare för målkatalogen, och sedan specificera den filbeskrivaren som dirfd argumentet för (säg) `fstatat(2)` och `openat()`. Användningen av dirfd filbeskrivaren har också andra fördelar:

  • Filbeskrivaren är en stabil referens till katalogen, även om katalogen byter namn;
  • Den öppna filbeskrivaren förhindrar det underliggande filsystemet från att avmonteras, precis som när en process har en aktuell arbetskatalog på ett filsystem.

För det andra, tillåter `openat()` implementeringen av ett per-tråd "aktuellt arbetskatalog", via filbeskrivare som underhålls av applikationen. (Denna funktionalitet kan också erhållas genom knep baserade på användning av `/proc/self/fd/dirfd`, men mindre effektivt.)

dirfd argumentet för dessa API:er kan erhållas genom att använda `open()` eller `openat()` för att öppna en katalog (med antingen `O_RDONLY` eller `O_PATH` flaggan). Alternativt kan en sådan filbeskrivare erhållas genom att applicera `dirfd(3)` på en katalogström skapad med `opendir(3)`.

När dessa API:er får ett dirfd argument av `AT_FDCWD` eller den specificerade pathname är absolut, hanterar de sina pathname argument på samma sätt som motsvarande konventionella API:er. Men i detta fall har flera av API:erna ett flags argument som ger tillgång till funktionalitet som inte är tillgänglig med motsvarande konventionella API:er.

NOTER

O_DIRECT

`O_DIRECT` flaggan kan införa justeringsrestriktioner på längden och adressen av användarutrymmet buffertar samt filoffseten av I/O:er. På Linux varierar justeringsrestriktionerna beroende på filsystem och kärnversion och kan helt saknas. Hanteringen av missanpassade `O_DIRECT` I/O:er varierar också; de kan antingen misslyckas med `EINVAL` eller falla tillbaka till buffrad I/O.

Sedan Linux 6.1 kan `O_DIRECT` stöd och justeringsrestriktioner för en fil frågas med `statx(2)`, med användning av `STATX_DIOALIGN` flaggan. Stöd för `STATX_DIOALIGN` varierar beroende på filsystem; se `statx(2)`.

Vissa filsystem tillhandahåller sina egna gränssnitt för att fråga om `O_DIRECT` justeringsrestriktioner, till exempel `XFS_IOC_DIOINFO` operationen i `xfsctl(3)`. `STATX_DIOALIGN` bör användas istället när det är tillgängligt.

Om inget av ovanstående är tillgängligt, kan stöd för direkt I/O och justeringsrestriktioner endast antas från kända egenskaper hos filsystemet, den individuella filen, de underliggande lagringsenheterna, och kärnversionen. I Linux 2.4 krävde de flesta filsystem baserade på blockenheter att filoffseten och längden och minnesadressen av alla I/O-segment var multipler av filsystemets blockstorlek (vanligtvis 4096 byte). I Linux 2.6.0 slapp detta av till den logiska blockstorleken av blockenheten (vanligtvis 512 byte). En blockenhets logiska blockstorlek kan bestämmas med `ioctl(2)` `BLKSSZGET` operationen eller från skalet med kommandot:

blockdev --getss

`O_DIRECT` I/O:er bör aldrig köras samtidigt med `fork(2)` systemanropet, om minnesbufferten är en privat mappning (dvs. någon mappning skapad med `mmap(2)` `MAP_PRIVATE` flaggan; detta inkluderar minne allokerat på heapen och statiskt allokerade buffertar). Alla sådana I/O:er, oavsett om de skickas via ett asynkront I/O-gränssnitt eller från en annan tråd i processen, bör slutföras innan `fork(2)` anropas. Underlåtenhet att göra detta kan resultera i datakorruption och ospecificerat beteende i föräldra- och barnprocesser. Denna restriktion gäller inte när minnesbufferten för `O_DIRECT` I/O:erna skapades med `shmat(2)` eller `mmap(2)` med `MAP_SHARED` flaggan. Inte heller gäller denna restriktion när minnesbufferten har rådgivits som `MADV_DONTFORK` med `madvise(2)`, vilket säkerställer att den inte kommer att vara tillgänglig för barnet efter `fork(2)`.

`O_DIRECT` flaggan introducerades i SGI IRIX, där den har justeringsrestriktioner liknande de i Linux 2.4. IRIX har också ett `fcntl(2)` anrop för att fråga lämpliga justeringar, och storlekar. FreeBSD 4.x introducerade en flagga med samma namn, men utan justeringsrestriktioner.

`O_DIRECT`-stöd lades till i Linux 2.4.10. Äldre Linux-kärnor ignorerar helt enkelt denna flagga. Vissa filsystem kanske inte implementerar flaggan, i vilket fall `open()` misslyckas med felet `EINVAL` om den används.

Applikationer bör undvika att blanda `O_DIRECT` och normal I/O till samma fil, och särskilt till överlappande byte-regioner i samma fil. Även när filsystemet korrekt hanterar koherensfrågorna i denna situation, är den totala I/O-genomströmningen sannolikt långsammare än att använda endera läget ensamt. På samma sätt bör applikationer undvika att blanda `mmap(2)` av filer med direkt I/O till samma filer.

Beteendet av `O_DIRECT` med NFS kommer att skilja sig från lokala filsystem. Äldre kärnor, eller kärnor konfigurerade på vissa sätt, kanske inte stöder denna kombination. NFS-protokollet stöder inte att passera flaggan till servern, så `O_DIRECT` I/O kommer att kringgå sidcachen endast på klienten; servern kan fortfarande cachera I/O. Klienten ber servern att göra I/O synkront för att bevara den synkrona semantiken av `O_DIRECT`. Vissa servrar kommer att prestera dåligt under dessa omständigheter, särskilt om I/O-storleken är liten. Vissa servrar kan också konfigureras att ljuga för klienterna om att I/O har nått stabil lagring; detta undviker prestandapåverkan till viss risk för data integritet vid server strömavbrott. Linux NFS-klienten placerar inga justeringsrestriktioner på `O_DIRECT` I/O.

Sammanfattningsvis är `O_DIRECT` ett potentiellt kraftfullt verktyg som bör användas med försiktighet. Det rekommenderas att applikationer behandlar användningen av `O_DIRECT` som ett prestandaalternativ som är inaktiverat som standard.

BUGGAR

  • För närvarande är det inte möjligt att aktivera signalstyrd I/O genom att specificera `O_ASYNC` när man anropar `open()`; använd `fcntl(2)` för att aktivera denna flagga.
  • Man måste kontrollera två olika felkoder, `EISDIR` och `ENOENT`, när man försöker avgöra om kärnan stöder `O_TMPFILE` funktionalitet.
  • När både `O_CREAT` och `O_DIRECTORY` specificeras i flags och filen specificerad av pathname inte existerar, kommer `open()` att skapa en vanlig fil (dvs. `O_DIRECTORY` ignoreras).

SE OCKSÅ

`chmod(2)`, `chown(2)`, `close(2)`, `dup(2)`, `fcntl(2)`, `link(2)`, `lseek(2)`, `mknod(2)`, `mmap(2)`, `mount(2)`, `open_by_handle_at(2)`, `openat2(2)`, `read(2)`, `socket(2)`, `stat(2)`, `umask(2)`, `unlink(2)`, `write(2)`, `fopen(3)`, `acl(5)`, `fifo(7)`, `inode(7)`, `path_resolution(7)`, `symlink(7)`

COLOFON

Denna sida är en del av man-pages (Linux kernel och C-bibliotek användargränssnitt dokumentation) projektet. Information om projektet finns på https://www.kernel.org/doc/man-pages/. Om du har en buggrapport för denna manual sida, se https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/CONTRIBUTING.

Sidslut

Orginalhemsidan på Engelska :https://man7.org/linux/man-pages/man2/open.2.html

Det här är en maskinöversättning av Linux man sidor till svenska. Om du hittar fel är vi tacksamma om du rapporterar dem via formuläret som finns på https://www.linux.se/kontaka-linux-se/

Tack till PC Service som har sponsrat Linux.se med webbhotell.