Provided by: manpages-pl-dev_4.23.1-1_all bug

NAZWA

       open, creat - otwiera i ewentualnie tworzy plik

BIBLIOTEKA

       Standardowa biblioteka C (libc, -lc)

SKŁADNIA

       #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 */ );

       /* Udokumentowane oddzielnie, w openat2(2):
        */
       int openat2(int dirfd, const char *pathname,
                  const struct open_how *how, size_t size);

   Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

       openat():
           Od glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
           Przed glibc 2.10:
               _ATFILE_SOURCE

OPIS

       Wywołanie  systemowe open() otwiera plik określony ścieżką pathname. Jeśli podany plik nie
       istnieje, może być opcjonalnie (jeśli we flags podano O_CREAT) utworzony przez open().

       Wartością zwracaną  przez  open()  jest  deskryptor  pliku:  niewielka,  całkowita  liczba
       nieujemna,  będąca  indeksem  wpisu  w  tablicy  otwartych  deskryptorów  plików  procesu.
       Deskryptor pliku jest używany w  kolejnych  wywołaniach  systemowych  (read(2),  write(2),
       lseek(2),  fcntl(2)  itp.),  w  celu  odniesienia się do otwartego pliku. Deskryptor pliku
       zwracany przez pomyślne wywołanie będzie najniższym numerem deskryptora pliku,  który  nie
       jest aktualnie otwarty przez proces.

       Domyślnie,  nowy  deskryptor  pliku  jest  ustawiany jako pozostający otwarty po wykonaniu
       przez execve(2)  (tj. znacznik  deskryptora  pliku  FD_CLOEXEC  opisany  w  fcntl(2)  jest
       początkowo  wyłączony);  można  użyć  opisanego poniżej znacznika O_CLOEXEC aby zmienić to
       zachowanie. Przesunięcie pliku jest ustawiane na początek pliku (zob. lseek(2)).

       Wywołanie open() tworzy nowy opis otwartego pliku, wpis  w  systemowej  tablicy  otwartych
       plików.  Opis  otwartego  pliku zawiera przesunięcie pliku i znaczniki statusu pliku (zob.
       niżej). Deskryptor pliku odnosi się do opisu otwartego pliku i na to  odniesienie  nie  ma
       wpływu  późniejsze usunięcie ścieżki pathname lub jej modyfikacja, w celu wskazania innego
       pliku. Więcej informacji o opisach otwartego pliku zawarto w rozdziale UWAGI.

       Argument flags musi zawierać jeden z następujących trybów dostępu: O_RDONLY, O_WRONLY  lub
       O_RDWR. Stanowią one, odpowiednio, żądania otwarcia tylko do odczytu, tylko do zapisu, lub
       do odczytu i zapisu.

       Ponadto, we flags może zsumować bitowo (OR) zero lub więcej znaczników tworzenia  pliku  i
       znaczników  statusu  pliku. Znaczniki tworzenia pliku to: O_CLOEXEC, O_CREAT, O_DIRECTORY,
       O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE i O_TRUNC. Znaczniki statusu  pliku  to  wszystkie
       pozostałe   znaczniki,   wypisane  poniżej.  Rozróżnieniem  pomiędzy  tymi  dwoma  grupami
       znaczników jest fakt, że znaczniki tworzenia pliku wpływają na zachowanie  samej  operacji
       otwarcia,  natomiast  znaczniki  statusu  pliku  wpływają na zachowanie kolejnych operacji
       wejścia/wyjścia. Znaczniki  statusu  pliku  można  pobrać  i  (w  niektórych  przypadkach)
       zmodyfikować; więcej szczegółów w podręczniku fcntl(2).

       Oto pełna lista znaczników tworzenia pliku i znaczników statusu pliku:

       O_APPEND
              Plik   jest   otwierany  w  trybie  dopisywania.  Przed  każdą  operacją  write(2),
              przesunięcie pliku jest ustawiane na koniec  pliku,  jak  z  lseek(2).  Modyfikacja
              przesunięcia  pliku  i operacja zapisu jest przeprowadzana jako jeden, niepodzielny
              krok.

              O_APPEND może prowadzić do uszkodzenia plików na systemach plików NFS,  gdy  więcej
              niż  jeden  proces  naraz dopisuje dane do pliku. Jest to związane z faktem, że NFS
              nie obsługuje dopisywania do pliku, więc jądro klienta musi to zasymulować, co  nie
              może zostać wykonane bez wyścigu.

       O_ASYNC
              Włącza  wejście/wyjście  sterowane  sygnałem: generuje sygnał (domyślnie SIGIO, ale
              można go  zmienić  za  pomocą  fcntl(2)),  gdy  wejście  lub  wyjście  poprzez  ten
              deskryptor pliku staje się możliwe. Ta funkcja jest dostępna jedynie dla terminali,
              pseudoterminali, gniazd i (od Linuksa 2.6) potoków  oraz  FIFO.  Więcej  szczegółów
              można znaleźć w podręczniku fcntl(2). Zob. też USTERKI poniżej.

       O_CLOEXEC (od Linuksa 2.6.23)
              Włącza  znacznik  zamknięcia-przy-wykonaniu  dla  nowego deskryptora pliku. Podanie
              tego znacznika umożliwia uniknięcie przez program wykonywania dodatkowych  operacji
              F_SETFD fcntl(2) w celu ustawienia znacznika FD_CLOEXEC.

              Proszę  zauważyć,  że  korzystanie  z  tego  znacznika  jest niezbędne w niektórych
              programach  wielowątkowych,   ponieważ   oddzielna   operacja   F_SETFD   fcntl(2),
              ustawiająca  znacznik  FD_CLOEXEC,  nie zapobiega wystąpieniu sytuacji wyścigu, gdy
              jeden  wątek   otwiera   deskryptor   pliku,   próbując   ustawić   swój   znacznik
              zamknięcia-przy-wykonaniu  za  pomocą  fcntl(2),  a  w  tym samym czasie inny wątek
              dokonuje fork(2) oraz execve(2). W zależności od kolejności wykonania,  wyścig  ten
              może  spowodować nieoczekiwany wyciek deskryptora pliku zwróconego przez open(), do
              programu wykonywanego przez proces potomny utworzony przez  fork(2)  (jest  to  typ
              wyścigu,   który  jest  teoretycznie  możliwy  dla  każdego  wywołania  systemowego
              tworzącego    deskryptor    pliku,     który     powinien     otrzymać     znacznik
              zamknięcia-przy-wykonaniu,   dlatego   różne  inne  linuksowe  wywołania  systemowe
              udostępniają równoważnik znacznika O_CLOEXEC, aby poradzić sobie z tym problemem).

       O_CREAT
              Jeśli pathname nie istnieje, tworzy ją jako zwykły plik.

              Właściciel (identyfikator użytkownika) nowego pliku  jest  ustawiany  na  efektywny
              identyfikator użytkownika procesu.

              Własność  grupy  (identyfikator  grupy)  nowego  pliku  jest ustawiana na efektywny
              identyfikator grupy procesu  (zachowanie  Systemu V)  lub  na  identyfikator  grupy
              katalogu  nadrzędnego (zachowanie BSD). W Linuksie, wybór typu zachowania zależy od
              ustawienia bitu trybu set-group-ID  w  katalogu  nadrzędnym:  jeśli  bit  ten  jest
              ustawiony,  wybierane  jest  zachowanie  BSD;  w  przeciwnym  razie, stosowane jest
              zachowanie Systemu V. W przypadku niektórych systemów plików, zachowanie to  zależy
              również  od  opcji  montowania  bsdgroups i sysvgroups, które opisano w podręczniku
              mount(8).

              Argument mode określa  bity  trybu  pliku,  jakie  mają  być  zastosowane  do  nowo
              tworzonego  pliku.  Jeśli nie poda się O_CREAT ani O_TMPFILE we flags, to mode jest
              ignorowane (można je zatem podać jako 0 lub po prostu pominąć). Argument mode  musi
              być  określony, jeśli we flags podano O_CREAT lub O_TMPFILE; jeśli się go nie poda,
              jako tryb pliku zostaną użyte jakieś losowe bajty ze stosu.

              Efektywny tryb  jest  modyfikowany  przez  umask  procesu,  w  zwykły  sposób:  pod
              nieobecność  domyślnych  list  kontroli dostępu (ACL), trybem tworzonego pliku jest
              (mode & ~umask).

              Proszę zauważyć, że mode stosuje się tylko do kolejnych dostępów do nowo tworzonego
              pliku;  wywołanie  open(), które tworzy plik tylko do odczytu, może zwrócić również
              deskryptor pliku do odczytu i do zapisu.

              Dla parametru mode udostępniono następujące stałe symboliczne:

              S_IRWXU  00700  użytkownik  (właściciel  pliku)  ma   prawa   odczytu,   zapisu   i
                       uruchamiania.

              S_IRUSR  00400 użytkownik ma prawa odczytu.

              S_IWUSR  00200 użytkownik ma prawa zapisu.

              S_IXUSR  00100 użytkownik ma prawa uruchamiania.

              S_IRWXG  00070 grupa ma prawa odczytu, zapisu i uruchamiania.

              S_IRGRP  00040 grupa ma prawa odczytu.

              S_IWGRP  00020 grupa ma prawa zapisu.

              S_IXGRP  00010 grupa ma prawa uruchamiania.

              S_IRWXO  00007 inni mają prawa odczytu, zapisu i uruchamiania.

              S_IROTH  00004 inni mają prawa odczytu.

              S_IWOTH  00002 inni mają prawa zapisu.

              S_IXOTH  00001 inni mają prawa uruchamiania.

              Zgodnie  z  POSIX,  wpływ  ustawienia  innych  bitów  w  mode  jest nieokreślony. W
              Linuksie, honorowane jest również ustawienie następujących bitów w mode:

              S_ISUID  0004000 bit set-user-ID

              S_ISGID  0002000 bit set-group-ID (zob. inode(7)).

              S_ISVTX  0001000 bit lepkości (zob. inode(7)).

       O_DIRECT (od Linuksa 2.4.10)
              Powoduje próbę zminimalizowania efektów związanych z  buforowaniem  wejścia/wyjścia
              do  i  z  tego  pliku.  Na  ogół  spowoduje to zmniejszenie wydajności, ale jest to
              przydatne w specyficznych sytuacjach, na przykład gdy aplikacje buforują we własnym
              zakresie.  Wejście/wyjście dla pliku odbywa się wówczas bezpośrednio z/do buforów w
              przestrzeni użytkownika.  Sam  znacznik  O_DIRECT  stara  się  dokonywać  transferu
              synchronicznie,  ale  nie  daje  gwarancji  znacznika  O_SYNC,  że  dane i wymagane
              metadane są transferowane. Aby zagwarantować synchroniczne wejście/wyjście,  oprócz
              O_DIRECT  konieczne jest użycie również O_SYNC. Więcej informacji w rozdziale UWAGI
              poniżej.

              Semantycznie podobny (lecz przestarzały) interfejs dla urządzeń blokowych opisano w
              raw(8).

       O_DIRECTORY
              Jeśli  pathname nie jest katalogiem, spowoduje niepowodzenie otwarcia. Ten znacznik
              dodano w Linuksie 2.1.126,  aby  uniknąć  problemów  blokowania  usług  (DoS),  gdy
              opendir(3) jest wywołane dla FIFO lub dla urządzenia taśmowego.

       O_DSYNC
              Operacje   zapisu   pliku   zakończą   się   zgodnie   z   wymaganiem  kompletności
              zsynchronizowanego wejścia/wyjścia danych w sposób gwarantujący spójność.

              W chwili powrotu write(2) (i podobnego), dane wyjściowe zostały już przeniesione na
              właściwe  urządzenie,  razem  ze wszystkimi metadanymi pliku, które są konieczne do
              pobrania tych danych  (tzn.  jest  to  równoważne  jak  gdyby  po  każdym  write(2)
              wywoływać fdatasync(2)). Proszę zapoznać się z UWAGAMI poniżej.

       O_EXCL Zapewnia,  że to wywołanie utworzy plik: jeśli znacznik poda się razem z O_CREAT, a
              ścieżka pathname już istnieje, to open() zawiedzie z błędem EEXIST.

              Po podaniu obu tych znaczników, nie podąża się za dowiązaniami symbolicznymi: jeśli
              pathname jest dowiązaniem symbolicznym, to open() zawiedzie niezależnie od tego, na
              co wskazuje to dowiązanie symboliczne.

              Co do zasady, zachowanie O_EXCL  jest  niezdefiniowane,  jeśli  użyje  się  go  bez
              O_CREAT.  Jest  jeden wyjątek: w Linuksie 2.6 i późniejszych, O_EXCL można użyć bez
              O_CREAT jeśli pathname odnosi się do urządzenia blokowego. Jeśli urządzenie blokowe
              jest  w  użyciu  przez  system (np. jest zamontowane), to open() zawiedzie z błędem
              EBUSY.

              W systemie plików NFS O_EXCL jest obsługiwane tylko  w  NFSv3  lub  późniejszym  na
              jądrze  2.6  lub  późniejszym.  W  środowiskach  NFS,  gdzie nie zapewniono obsługi
              O_EXCL, programy które polegają na nim, w celu dokonywania zadań  blokowania,  będą
              prowadziły  do  wyścigu.  Przenośne programy, które chcą przeprowadzać niepodzielne
              blokowanie pliku za pomocą pliku-blokady  i  muszą  unikać  polegania  na  obsłudze
              O_EXCL  w  NFS,  mogą  tworzyć  unikalny  plik  na  tym  samym systemie plików (np.
              wykorzystując nazwę stacji i PID) i używać  link(2)  do  utworzenia  dowiązania  do
              pliku-blokady.  Jeśli  link(2)  zwróci  0,  to  utworzenie  blokady się powiodło. W
              przeciwnym razie, należy użyć stat(2) na unikalnym pliku, aby sprawdzić, czy  ilość
              jego  dowiązań  wzrosła  do  2.  W  takiej  sytuacji utworzenie blokady również się
              powiodło.

       O_LARGEFILE
              (LFS)  Pozwala na otwarcie plików, których rozmiarów nie można przedstawić w  off_t
              (lecz  można  w  off64_t).  Konieczne  jest zdefiniowanie makra _LARGEFILE64_SOURCE
              (przed włączeniem jakichkolwiek plików nagłówkowych) aby  uzyskać  jego  definicję.
              Ustawienie  makra sprawdzania cech _FILE_OFFSET_BITS na 64 (zamiast na O_LARGEFILE)
              jest  preferowaną  metodą  uzyskiwania  dostępu  do  dużych  plików   w   systemach
              32-bitowych (zob. feature_test_macros(7)).

       O_NOATIME (od Linuksa 2.6.8)
              Nie  aktualizuje  czasu  ostatniego  dostępu do pliku (st_atime w i-węźle) gdy plik
              jest odczytywany (read(2)).

              Znacznik ten  można  użyć  tylko,  jeśli  spełniony  zostanie  jeden  z  poniższych
              warunków:

              •  Efektywny UID procesu jest zgodny z UID-em właściciela pliku.

              •  Proces wywołujący ma przywilej CAP_FOWNER (ang. capability) w swojej przestrzeni
                 nazw użytkownika, a UID właściciela pliku  ma  przypisanie  do  tej  przestrzeni
                 nazw.

              Znacznik  ten  jest  przeznaczony  dla programów indeksujących lub tworzących kopie
              zapasowe, gdzie pozwala na znaczną redukcję aktywności dysku. Znacznik ten może nie
              działać  we  wszystkich  systemach  plików.  Jednym z przykładów jest NFS, gdzie to
              serwer zarządza czasami dostępu.

       O_NOCTTY
              Jeśli pathname odnosi się do urządzenia terminalowego — zob. tty(4) — to nie stanie
              się terminalem sterującym procesu, nawet jeśli proces takiego nie ma.

       O_NOFOLLOW
              Jeśli  końcowa  składowa (basename) ścieżki pathname jest dowiązaniem symbolicznym,
              to  otwarcie  zawiedzie  z  błędem  ELOOP.  Dowiązania  symboliczne  wcześniejszych
              składowych  ścieżki wciąż zostaną rozwinięte (proszę zauważyć, że błąd ELOOP, który
              może się zdarzyć w tym przypadku, jest nierozróżnialny od  sytuacji,  gdy  otwarcie
              zawiedzie,  z  powodu  zbyt  wielu  dowiązań  symbolicznych,  które  wystąpiły przy
              rozwiązywaniu wcześniejszych składowych ścieżki).

              Znacznik ten jest rozszerzeniem FreeBSD, który został dodany w Linuksie  2.1.126  i
              został później wprowadzony jako standard w normie POSIX.1-2008.

              Zob. też O_PATH poniżej.

       O_NONBLOCK lub O_NDELAY
              Plik  jest  otwierany  w  trybie  nieblokującym,  o  ile to możliwe. Ani open() ani
              kolejne operacje wejścia/wyjścia, na zwróconym przez to wywołanie deskryptorze, nie
              spowodują blokowania procesu wywołującego.

              Proszę  zauważyć,  że ustawienie tego znacznika nie ma wpływu na działanie poll(2),
              select(2),  epoll(7)  i  podobnych,  ponieważ  interfejsy  te   jedynie   informują
              wywołującego  o  tym,  gdy  deskryptor  pliku jest „gotowy” co oznacza, że operacja
              wejścia/wyjścia na deskryptorze pliku ze znacznikiem  O_NONBLOCK  zdecydowanie  nie
              prowadziłaby do zablokowania.

              Proszę zauważyć, że znacznik ten nie ma wpływu na zwykłe pliki i urządzenia blokowe
              tzn.  operacja  wejścia/wyjścia  będzie  (chwilowo)  blokować,  gdy  wymagana  jest
              aktywność   urządzenia,   niezależnie  od  ustawienia  O_NONBLOCK.  Ponieważ  takie
              zachowanie O_NONBLOCK  może  w  przyszłości  być  zaimplementowane,  aplikacje  nie
              powinny zależeć od zachowania blokowania, przy podawaniu tego znacznika w przypadku
              zwykłych plików i urządzeń blokowych.

              Szczegóły dotyczące obsługi FIFO (nazwanych potoków) można  znaleźć  w  podręczniku
              fifo(7).  Opis wpływu znacznika O_NONBLOCK, w połączeniu z blokadami obowiązującymi
              (przymusowymi) oraz z dzierżawami pliku, znajduje się w podręczniku fcntl(2).

       O_PATH (od Linuksa 2.6.39)
              Pozyskuje deskryptor pliku,  którego  można  użyć  w  dwóch  celach:  do  wskazania
              położenia w drzewie systemu plików i do przeprowadzenia operacji, które działają na
              poziomie samego deskryptora pliku.  Sam  plik  nie  jest  otwierany,  dlatego  inne
              operacje  plikowe  (np.  read(2),  write(2),  fchmod(2),  fchown(2),  fgetxattr(2),
              ioctl(2), mmap(2)) zawiodą z błędem EBADF.

              Na wynikowym deskryptorze pliku można wykonać następujące operacje:

              •  close(2).

              •  fchdir(2), jeśli deskryptor pliku odnosi się do katalogu (od Linuksa 3.5).

              •  fstat(2) (od Linuksa 3.6).

              •  fstatfs(2) (od Linuksa 3.12).

              •  Zduplikowanie deskryptora pliku (dup(2), F_DUPFD z fcntl(2), itp).

              •  Uzyskanie i  ustawienie  znaczników  deskryptora  pliku  (F_GETFD  i  F_SETFD  z
                 fcntl(2)).

              •  Pobranie  znaczników  statusu  otwartego  pliku  za  pomocą  operacji  F_GETFL z
                 fcntl(2): zwrócone znaczniki będą obejmowały również bit O_PATH.

              •  Przekazanie deskryptora pliku jako argumentu dirfd do openat() i innych  wywołań
                 systemowych  „*at()”.  Obejmuje  to  również  linkat(2)  z AT_EMPTY_PATH (lub za
                 pomocą  procfs  wykorzystując  AT_SYMLINK_FOLLOW)  nawet,  gdy  plik  nie   jest
                 katalogiem.

              •  Przekazanie  deskryptora pliku do innego procesu za pomocą gniazda domeny Uniksa
                 (zob. SCM_RIGHTS w podręczniku unix(7)).

              Gdy O_PATH poda się we flags, to bity znaczników inne niż O_CLOEXEC, O_DIRECTORY  i
              O_NOFOLLOW są ignorowane.

              Otwarcie  pliku  lub  katalogu ze znacznikiem O_PATH nie wymaga uprawnień do samego
              obiektu  (lecz  wymaga  uprawnienia  wykonania  (przeszukiwania)  na  katalogach  w
              składowej   ścieżki).   W  zależności  od  kolejnej  operacji,  może  być  wykonane
              sprawdzenie  odpowiednich  uprawnień  pliku  (np.  fchdir(2)   wymaga   uprawnienia
              wykonania  (przeszukania)  na  katalogu,  do  którego  odnosi  się  jego argument z
              deskryptorem pliku). Odmiennie, przy uzyskiwaniu  odniesienia  do  obiektu  systemu
              plików  za  pomocą  znacznika O_RDONLY, wymagane jest posiadanie przez wywołującego
              uprawnienia odczytu, nawet gdy  kolejna  operacja  (np.  fchdir(2),  fstat(2))  nie
              wymaga uprawnienia odczytu do obiektu.

              Jeśli  pathname jest dowiązaniem symbolicznym i podano również znacznik O_NOFOLLOW,
              to wywołanie zwróci deskryptor pliku odnoszący się do dowiązania symbolicznego. Ten
              deskryptor  pliku  może  służyć  jako  argument dirfd w wywołaniach do fchownat(2),
              fstatat(2), linkat(2) i readlinkat(2) z pustą ścieżką, aby  wywołania  działały  na
              samym dowiązaniu symbolicznym.

              Jeśli  pathname  odnosi  się  do punktu automatycznego montowania, który nie został
              jeszcze wyzwolony, tak więc  nie  zamontowano  w  nim  innego  systemu  plików,  to
              wywołanie   zwróci  deskryptor  pliku  odnoszący  się  do  katalogu  automatycznego
              montowania,  bez  wyzwalania  montowania.  Można  następnie  użyć  fstatfs(2),  aby
              sprawdzić,  czy  jest  to  faktycznie  niewyzwolony punkt automatycznego montowania
              (.f_type == AUTOFS_SUPER_MAGIC).

              Można  użyć  O_PATH  w  przypadku  zwykłych  plików,  aby  uzyskać   funkcjonalność
              równoważną  O_EXEC  z POSIX.1. Pozwala to na otwarcie pliku, do którego posiada się
              uprawnienie wykonywania, ale nie  posiada  się  uprawnienia  odczytu,  a  następnie
              wykonanie pliku, za pomocą kroków podobnych do poniższych:

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

              Deskryptor pliku O_PATH może być również przekazany jako argument fexecve(3).

       O_SYNC Operacje   zapisu   na   pliku  zakończą  się  zgodnie  z  wymaganiem  kompletności
              zsynchronizowanego wejścia/wyjścia pliku w sposób gwarantujący spójność  (odmiennie
              od zakończenia zgodnie z wymaganiem kompletności zsynchronizowanego wejścia/wyjścia
              danych, udostępnianego przez O_DSYNC).

              W chwili powrotu write(2) (i podobnego), dane wyjściowe i powiązane metadane  pliku
              zostały  już przeniesione na właściwe urządzenie (tzn. jest to równoważne jak gdyby
              po każdym write(2) wywoływać fsync(2)). Proszę zapoznać się z UWAGAMI poniżej.

       O_TMPFILE (od Linuksa 3.11)
              Tworzy nienazwany, zwykły plik tymczasowy. Argument  pathname  określa  katalog,  w
              katalogu tym, w systemie plików zostanie utworzony nienazwany i-węzeł. Wszystko, co
              zostanie zapisane do wynikowego pliku, ulegnie  utracie  po  zamknięciu  ostatniego
              deskryptora pliku chyba, że plik otrzyma nazwę.

              Ze  znacznikiem  O_TMPFILE  należy użyć O_RDWR lub O_WRONLY i, opcjonalnie, O_EXCL.
              Jeśli nie poda się O_EXCL, to można skorzystać z linkat(2) do utworzenia dowiązania
              do systemu plików, czyniąc plik stałym, za pomocą kodu podobnego do poniższego:

                  char path[PATH_MAX];
                  fd = open("/ścieżka/do/katalogu", O_TMPFILE | O_RDWR,
                                          S_IRUSR | S_IWUSR);

                  /* Wejście/wyjście na 'fd'... */

                  linkat(fd, "", AT_FDCWD, "/ścieżka/do/pliku", AT_EMPTY_PATH);

                  /* Jeśli wywołujący nie ma przywileju CAP_DAC_READ_SEARCH
                     (potrzebnego do użycia AT_EMPTY_PATH z linkat(2)),
                     i system plików proc(5) jest zamontowany, to powyższe
                     wywołanie linkat(2) można zastąpić przez:

                  snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
                  linkat(AT_FDCWD, path, AT_FDCWD, "/ścieżka/do/pliku",
                                          AT_SYMLINK_FOLLOW);
                  */

              W  tym  przypadku  argument  mode open() określa tryb uprawnień pliku, podobnie jak
              przy O_CREAT.

              Podanie O_EXCL w połączeniu z O_TMPFILE zapobiega możliwości utworzenia  dowiązania
              do  systemu  plików  w  powyższy sposób (proszę zauważyć, że znaczenie O_EXCL w tym
              przypadku różni się od znaczenia O_EXCL w pozostałych przypadkach).

              Istnieją dwa główne zastosowania O_TMPFILE:

              •  Usprawniona funkcjonalność tmpfile(3): tworzenie plików tymczasowych bez  ryzyka
                 wystąpienia  wyścigu, które: (1) są automatycznie usuwane po zamknięciu; (2) nie
                 da się do nich dostać za pomocą żadnej ścieżki; (3) nie są przedmiotem ataków na
                 dowiązania  symboliczne  oraz  (4)  nie  wymagają  wymyślania przez wywołującego
                 unikatowych nazw.

              •  Tworzenie plików początkowo niewidocznych, które są następnie wypełniane  danymi
                 i   dostosowywane   w   celu  posiadania  właściwych  atrybutów  systemu  plików
                 (fchown(2),  fchmod(2),  fsetxattr(2)  itp.)  przed  niepodzielnym   utworzeniem
                 dowiązania  do  systemu  plików,  w stanie już w pełni ukształtowanym (za pomocą
                 opisanego wyżej linkat(2)).

              O_TMPFILE wymaga obsługi w podległym systemie plików; jedynie podzbiór  linuksowych
              systemów  plików ją zapewnia. W pierwotnej implementacji, obsługę zapewniały system
              plików ext2, ext3, ext4, UDF, Minix i tmpfs.  Następnie  dodano  obsługę  kolejnych
              systemów plików: XFS (Linux 3.15); Btrfs (Linux 3.16); F2FS (Linux 3.16) oraz ubifs
              (Linux 4.9)

       O_TRUNC
              Jeśli plik już istnieje, jest zwykłym plikiem i tryb dostępu pozwala na zapis (tzn.
              jest  to  O_RDWR  lub  O_WRONLY), to plik ten zostanie obcięty do zerowej długości.
              Jeśli plik to FIFO lub urządzenie terminalowe, to znacznik O_TRUNC jest ignorowany.
              W pozostałych przypadkach efekt użycia znacznika O_TRUNC jest nieokreślony.

   creat()
       Wywołanie  creat()  jest  równoważne  wywołaniu  open()  z  argumentem flags ustawionym na
       O_CREAT|O_WRONLY|O_TRUNC.

   openat()
       Wywołanie systemowe openat() operuje w dokładnie taki sam sposób jak open(),  z  wyjątkiem
       różnic opisanych tutaj.

       Argument dirfd jest używany w połączeniu z argumentem pathname, w następujący sposób:

       •  Jeśli ścieżka podana w pathname jest bezwzględna, to dirfd jest ignorowane.

       •  Jeśli  ścieżka  podana w pathname jest względna, a dirfd ma wartość specjalną AT_FDCWD,
          to  pathname  jest  interpretowana  względem  bieżącego  katalogu   roboczego   procesu
          wywołującego (jak open()).

       •  Jeśli  ścieżka  podana  w  pathname  jest  względna,  to  jest  interpretowana względem
          katalogu, do którego odnosi się  deskryptor  pliku  dirfd  (zamiast  w  odniesieniu  do
          bieżącego  katalogu  roboczego  procesu wywołującego, jak czyni to open() w stosunku do
          ścieżek względnych). W tym przypadku, dirfd musi być katalogiem, który był  otwarty  do
          odczytu (O_RDONLY) lub za pomocą znacznika O_PATH.

       Jeśli  ścieżka  podana w pathname jest względna, a dirfd nie jest prawidłowym deskryptorem
       pliku, to wystąpi błąd (EBADF; można zatem posłużyć się tym mechanizmem do upewnienia się,
       że ścieżka pathname jest bezwzględna, podając w dirfd nieprawidłowy numer deskryptora).

   openat2(2)
       Wywołanie  systemowe  openat2(2) jest rozszerzeniem openat() i udostępnia nadzbiór funkcji
       wobec openat(). Jest udokumentowane oddzielnie, w podręczniku openat2(2).

