Deskryptor pliku

W komputerowych systemach operacyjnych Unix i Unix deskryptor pliku ( FD , rzadziej fildes ) jest unikalnym dla procesu identyfikatorem ( uchwytem ) pliku lub innego zasobu wejścia/wyjścia , takiego jak potok lub gniazdo sieciowe .

Deskryptory plików mają zwykle nieujemne wartości całkowite , przy czym wartości ujemne są zarezerwowane do wskazania „brak wartości” lub warunki błędu.

Deskryptory plików są częścią POSIX API . Każdy proces uniksowy (może z wyjątkiem demonów ) powinien mieć trzy standardowe deskryptory plików POSIX, odpowiadające trzem standardowym strumieniom :

Wartość całkowita Nazwa < unistd.h > stała symboliczna < stdio.h > strumień plików
0 Wejście standardowe STDIN_FILENO stdin
1 Standardowe wyjście STDOUT_FILENO stdout
2 Standardowy błąd STDERR_FILENO stderr

Przegląd

Deskryptory plików dla pojedynczego procesu, tablica plików i tablica i-węzłów . Zauważ, że wiele deskryptorów plików może odwoływać się do tego samego wpisu tablicy plików (np. w wyniku wywołania systemowego dup ) i że wiele wpisów tablicy plików może z kolei odnosić się do tego samego i-węzła (jeśli był otwierany wiele razy; tabela jest nadal uproszczony, ponieważ reprezentuje i-węzły według nazw plików, mimo że i-węzeł może mieć wiele nazw ). Deskryptor pliku 3 nie odnosi się do niczego w tabeli plików, co oznacza, że ​​został zamknięty.

tabeli deskryptorów plików dla poszczególnych procesów, utrzymywanej przez jądro, która z kolei indeksuje do ogólnosystemowej tabeli plików otwieranych przez wszystkie procesy, zwanej tablicą plików . Ta tabela rejestruje tryb , w jakim plik (lub inny zasób) został otwarty: do odczytu, zapisu, dołączania i ewentualnie innych trybów. Indeksuje również do trzeciej tabeli zwanej tablicą i-węzłów , która opisuje rzeczywiste pliki bazowe. Aby wykonać wejście lub wyjście, proces przekazuje deskryptor pliku do jądra poprzez wywołanie systemowe , a jądro uzyskuje dostęp do pliku w imieniu procesu. Proces nie ma bezpośredniego dostępu do pliku ani tabel i-węzłów.

W systemie Linux zestaw deskryptorów plików otwartych w procesie można uzyskać pod ścieżką /proc/PID/fd/ , gdzie PID jest identyfikatorem procesu . Deskryptor pliku /proc/PID/fd/0 to stdin , /proc/PID/fd/1 to stdout , a /proc/PID/fd/2 to stderr . Jako skrót do nich, każdy działający proces może również uzyskać dostęp do własnych deskryptorów plików poprzez foldery /proc/self/fd i /dev/fd .

W systemach uniksopodobnych deskryptory plików mogą odnosić się do dowolnego typu pliku uniksowego nazwanego w systemie plików. Oprócz zwykłych plików obejmuje to katalogi , urządzenia blokowe i znakowe (zwane także „plikami specjalnymi”), gniazda domeny Unix i nazwane potoki . Deskryptory plików mogą również odnosić się do innych obiektów, które normalnie nie istnieją w systemie plików, takich jak anonimowe potoki i gniazda sieciowe .

Struktura danych FILE w standardowej bibliotece we/wy języka C zwykle zawiera deskryptor pliku niskiego poziomu dla danego obiektu w systemach typu Unix. Ogólna struktura danych zapewnia dodatkową abstrakcję i zamiast tego jest nazywana uchwytem pliku .

Operacje na deskryptorach plików

Poniżej wymieniono typowe operacje na deskryptorach plików w nowoczesnych systemach typu Unix . Większość z tych funkcji jest zadeklarowana w <unistd.h> , ale niektóre zamiast tego znajdują się w nagłówku <fcntl.h> .

Tworzenie deskryptorów plików

  • otwórz ()
  • utwórz()
  • gniazdo elektryczne()
  • zaakceptować()
  • para gniazd()
  • rura()
  • epoll_create() (Linux)
  • signalfd() (Linux)
  • eventfd() (Linux)
  • timerfd_create() (Linux)
  • memfd_create() (Linux)
  • userfaultfd() (Linux)
  • fanotify_init() (Linux)
  • inotify_init() (Linux)
  • clone() (z flagą CLONE_PIDFD, Linux)
  • pidfd_open() (Linux)
  • open_by_handle_at() (Linux)

Wyprowadzanie deskryptorów plików

  • dirfd()
  • plik numer()

