| sendfile(2) | System Calls Manual | sendfile(2) |
sendfile - przesyła dane pomiędzy deskryptorami plików
Standardowa biblioteka C (libc, -lc)
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *_Nullable offset,
size_t count);
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). Od Linuksa 5.12 nie dotyczy to sytuacji, gdy out_fd jest potokiem; wówczas sendfile() upraszcza się do splice(2) i stosują się jego ograniczenia.
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 przewijalny, to sendfile() odpowiednio dostosowuje przesunięcie pliku.
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.
Inne systemy uniksowe implementują sendfile() z różnym zachowaniem i prototypami. Nie należy stosować tego wywołania w przenośnym programach.
Brak.
Linux 2.2, glibc 2.1.
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.
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.
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.
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.
| 2 maja 2024 r. | Linux man-pages 6.9.1 |