WARTOŚĆ ZWRACANA

       W przypadku powodzenia, open(), openat() i creat() zwracają nowy deskryptor pliku  (liczbę
       nieujemną). W razie wystąpienia błędu zwracane jest -1 i ustawiane errno wskazując błąd.

BŁĘDY

       open(), openat() i creat() mogą zawieść z powodu następujących błędów:

       EACCES Żądany dostęp do pliku nie jest dozwolony, odmówiono uprawnienia przeszukiwania dla
              jednego z katalogów składowych ścieżki pathname, plik jeszcze nie  istnieje  i  nie
              dozwolono    na    dostęp   do   zapisu   do   katalogu   nadrzędnego   (zob.   też
              path_resolution(7)).

       EACCES Gdy podano O_CREAT, włączona jest kontrolka systemowa  sysctl  protected_fifos  lub
              protected_regular,  plik już istnieje i jest FIFO lub zwykłym plikiem, właścicielem
              pliku nie jest ani bieżący użytkownik, ani  właściciel  katalogu  nadrzędnego  oraz
              katalog  nadrzędny  jest zapisywalny zarówno dla wszystkich lub dla grupy, jak i ma
              ustawiony bit lepkości. Więcej szczegółów w opisach /proc/sys/fs/protected_fifos  i
              /proc/sys/fs/protected_regular w podręczniku proc_sys_fs(5).

       EBADF  (openat())   pathname  jest  względne,  lecz dirfd nie wynosi ani AT_FDCWD, ani nie
              jest prawidłowym deskryptorem pliku.

       EBUSY  We flags podano O_EXCL, a ścieżka pathname  odnosi  się  do  urządzenia  blokowego,
              które jest w użyciu przez system (np. jest zamontowane).

       EDQUOT Podano  O_CREAT,  plik  nie istnieje, a przydział bloków dyskowych lub i-węzłów dla
              użytkownika w systemie plików wyczerpał się.

       EEXIST pathname już istnieje, a użyto O_CREAT i O_EXCL.

       EFAULT pathname wskazuje poza dostępną dla użytkownika przestrzeń adresową.

       EFBIG  Zob. EOVERFLOW.

       EINTR  Wywołanie zostało przerwane przez procedurę obsługi sygnału, w trakcie zablokowania
              w  oczekiwaniu  na  ukończenie  otwarcia  na  powolnym  (np.  FIFO;  zob.  fifo(7))
              urządzeniu; zob. signal(7).

       EINVAL System plików nie obsługuje znacznika O_DIRECT. Więcej informacji w UWAGACH.

       EINVAL Nieprawidłowa wartość we flags.

       EINVAL We flags podano O_TMPFILE, lecz nie podano O_WRONLY, ani O_RDWR.

       EINVAL We flags podano O_CREAT,  lecz  ostatnia  składowa  („basename”)  ścieżki  pathname
              nowego  pliku jest nieprawidłowa (np. zawiera znaki, które nie są dozwolone w danym
              systemie plików).

       EINVAL Ostatnia składowa („basename”) ścieżki pathname  jest  nieprawidłowa  (np.  zawiera
              znaki, które nie są dozwolone w danym systemie plików).

       EISDIR pathname  odnosi  się  do  katalogu,  a  żądany  był  dostęp  z prawem zapisu (tzn.
              ustawione było O_WRONLY lub O_RDWR).

       EISDIR pathname odnosi się do istniejącego katalogu, we flags podano O_TMPFILE i jeden  z:
              O_WRONLY lub O_RDWR, lecz ta wersja jądra nie zapewnia funkcjonalności O_TMPFILE.

       ELOOP  Podczas rozwiązywania pathname napotkano zbyt wiele dowiązań symbolicznych.

       ELOOP  pathname  była  dowiązaniem  symbolicznym,  a  we flags podano O_NOFOLLOW, lecz nie
              podano O_PATH.

       EMFILE Osiągnięto  limit  liczby  otwartych  deskryptorów  pliku  na  proces  (zob.   opis
              RLIMIT_NOFILE w podręczniku getrlimit(2)).

       ENAMETOOLONG
              pathname było zbyt długie.

       ENFILE Zostało osiągnięte systemowe ograniczenie na całkowitą liczbę otwartych plików.

       ENODEV pathname  odnosi się do pliku urządzenia specjalnego, a odpowiadające mu urządzenie
              nie istnieje (jest to błąd w jądrze Linux; w takiej sytuacji powinno  być  zwracane
              ENXIO).

       ENOENT Nie ustawiono O_CREAT, a nazwany plik nie istnieje.

       ENOENT Składowa  pathname,  która  powinna  być  katalogiem nie istnieje lub jest wiszącym
              dowiązaniem symbolicznym.

       ENOENT pathname odnosi się do nieistniejącego katalogu, we flags podano O_TMPFILE i  jeden
              z:  O_WRONLY  lub  O_RDWR,  lecz  ta  wersja  jądra  nie  zapewnia  funkcjonalności
              O_TMPFILE.

       ENOMEM Nazwany plik jest FIFO,  lecz  nie  można  przydzielić  pamięci  dla  bufora  FIFO,
              ponieważ osiągnięto bezwzględny limit pamięci przydzielanej potokom na użytkownika,
              a wywołujący nie jest uprzywilejowany; zob. pipe(7).

       ENOMEM Brak pamięci jądra.

       ENOSPC Gdy pathname miało być utworzone, okazało się, że na urządzeniu na którym miało się
              znajdować brak miejsca na nowy plik.

       ENOTDIR
              Składowa  użyta  w  pathname  jako katalog w rzeczywistości nie jest katalogiem lub
              podano O_DIRECTORY, a pathname nie było katalogiem.

       ENOTDIR
              (openat())   pathname  jest  ścieżką  względną  a  dirfd  jest  deskryptorem  pliku
              odnoszącym się do pliku zamiast do katalogu.

       ENXIO  Podano  O_NONBLOCK  |  O_WRONLY,  plik o zadanej nazwie stanowi FIFO i nie jest ono
              otwarte dla żadnego procesu do odczytu.

       ENXIO  Plik  jest  specjalnym  plikiem  urządzenia,  a  odpowiadające  mu  urządzenie  nie
              istnieje.

       ENXIO  Plik jest gniazdem domeny Uniksa.

       EOPNOTSUPP
              System plików zawierający pathname nie obsługuje O_TMPFILE.

       EOVERFLOW
              Ścieżka  pathname  odnosi  się  do zwykłego pliku, który jest zbyt duży, aby móc go
              otworzyć. Zwykle jest to sytuacja, w której aplikacja  skompilowana  na  platformie
              32-bitowej  bez  -D_FILE_OFFSET_BITS=64  próbuje  otworzyć  plik  o rozmiarze ponad
              (1<<31)-1 bajtów; zob. też O_LARGEFILE powyżej. Jest  to  kod  błędu  wynikający  z
              POSIX.1; przed Linuksem 2.6.24, Linux w takiej sytuacji generował błąd EFBIG.

       EPERM  Podano znacznik O_NOATIME, ale efektywny identyfikator użytkownika wywołującego nie
              równał się właścicielowi pliku, a wywołujący nie był uprzywilejowany.

       EPERM  Operacja zablokowana,  z  powodu  zapieczętowania  pliku  (ang.  file  seal);  zob.
              fcntl(2).

       EROFS  pathname odnosi się do pliku na systemie plików tylko do odczytu, a żądano otwarcia
              w trybie do zapisu.

       ETXTBSY
              pathname odnosi się do wykonywalnego  obrazu,  który  obecnie  jest  wykonywany,  a
              zażądano dostępu do zapisu.

       ETXTBSY
              pathname  odnosi  się  do  pliku,  używanego  obecnie  jako pliku wymiany, a podano
              znacznik O_TRUNC.

       ETXTBSY
              pathname  odnosi  się  do  pliku  aktualnie  odczytywanego  przez  jądro  (np.   do
              załadowania modułu/oprogramowania układowego), a zażądano dostępu do zapisu.

       EWOULDBLOCK
              Podano  znacznik  O_NONBLOCK, a na pliku utrzymywana jest niezgodna dzierżawa (zob.
              fcntl(2)).

