Scroll to navigation

sendfile(2) System Calls Manual sendfile(2)

NAZWA

sendfile - przesyła dane pomiędzy deskryptorami plików

BIBLIOTEKA

Standardowa biblioteka C (libc, -lc)

SKŁADNIA

#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *_Nullable offset,
                 size_t count);

OPIS

sendfile() kopiuje dane pomiędzy dwoma deskryptorami plików. Kopiowanie odbywa się wewnątrz jądra, dlatego sendfile() jest wydajniejsze niż połączenie read(2) z write(2), które wymagałoby przesłania danych do i z przestrzeni użytkownika.

in_fd powinien być deskryptorem pliku otwartym do odczytu, a out_fd powinien być deskryptorem otwartym do zapisu.

Jeśli offset nie wynosi NULL, to wskazuje on na zmienną przechowującą przesunięcie pliku, od którego sendfile() zacznie odczytywać dane z in_fd. Gdy sendfile() powróci, zmienna ta zostanie ustawiona na przesunięcie bajtu, który następuje po ostatnim odczytanym bajcie. Jeśli offset nie wynosi NULL, to sendfile() nie modyfikuje przesunięcia pliku in_fd; w innym przypadku przesunięcie pliku jest dostosowywane, aby uwzględnić liczbę bajtów odczytanych z in_fd.

Jeśli offset wynosi NULL, to dane będą odczytane z in_fd, począwszy od przesunięcia pliku, a przesunięcie pliku zostanie zaktualizowane przez to wywołanie.

count jest liczbą bajtów do skopiowania pomiędzy deskryptorami plików.

Argument in_fd musi odnosić się do pliku obsługującego operacje w stylu mmap(2) (tj. nie może być gniazdem).

Przed Linuksem 2.6.33, out_fd musiał odnosić się do gniazda. Od Linuksa 2.6.33 może być to dowolny plik. Jeśli jest to zwykły plik, to sendfile() odpowiednio dostosowuje przesunięcie pliku.

WARTOŚĆ ZWRACANA

Jeśli przesłanie się powiodło, zwracana jest liczba bajtów zapisanych do out_fd. Proszę zauważyć, że pomyślne wywołanie do sendfile() może zapisać mniej bajtów niż zażądano; wywołujący powinien być przygotowany na ponowienie wywołania, jeśli wystąpiły niewysłane bajty. Zob. też UWAGI.

W razie wystąpienia błędu zwracane jest -1 i ustawiane errno wskazując błąd.

BŁĘDY

Wybrano nieblokujące wejście/wyjście za pomocą O_NONBLOCK, a zapis zablokowałby.
Plik wejściowy nie został otwarty do odczytu lub plik wyjściowy nie został otwarty do zapisu.
Niepoprawny adres.
Deskryptor nie jest prawidłowy lub zablokowany; albo operacja w stylu mmap(2) nie jest dostępna dla in_fd; albo count jest ujemne.
out_fd ma ustawiony znacznik O_APPEND. Obecnie nie jest to obsługiwane przez sendfile().
Nieokreślony błąd przy odczycie z in_fd.
Zabrakło pamięci do odczytu z in_fd.
count jest zbyt duże, operacja spowodowałaby przekroczenie maksymalnego rozmiaru pliku wejściowego lub pliku wyjściowego.
offset nie wynosi NULL, lecz plik wejściowy nie jest przewijalny.

WERSJE

sendfile() pojawiło się po raz pierwszy w Linuksie 2.2. Plik include <sys/sendfile.h> jest obecny od glibc 2.1.

STANDARDY

Nie jest określone w POSIX.1-2001, ani w innych standardach.

Inne systemy uniksowe implementują sendfile() z różnym zachowaniem i prototypami. Nie należy stosować tego wywołania w przenośnym programach.

UWAGI

sendfile() dokona transferu co najwyżej 0x7ffff000 (2 147 479 552) bajtów, zwracając liczbę bajtów faktycznie przesłanych (jest to prawdziwe zarówno dla systemów 32 jak i 64-bitowych).

Jeśli planuje się używać sendfile() do wysyłania plików do gniazda TCP, lecz przed zawartością pliku trzeba dołączyć jakieś dane nagłówka, przydatne będzie korzystanie z opcji TCP_CORK, opisanej w podręczniku tcp(7), w celu ograniczenia liczby pakietów i poprawienia wydajności.

W Linuksie 2.4 i wcześniejszych, out_fd mógł odnosić się także do zwykłego pliku; ta możliwość zniknęła w serii jąder Linux 2.6.x, lecz przywrócono ją w Linuksie 2.6.33.

Pierwotne, linuksowe wywołanie systemowe sendfile() nie było zaprojektowane do obsługi dużych przesunięć plików. Z tego względu w Linuksie 2.4 dodano sendfile64(), z szerszym typem argumentu offset. Funkcja opakowująca sendfile() z glibc radzi sobie z różnicami w jądrze w sposób transparentny.

Aplikacje mogą uznać za stosowne awaryjnie korzystanie z read(2) i write(2) w przypadku, gdy sendfile() zawiedzie z błędem EINVAL lub ENOSYS.

Jeśli out_fd odnosi się do gniazda lub potoku z obsługą zero-copy, wywołujący muszą upewnić się, że przesyłane części pliku, do których odnosi się in_fd, pozostaną niezmodyfikowane do momentu skonsumowania przesłanych danych przez odczytującego na drugim końcu out_fd.

Typowo linuksowe wywołanie splice(2) obsługuje przesyłanie danych pomiędzy dwoma dowolnymi deskryptorami plików, pod warunkiem, że jeden (lub obydwa) z nich jest potokiem.

ZOBACZ TAKŻE

copy_file_range(2), mmap(2), open(2), socket(2), splice(2)

TŁUMACZENIE

Tłumaczenie niniejszej strony podręcznika: 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 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.

4 grudnia 2022 r. Linux man-pages 6.03