Operacje na pojedynczym deskryptorze pliku

  • czytać (), pisać ()
  • czytajv() , piszv()
  • pread() , pwrite()
  • recv() , wyślij()
  • recvfrom() , sendto()
  • recvmsg() , sendmsg() (używane również do wysyłania FD do innych procesów przez gniazdo domeny Unix)
  • recvmmsg() , sendmmsg()
  • szukaj() , szukaj()
  • fstat()
  • fstatvfs()
  • fchmod()
  • fchown()
  • fruncate()
  • fsync()
  • fdatasync()
  • fdopendir()
  • fgetxattr() , fsetxattr() (Linux)
  • flistxattr() , fremovexattr() (Linux)
  • statx (Linux)
  • zestawy (Linux)
  • vmsplice() (Linux)
  • pidfd_send_signal() (Linux)
  • waitid() (z typem identyfikatora P_PIDFD, Linux)
  • fdopen() (funkcja stdio: konwertuje deskryptor pliku na PLIK*)
  • dprintf() (funkcja stdio: drukuje do deskryptora pliku)

Operacje na wielu deskryptorach plików

  • wybierz() , pwybierz()
  • ankieta() , ppoll()
  • epoll_wait() , epoll_pwait() , epoll_pwait2() (Linux, pobiera pojedynczy filedescriptor epoll, aby czekać na wiele innych deskryptorów plików)
  • epoll_ctl() (dla Linuksa)
  • kqueue() (dla systemów opartych na BSD).
  • Wyślij plik()
  • splice() , tee() (dla Linuksa)
  • copy_file_range() (dla Linuksa)
  • close_range() (dla Linuksa)

Operacje na tablicy deskryptorów plików

Funkcja fcntl() służy do wykonywania różnych operacji na deskryptorze pliku, w zależności od przekazanego mu argumentu polecenia. Istnieją polecenia do pobierania i ustawiania atrybutów powiązanych z deskryptorem pliku, w tym F_GETFD, F_SETFD, F_GETFL i F_SETFL .

  • zamknąć()
  • closefrom() (tylko BSD i Solaris; usuwa wszystkie deskryptory plików większe lub równe podanej liczbie)
  • dup() (duplikuje istniejący deskryptor pliku, gwarantując, że będzie to deskryptor pliku o najniższej dostępnej liczbie)
  • dup2 () , dup3() (w razie potrzeby zamknij fd1 i ustaw deskryptor pliku fd1 na otwarty plik fd2)
  • fcntl (F_DUPFD)

Operacje modyfikujące stan procesu

  • fchdir() (ustawia bieżący katalog roboczy procesu na podstawie deskryptora pliku katalogu)
  • mmap () (odwzorowuje zakresy pliku na przestrzeń adresową procesu)

Blokowanie plików

  • trzoda()
  • fcntl() (F_GETLK, F_SETLK i F_SETLKW)
  • blokada()

Gniazda

  • łączyć()
  • wiązać()
  • Słuchać()
  • accept() (tworzy nowy deskryptor pliku dla połączenia przychodzącego)
  • dostaje nazwę skarpetki()
  • getpeername()
  • getockopt()
  • setsockopt()
  • shutdown() (zamyka jedną lub obie połowy pełnego dupleksu połączenia)

Różnorodny

  • ioctl() (duży zbiór różnych operacji na jednym deskryptorze pliku, często powiązany z urządzeniem)

Nadchodzące operacje

Szereg nowych operacji na deskryptorach plików został dodany do wielu nowoczesnych systemów uniksopodobnych, a także do licznych bibliotek C, które mają zostać ujednolicone w przyszłej wersji POSIX . Sufiks at oznacza, że ​​funkcja przyjmuje dodatkowy pierwszy argument dostarczający deskryptor pliku, z którego są rozwiązywane ścieżki względne , formularze pozbawione przyrostka at stają się w ten sposób równoważne z przekazaniem deskryptora pliku odpowiadającego bieżącemu katalogowi roboczemu . Celem tych nowych operacji jest obrona przed określoną klasą TOCTOU .

  • otwórz()
  • faccess()
  • fchmodat()
  • fchownat()
  • fstat()
  • futimesat()
  • łącze()
  • mkdirat()
  • mknodat()
  • Odczyt łącza()
  • zmień nazwę()
  • dowiązanie symboliczne ()
  • odłącz ()
  • mkfifoat()
  • fdopendir()

Deskryptory plików jako możliwości

Uniksowe deskryptory plików zachowują się na wiele sposobów jako możliwości . Mogą być przekazywane między procesami w gniazdach domeny Unix za pomocą wywołania systemowego sendmsg() . Należy jednak zauważyć, że to, co jest faktycznie przekazywane, to odniesienie do „opisu otwartego pliku”, który ma zmienny stan (przesunięcie pliku oraz status pliku i flagi dostępu). To komplikuje bezpieczne korzystanie z deskryptorów plików jako możliwości, ponieważ gdy programy współużytkują dostęp do tego samego otwartego opisu pliku, mogą zakłócać wzajemne korzystanie z niego, zmieniając na przykład jego przesunięcie lub to, czy jest blokujący, czy nieblokujący. W systemach operacyjnych, które są specjalnie zaprojektowane jako systemy możliwości, bardzo rzadko istnieje zmienny stan powiązany z samą zdolnością.

Tabela deskryptorów plików procesu Unix jest przykładem listy C.

Zobacz też