WERSJE

       (Niezdefiniowany) wynik O_RDONLY | O_TRUNC różni się  w  zależności  od  implementacji.  W
       wielu systemach plik jest faktycznie przycinany.

   Synchronizowane wejście/wyjście
       Opcja   POSIX.1-2008   „synchronized   I/O”   określa   różne  warianty  synchronizowanego
       wejścia/wyjścia i podaje znaczniki O_SYNC, O_DSYNC i O_RSYNC open() jako  przeznaczone  do
       kontrolowania  oczekiwanego  zachowania.  Niezależnie  od  tego,  czy  dana  implementacja
       obsługuje tę opcję, obowiązkowa jest obsługa  co  najmniej  O_SYNC  w  przypadku  zwykłych
       plików.

       Linux  implementuje  O_SYNC  i  O_DSYNC,  lecz  nie  O_RSYNC. Poniekąd niewłaściwie, glibc
       definiuje O_RSYNC jako mające tę samą wartość  co  O_SYNC  (O_RSYNC  jest  zdefiniowane  w
       linuksowym  pliku  nagłówkowym  <asm/fcntl.h>  na  architekturze HP PA-RISC, lecz nie jest
       używane).

       O_SYNC zapewnia kompletność zsynchronizowanego wejścia/wyjścia pliku w sposób gwarantujący
       spójność   tzn.   operacje  zapisu  przenoszą  dane  i  wszystkie  powiązane  metadane  na
       przedmiotowe urządzenie. O_DSYNC zapewnia kompletność  zsynchronizowanego  wejścia/wyjścia
       danych  w sposób gwarantujący spójność tzn. operacje zapisu przenoszą dane na przedmiotowe
       urządzenie, lecz przeniosą jedynie  te  aktualizowane  metadane,  które  są  konieczne  do
       pomyślnego  zakończenia  kolejnych  operacji  odczytu.  Ta druga metoda pozwala zredukować
       liczbę operacji dysku wymaganych w  przypadku  aplikacji,  które  nie  wymagają  gwarancji
       spójności pliku.

       Aby  zrozumieć  różnicę  pomiędzy  tymi  dwoma  typami  kompletności, proszę rozważyć dwie
       cząstki metadanych pliku: znacznik  czasu  ostatniej  modyfikacji  pliku  (st_mtime)  oraz
       długość pliku. Wszystkie operacje zapisu zaktualizują znacznik czasu ostatniej modyfikacji
       pliku, lecz jedynie zapisy dodające dane na końcu pliku, spowodują zmianę  jego  długości.
       Znacznik  czasu ostatniej modyfikacji nie jest wymagany do pomyślnego zakończenia operacji
       odczytu,  w  przeciwieństwie  do  długości  pliku.  Zatem  O_DSYNC  zagwarantuje   jedynie
       zaktualizowanie  metadanej  długości pliku (podczas gdy O_SYNC również metadanej znacznika
       czasu ostatniej modyfikacji pliku).

       Przed Linuksem 2.6.33, Linux implementował dla open() jedynie znacznik O_SYNC. Jednak  gdy
       podało się ten znacznik, większość systemów plików w rzeczywistości zapewniało równoważnik
       kompletności zsynchronizowanego wejścia/wyjścia danych w sposób zapewniający spójność (tj.
       O_SYNC był zaimplementowany w rzeczywistości jako ekwiwalent O_DSYNC).

       Od Linuksa 2.6.33, zapewniona jest prawidłowa obsługa O_SYNC. Jednak aby zapewnić wsteczną
       kompatybilność binarną, O_DSYNC zdefiniowano z tą samą wartością co historyczne O_SYNC,  a
       O_SYNC  zdefiniowano  jako  nową  (dwubitową)  wartość  znacznika,  która  zawiera wartość
       znacznika O_DSYNC. W ten sposób aplikacje skompilowane z nowymi nagłówkami,  otrzymają  co
       najmniej zachowanie O_DSYNC przed Linuksem 2.6.33.

   Różnice biblioteki C/jądra
       Od  glibc  2.26,  funkcja  opakowująca  open()  z  glibc  korzysta z wywołania systemowego
       openat(), zamiast z wywołania  systemowego  jądra  open().  Na  niektórych  architekturach
       działo się to także przed glibc 2.26.

STANDARDY

       open()
       creat()
       openat()
              POSIX.1-2008.

       openat2(2)  Linux.

       Znaczniki  O_DIRECT,  O_NOATIME,  O_PATH  i O_TMPFILE są typowo linuksowe. Aby uzyskać ich
       definicje, należy zdefiniować _GNU_SOURCE.

       Znaczniki O_CLOEXEC, O_DIRECTORY i O_NOFOLLOW nie są określone  w  POSIX.1-2001,  lecz  są
       określone  w  POSIX.1-2008.  Od  glibc  2.12,  można uzyskać ich definicje definiując albo
       _POSIX_C_SOURCE z wartością większą lub równą  200809L,  albo  _XOPEN_SOURCE  z  wartością
       większą  lub  równą  700.  W  glibc  2.11  i  wcześniejszych,  można  uzyskać te definicje
       definiując _GNU_SOURCE.

HISTORIA

       open()
       creat()
              SVr4, 4.3BSD, POSIX.1-2001.

       openat()
              POSIX.1-2008.  Linux 2.6.16, glibc 2.4.

UWAGI

       W Linuksie, znacznik O_NONBLOCK jest niekiedy używany w przypadkach, gdy chce się otworzyć
       plik, ale niekonieczne ma się zamiar odczytu lub zapisu z niego. Przykładowo można go użyć
       do otworzenia urządzenia, w celu uzyskania deskryptora pliku do wykorzystania z ioctl(2).

       Należy zauważyć, że open() może otwierać specjalne pliki urządzeń, lecz creat()  nie  może
       ich tworzyć. Zamiast niego należy używać mknod(2).

       Jeśli  plik  jest  nowoutworzony,  to jego pola st_atime, st_ctime, st_mtime (odpowiednio:
       czas ostatniego dostępu, czas ostatniej zmiany statusu i czas ostatniej modyfikacji,  zob.
       stat(2))  są  ustawione na czas bieżący i to samo dotyczy pól st_ctime i st_mtime katalogu
       nadrzędnego. Natomiast gdy plik jest modyfikowany z powodu użycia znacznika O_TRUNC,  jego
       pola st_ctime i st_mtime są ustawiane na czas bieżący.

       Pliki w katalogu /proc/pid/fd pokazują otwarte deskryptory pliku procesu o PID równym pid.
       Pliki w katalogu /proc/pid/fdinfo pokazują jeszcze więcej informacji o tych  deskryptorach
       pliku. Więcej informacji o obu tych katalogach znajduje się w podręczniku proc(5).

       Linuksowy  plik  nagłówkowy  <asm/fcntl.h>  nie definiuje O_ASYNC; definiowany jest jednak
       (wywodzący się z BSD) synonim FASYNC.

   Opisy otwartego pliku
       Termin „opis otwartego pliku ” (ang. „open file description”) jest używany przez  POSIX  w
       odniesieniu  do wpisów w systemowej tablicy otwartych plików. W innych kontekstach, obiekt
       ten miewa również następujące określenia  (w  nawiasach  określenia  angielskie):  „obiekt
       otwartego  pliku”  („open  file  object”),  „uchwyt  pliku” („file handle”), „wpis tablicy
       otwartych plików” („open file table entry”) albo — w żargonie  deweloperów  jądra  —  plik
       struct („struct file”).

       Gdy deskryptor pliku jest duplikowany (za pomocą dup(2) lub podobnego), to duplikat odnosi
       się do tego samego opisu otwartego pliku, co pierwotny deskryptor pliku;  oba  deskryptory
       dzielą  zatem  przesunięcie  pliku i znaczniki statusu pliku. Takie dzielenie może również
       nastąpić między procesami: proces potomny utworzony za pomocą fork(2) dziedziczy duplikaty
       deskryptorów  pliku  swojego  rodzica,  a  te  duplikaty odnoszą się do tych samych opisów
       otwartego pliku.

       Każde otwarcie pliku za pomocą open() tworzy nowy opis otwartego pliku; zatem może istnieć
       wiele opisów otwartego pliku odnoszących do i-węzła pliku.

       W  Linuksie,  można  użyć  operacji  KCMP_FILE kcmp(2) do sprawdzenia, czy dwa deskryptory
       pliku (w tym samym procesie lub w dwóch różnych procesach)  odnoszą  się  do  tego  samego
       opisu otwartego pliku.

   NFS
       Jest  wiele  niedogodności  w protokole podległym NFS, dotykających między innymi O_SYNC i
       O_NDELAY.

       Na systemach NFS z włączonym mapowaniem UID-ów, open() może zwrócić deskryptor pliku,  dla
       którego  np.  żądania  read(2)  są  zabronione przy ustawionym EACCES. Jest to związane ze
       sprawdzaniem uprawnień odbywającym się na  kliencie,  ale  to  serwer  wykonuje  mapowanie
       UID-ów podczas żądań odczytu i zapisu.

   FIFO
       Otwarcie  końca  do  odczytu lub końca do zapisu FIFO blokuje, do momentu otwarcia również
       drugiego z końców (przez inny proces lub wątek). Więcej informacji w podręczniku fifo(7).

   Tryb dostępu do pliku
       W przeciwieństwie do innych wartości, jakie można podać we flags, wartości trybu  dostępu:
       O_RDONLY,  O_WRONLYi  O_RDWR  nie  określają  pojedynczych  bitów.  Definiują one dwa bity
       niższego rzędu flags i są  zdefiniowane  jako,  odpowiednio,  0,  1  i  2.  Innymi  słowy,
       połączenie  O_RDONLY  |  O_WRONLY  jest  błędem  logicznym, w szczególności nie ma takiego
       samego znaczenia jak O_RDWR.

       Linux rezerwuje specjalny, niestandardowy  tryb  dostępu  3  (binarne  11)  we  flags,  do
       następującego  znaczenia:  sprawdź  uprawnienia  odczytu i zapisu pliku i zwróć deskryptor
       pliku, który nie może być użyty do odczytu i do zapisu. Ten  niestandardowy  tryb  dostępu
       jest  wykorzystywany  przez  niektóre  linuksowe  sterowniki  w celu zwrócenia deskryptora
       pliku, przeznaczonego tylko do typowo „sterownikowych” działań ioctl(2).

   Celowość API openat() i innych API katalogowych deskryptorów pliku
       openat() oraz inne wywołania  systemowe  i  funkcje  biblioteczne,  które  przyjmują  jako
       argument  deskryptor  pliku  odnoszący  się  do  katalogu  (tj. 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)  i  scandirat(3))  rozwiązują  dwa
       problemy starszych interfejsów, które je poprzedzały. Tu podano wyjaśnienie odnoszące  się
       do wywołania openat(), jednak analogicznie można je zastosować do pozostałych interfejsów.

       Przede  wszystkim  openat() pozwala uniknąć aplikacjom wystąpienia sytuacji wyścigu, która
       może zachodzić przy otwieraniu za pomocą open() plików w katalogach  innych,  niż  bieżący
       katalog roboczy. Wyścig wynika z tego, że pewna składowa ścieżki podanej open() mogła ulec
       zmianie równolegle z wywołaniem open(). Proszę założyć na przykład, że próbujemy  utworzyć
       plik  kat1/kat2/xxx.zal,  jeśli  plik kat1/kat2/xxx istnieje. Jednak pomiędzy sprawdzeniem
       istnienia i  krokiem  utworzenia  pliku,  kat1  lub  kat2  (które  mogą  być  dowiązaniami
       symbolicznymi)  mogą  być  zdefiniowane,  aby  wskazywać  na inne położenia. Wyścigu można
       uniknąć,  otwierając  deskryptor  pliku  katalogu  docelowego,  a  następnie  podając  ten
       deskryptor  pliku  jako  argument  dirfd  do  (przykładowo)  fstatat(2) i openat(). Użycie
       deskryptora pliku dirfd ma także inne zalety:

       •  deskryptor pliku jest stabilną referencją do katalogu, nawet gdy jego nazwa się  zmieni
          oraz

       •  otwarty deskryptor pliku zapobiega odmontowaniu systemu plików, na którym się znajduje,
          podobnie jak ma to miejsce w przypadku procesu, mającego swój bieżący katalog roboczy w
          danym systemie plików.

       Po  drugie,  openat() pozwala na implementację „bieżącego katalogu roboczego” przypisanego
       wątkowi,  za  pomocą  deskryptora(-ów)  pliku(-ów)  zarządzanych   przez   aplikację   (tę
       funkcjonalność   można   też   uzyskać  za  pomocą  sztuczek  opartych  na  korzystaniu  z
       /proc/self/fd/dirfd, lecz jest to mniej wydajne).

       Argument dirfd do tych API można pozyskać za pomocą  open()  lub  openat()  do  otworzenia
       katalogu (ze znacznikiem O_RDONLY albo O_PATH). Alternatywnie, taki deskryptor pliku można
       uzyskać stosując dirfd(3) do strumienia katalogu utworzonego za pomocą opendir(3).

       W omawianych API, gdy poda się argument dirfd równy  AT_FDCWD  albo  podana  ścieżka  jest
       bezwzględna,  API  obsługują swój argument ścieżki w taki sam sposób, jak odpowiadające im
       tradycyjne API. Jednak w tym przypadku, wiele z API posiada argument flags, pozwalający na
       dostęp do funkcjonalności, która nie jest dostępna w odpowiadającym im tradycyjnym API.

   O_DIRECT
       Znacznik  O_DIRECT  może  nakładać  ograniczenia  (związane  z  wyrównaniem) na długości i
       adresie  buforów  definiowanych  w  przestrzeni  użytkownika  oraz  przesunięciu  pliku  w
       wejściu/wyjściu.  W  Linuksie, ograniczenia związane z wyrównaniem różnią się w zależności
       od systemu plików i wersji jądra, mogą też wcale nie  występować.  Obsługa  niewyrównanych
       wejść/wyjść  O_DIRECT  również  jest  zróżnicowana; mogą one albo zawieść z błędem EINVAL,
       albo awaryjnie skorzystać z buforowanego wejścia/wyjścia.

       Od Linuksa 6.1, obsługa O_DIRECT i ograniczenia wyrównania związane z danym plikiem  można
       sprawdzić   za   pomocą   statx(2),   wykorzystując   znacznik   STATX_DIOALIGN.   Obsługa
       STATX_DIOALIGN różni się w zależności od systemu plików; więcej szczegółów  w  podręczniku
       statx(2).

       Niektóre  systemy  plików zapewniają swoje interfejsy do odpytywania ograniczeń wyrównania
       O_DIRECT, przykładowo jest to operacja XFS_IOC_DIOINFO w xfsctl(3). Gdy jednak tylko  jest
       dostępny, należy korzystać z STATX_DIOALIGN.

       Jeśli żadne w powyższych nie jest dostępne, to obsługa bezpośredniego wejścia/wyjścia oraz
       ograniczenia  związane  z  wyrównaniem  można  odgadnąć  jedynie   na   podstawie   znanej
       charakterystyki  systemu  plików,  danego pliku, nośnika danych i wersji jądra. W Linuksie
       2.4, większość systemu plików opartych na urządzeniach blokowych wymagało, aby długości  i
       adresy pamięci wszystkich segmentów wejścia/wyjścia, były wielokrotnościami rozmiaru bloku
       systemu plików (zwykle 4096 bajtów). W  Linuksie  2.6.0,  to  ograniczenie  poluzowano  do
       logicznego  rozmiaru  bloku  (zwykle  512  bajtów).  Rozmiar  logicznego  bloku urządzenia
       blokowego można sprawdzić za pomocą operacji BLKSSZGET ioctl(2) lub z powłoki, poleceniem:

           blockdev --getss

       Wejścia/wyjścia O_DIRECT nigdy nie należy uruchamiać równolegle  z  wywołaniem  systemowym
       fork(2),   jeśli   bufor  pamięci  jest  przypisaniem  prywatnym  (obejmuje  to  wszystkie
       przypisania utworzone za pomocą znacznika MAP_PRIVATE mmap(2); w tym  pamięć  przydzieloną
       do kopca oraz bufory przydzielone statycznie). Każde takie wejście/wyjście, niezależnie od
       tego, czy zostanie przesłane poprzez interfejs asynchronicznego  wejścia/wyjścia,  czy  od
       innego  wątku  procesu,  powinno być ukończone przed wywołaniem fork(2). Jeśli tak się nie
       stanie, może dojść do uszkodzenia danych  oraz  niezdefiniowanego  zachowania  w  procesie
       macierzystym  i  potomnym.  To  ograniczenie  nie  ma zastosowania w przypadku, gdy bufory
       pamięci  do  wejścia/wyjścia  O_DIRECT  utworzono  za  pomocą  shmat(2)  lub  mmap(2)   ze
       znacznikiem  MAP_SHARED.  Nie  ma  zastosowania  również  wtedy,  gdy w stosunku do bufora
       pamięci udzielono wskazówki MADV_DONTFORK za pomocą madvise(2), co zapewnia, że nie będzie
       on dostępny dla potomka po wykonaniu fork(2).

       Znacznik  O_DIRECT  wprowadzono w SGI IRIX, gdzie ograniczenia związane z wyrównaniem były
       podobne do Linuksa 2.4. IRIX ma również  wywołanie  fcntl(2)  do  odpytywania  o  poprawne
       wyrównania  i  rozmiary.  We  FreeBSD  4.x  wprowadzono  znacznik  o tej samej nazwie, ale
       nieposiadający ograniczeń wyrównania.

       Obsługę O_DIRECT dodano w Linuksie 2.4.10. Starsze  jądra  Linux  ignorują  ten  znacznik.
       Niektóre  systemy  plików  mogą  go  nie  implementować;  wówczas  zastosowanie  znacznika
       spowoduje, że open() zawiedzie z błędem EINVAL.

       Aplikacje powinny unikać mieszania O_DIRECT i zwykłego wejścia/wyjścia w tym samym  pliku,
       szczególnie  w  nachodzących  na siebie obszarach pliku. Nawet gdy system plików poprawnie
       obsługuje  zagadnienia  związane  ze  spójnością  danych  w   tej   sytuacji,   sumaryczna
       przepustowość  wejścia/wyjścia  będzie prawdopodobnie gorsza, niż przy zdecydowaniu się na
       któryś z trybów. Aplikacje powinny również  unikać  mieszania  korzystania  z  mmap(2)  na
       plikach, przy używaniu bezpośredniego wejścia/wyjścia do tych samych plików.

       Zachowanie  O_DIRECT  w systemie NFS różni się od lokalnych systemów plików. Starsze jądra
       oraz jądra skonfigurowane w pewien sposób mogą nie obsługiwać  tego  połączenia.  Protokół
       NFS  nie  obsługuje  przekazywania  znacznika  serwerowi,  zatem  wejście/wyjście O_DIRECT
       pominie  buforowanie  strony  tylko  po  stronie  klienta;  serwer  wciąż  może  buforować
       wejście/wyjście.  Klient  prosi  serwer  o  uczynienie wejścia/wyjścia synchronicznym, aby
       zachować synchroniczne zachowanie O_DIRECT. Niektóre  serwery  nie  będą  się  zachowywały
       wydajnie  w  takim  przypadku,  szczególnie  jeśli rozmiar wejścia/wyjścia jest niewielki.
       Niektóre serwery mogą być również skonfigurowane w ten  sposób,  aby  informować  klientów
       nieprawidłowo  (przedwcześnie)  o osiągnięciu stabilnego nośnika przez wejście/wyjście; ta
       metoda unika uszczerbku wydajności  kosztem  pewnego  ryzyka  utraty  spójności  danych  w
       przypadku awarii zasilania serwera. Linuksowy klient NFS nie narzuca ograniczeń związanych
       z wyrównaniem w przypadku wejścia/wyjścia O_DIRECT.

       Podsumowując, O_DIRECT jest narzędziem o potencjalnie dużych możliwościach, którego należy
       używać  ze  sporą  dawką  ostrożności.  Zaleca się, aby aplikacje korzystające z O_DIRECT,
       traktowały go jako, domyślnie wyłączoną, opcję poprawiającą wydajność.

USTERKI

       Obecnie nie da się włączyć wejścia/wyjścia sterowanego sygnałem podając  znacznik  O_ASYNC
       przy wywołaniu open(); należy użyć fcntl(2), aby włączyć ten znacznik.

       Przy  próbie określenia, czy jądro obsługuje funkcję O_TMPFILE, należy sprawdzać dwa różne
       kody błędu: EISDIR i ENOENT.

       Jeśli we flags poda się O_CREAT oraz O_DIRECTORY, a plik podany  w  ścieżce  pathname  nie
       istnieje, open() utworzy zwykły plik (tj. O_DIRECTORY zostanie zignorowany).

ZOBACZ TAKŻE

       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)

TŁUMACZENIE

       Autorami   polskiego   tłumaczenia   niniejszej   strony  podręcznika  są:  Przemek  Borys
       <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i  Michał  Kułach
       <michal.kulach@gmail.com>

       Niniejsze  tłumaczenie  jest  wolną  dokumentacją. Bliższe informacje o warunkach licencji
       można   uzyskać   zapoznając   się   z   GNU   General   Public   License   w   wersji   3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   lub   nowszej.   Nie  przyjmuje  się  ŻADNEJ
       ODPOWIEDZIALNOŚCI.

       Błędy w tłumaczeniu  strony  podręcznika  prosimy  zgłaszać  na  adres  listy  dyskusyjnej
       ⟨manpages-pl-list@lists.sourceforge.net⟩.