readv(2) System Calls Manual readv(2) NAZWA readv, writev, preadv, pwritev, preadv2, pwritev2 - czyta lub zapisuje dane do wielu buforow BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include ssize_t readv(int fd, const struct iovec *iov, int iovcnt); ssize_t writev(int fd, const struct iovec *iov, int iovcnt); ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); ssize_t preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags); ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags); Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)): preadv(), pwritev(): Od glibc 2.19: _DEFAULT_SOURCE glibc 2.19 i wczesniejsze: _BSD_SOURCE OPIS Wywolanie systemowe readv() czyta liczbe iovcnt blokow z pliku skojarzonego z deskryptorem pliku fd do wielu buforow opisanych przez iov (,,rozrzucone wejscie"). Funkcja writev() zapisuje co najwyzej iovcnt blokow opisanych przez iov do pliku skojarzonego z deskryptorem pliku fd (,,zgromadzone wyjscie"). Wskaznik iov prowadzi do struktury iovec, opisanej w iovec(3type). Wywolanie systemowe readv() dziala tak samo jak read(2), z ta roznica ze wypelnianych jest wiele buforow. Wywolanie systemowe writev() dziala tak samo jak write(2), z ta roznica ze zapisywane dane pochodza z wielu buforow. Bufory sa przetwarzane w porzadku, w ktorym zostaly wymienione w tablicy. Oznacza to, ze readv() calkowicie zapelni iov[0] zanim przejdzie do iov[1] itd. (jesli jest za malo danych, to nie wszystkie bufory w iov zostana wypelnione). Podobnie writev zapisuje calkowicie zawartosc iov[0], zanim przejdzie do iov[1], itd. Transfery danych przeprowadzane przez readv() i writev() sa atomowe: dane zapisywane przez writev() sa zapisywane jako pojedynczy blok danych, niekolidujacy z danymi zapisywanymi przez inne procesy. Analogicznie readv() gwarantuje przeczytanie sasiadujacych blokow danych, niezaleznie od operacji odczytu przeprowadzanych przez inne watki lub procesy majace deskryptory plikow odnoszace sie do tego samego otwartego pliku (patrz open(2)). preadv() i pwritev() Wywolanie systemowe preadv() laczy w sobie funkcjonalnosci dostarczane przez readv() i przez pread(2). Wykonuje to samo zadanie, co readv(), ale dodaje czwarty argument, offset, okreslajacy miejsce w pliku, w ktorym zostanie przeprowadzona operacja wejsciowa. Wywolanie systemowe pwritev() laczy w sobie funkcjonalnosci dostarczane przez writev() i przez pwrite(2). Wykonuje to samo zadanie, co writev, ale dodaje czwarty argument, offset, okreslajacy miejsce w pliku, w ktorym zostanie przeprowadzona operacja wyjsciowa. Opisywane wywolania systemowe nie zmieniaja pozycji przesuniecia w pliku. Pliki wskazywane przez fd musza pozwalac na swobodny dostep (przeszukiwanie). preadv2() i pwritev2() Te wywolania systemowe sa podobne do wywolan preadv() i pwritev(), lecz dodaja piaty argument flags, modyfikujacy zachowanie w zaleznosci od wywolania. W przeciwienstwie do preadv() i pwritev(), jesli argument offset wynosi -1, to uzywane i aktualizowane jest przesuniecie biezacego pliku. Argument flags zawiera sume bitowa (OR) z jednego lub wiecej z nastepujacych znacznikow: RWF_DSYNC (od Linuksa 4.7) Udostepnia ekwiwalent znacznika O_DSYNC open(2), tyle ze do zapisu. Znacznik ten ma znaczenie jedynie dla pwritev2(), a jego efekty stosuja sie tylko w zakresie danych zapisanych przez wywolanie systemowe. RWF_HIPRI (od Linuksa 4.6) Odczyt/zapis o wysokim priorytecie. Pozwala blokowym systemom plikow na odpytywanie urzadzenia, co zapewnia nizsze opoznienia, lecz moze wymagac dodatkowych zasobow (obecnie ta funkcja nadaje sie do uzycia wylacznie, jesli deskryptor pliku otwarto ze znacznikiem O_DIRECT). RWF_SYNC (od Linuksa 4.7) Udostepnia ekwiwalent znacznika O_SYNC open(2), tyle ze do zapisu. Znacznik ten ma znaczenie jedynie dla pwritev2(), a jego efekty stosuja sie tylko w zakresie danych zapisanych przez wywolanie systemowe. RWF_NOWAIT (od Linuksa 4.14) Nie oczekuje na dane, ktore nie sa natychmiast dostepne. Jesli poda sie ten znacznik, to wywolanie systemowe preadv2() powroci natychmiast, jesli mialoby musiec odczytywac dane z nosnika nieulotnego lub czekac na blokade. Jesli jakies dane zostaly pomyslnie odczytane, zwroci liczbe odczytanych bajtow. Jesli nie odczytano zadnych danych, zwroci -1 i ustawi errno na EAGAIN (lecz zobacz USTERKI). Obecnie, znacznik ten ma znaczenie jedynie dla preadv2(). RWF_APPEND (od Linuksa 4.16) Udostepnia ekwiwalent znacznika O_APPEND open(2), tyle ze do zapisu. Znacznik ten ma znaczenie jedynie dla pwritev2(), a jego efekty stosuja sie tylko w zakresie danych zapisanych przez wywolanie systemowe. Argument offset nie wplywa na operacje zapisu; dane sa zawsze dopisywane do konca pliku. Jednakze, jesli argument offset wynosi -1, biezace przesuniecie pliku jest uaktualniane. RWF_NOAPPEND (od Linuksa 6.9) Nie honoruje znacznika O_APPEND open(2). Znacznik ten jest istotny tylko dla pwritev2(). Historycznie, Linux uwzglednial znacznik O_APPEND, jesli byl ustawiony, i ignorowal argument przesuniecia, co jest bledem. W przypadku pwritev2(), jesli znacznik RWF_NOAPPEND jest ustawiony, argument offset jest honorowany zgodnie z przewidywaniami, czyli tak samo, jak gdyby znacznik O_APPEND nie byl ustawiony. RWF_ATOMIC (od Linuksa 6.11) Wymaga, aby zapisy do zwyklych plikow w systemie plikow korzystajacym z blokow, byly wydawane z zabezpieczeniem przed rozdartym zapisem (ang. torn-write). Zabezpieczenie przed rozdartym zapisem oznacza, ze w przypadku usterki zasilania lub dowolnej innej usterki sprzetowej zostana zapisane albo wszystkie, albo zadne dane z zapisu, jednak nigdy nie bedzie do mieszanina starych i nowych danych. Znacznik ten jest istotny tylko dla pwritev2(), a jego skutki dotycza tylko danych zapisywanych przez to wywolanie systemowe. Calkowita dlugosc zapisu musi byc potega dwojki i musi miescic sie w przedziale [stx_atomic_write_unit_min, stx_atomic_write_unit_max]. Zapis musi byc w naturalnie dopasowanym przesunieciu w pliku, z uwzglednieniem calkowitej dlugosci zapisu. Na przyklad zapis o dlugosci 32KiB na przesunieciu 32KiB w pliku jest dozwolony, natomiast zapis o dlugosci 32KiB na przesunieciu 48KiB juz nie. Gorna granice iovcnt dla pwritev2() okresla wartosc w stx_atomic_write_segments_max. Zabezpieczenie przed rozdartym zapisem dziala tylko ze znacznikiem O_DIRECT, tj. zapisy buforowane nie sa obslugiwane. Aby zagwarantowac spojnosc zapisu pomiedzy wewnetrznym stanem pliku a tym na urzadzeniu dyskowym, konieczne jest podanie O_SYNC lub O_DSYNC przy open(2). Taka sama gwarancja zsynchronizowanego wejscia/wyjscie jak opisana w open(2) jest zapewniana, gdy uzywane sa te znaczniki, albo ich odpowiedniki, oraz wywolania systemowe (np. gdy podano RWF_SYNC dla pwritev2()). RWF_DONTCACHE (od Linuksa 6.14) Odczyty lub zapisy do zwyklego pliku wyczyszcza zawartosc utworzonego bufora strony po zakonczeniu operacji. Rozni sie to od zwyklego buforowanego wejscia/wyjscia, gdzie dane zwykle pozostaja w buforze do momentu, gdy zostanie on odzyskany ze wzgledu na potrzebna pamiec. Jesli dane zakresy odczytywanego lub zapisywanego wejscia/wyjscia juz znajdowaly sie w buforze przed tym odczytem lub zapisem, to nie zostana one wyczyszczone po zakonczeniu operacji wejscia/wyjscia. Dodatkowo, wszelkie zakresy zmodyfikowane (dirty) przez operacje zapisu z ustawionym RWF_DONTCACHE zostana przeznaczone do zapisu zwrotnego. Jest to podobne do wywolania sync_file_range(2) z SYNC_FILE_RANGE_WRITE w celu rozpoczecia zapisu zwrotnego zadanego zakresu. RWF_DONTCACHE jest wskazowka, wobec ktorej, pomimo proby jej spelnienia, nie istnieje gwarancja co do stanu bufora strony po zakonczeniu operacji. Przy uzyciu w systemie plikow lub na urzadzeniu blokowym, ktory go nie obsluguje, zwroci -1 i spowoduje ustawienie errno na EOPNOTSUPP. WARTOSC ZWRACANA Gdy sie powioda, funkcje readv(), preadv() i preadv2() zwracaja liczbe przeczytanych bajtow, a funkcje writev(), pwritev() i pwritev2() zwracaja liczbe bajtow zapisanych. Prosze zauwazyc, ze nie jest bledem przeslanie mniejszej liczby bajtow niz zadano przez poprawne wywolanie (zob. read(2) i write(2)). W razie wystapienia bledu zwracane jest -1 i ustawiane errno wskazujac blad. BLEDY Zwracane bledy sa takie same, jak w przypadku funkcji read(2) i write(2). Ponadto preadv(), preadv2(), pwritev() i pwritev2() moga takze zwrocic bledy takie jak w przypadku lseek(2). Dodatkowo zdefiniowane sa nastepujace bledy: EINVAL Suma wartosci iov_len przekracza rozmiar ssize_t. EINVAL Jesli podano RWF_ATOMIC, polaczenie sumy wartosci iov_len i wartosci offset nie jest zgodne z regulami okreslonymi dla dlugosci i przesuniecia, przy stosowaniu zabezpieczenia przed rozdartym zapisem (ang. torn-write). EINVAL Liczba iovcnt wektorow wynosi mniej niz zero lub jest wieksza od dozwolonego maksimum. Jesli podano RWF_ATOMIC, maksimum wynika z wartosci stx_atomic_write_segments_max ze statx. EOPNOTSUPP We flags ustawiono RWF_DONTCACHE, a plik tego nie obslugiwal. EOPNOTSUPP Jako flags podano nieznana flage. WERSJE Roznice biblioteki C/jadra Surowe wywolania systemowe preadv() i pwritev() maja sygnatury wywolan rozniace sie subtelnie od odpowiadajacych im w funkcji opakowujacej biblioteki GNU C pokazanych w SKLADNI. Ostatni argument offset, jest rozpakowany przez funkcje opakowujaca na dwa argumenty wywolania systemowego: unsigned long pos_l, unsigned long pos Argumenty te zawieraja 32 bitowy offset w kolejnosci odpowiednio, od najmniej i od najbardziej znaczacego bitu. STANDARDY readv() writev() POSIX.1-2024. preadv() pwritev() BSD. preadv2() pwritev2() Linux. HISTORIA readv() writev() POSIX.1-2001, 4.4BSD (pojawilo sie pierwotnie w 4.2BSD). preadv() pwritev() Linux 2.6.30, glibc 2.10. preadv2() pwritev2() Linux 4.6, glibc 2.26. Historyczne roznice biblioteki C/jadra Aby rozwiazac sytuacje, gdy IOV_MAX bylo tak niskie we wczesnych wersjach Linuksa, funkcje opakowujace readv() i writev() wykonywaly pewne dodatkowe dzialania po wykryciu, ze odpowiednie wywolanie systemowe zakonczylo sie bledem z powodu przekroczenia limitu. W takim wypadku funkcja readv() biblioteki glibc przydzielala tymczasowy bufor, wystarczajaco duzy, by pomiescic wszystkie elementy okreslone przez iov, przekazywala ten bufor wywolaniu systemowemu read(2), kopiowala dane z bufora tymczasowego do lokalizacji okreslonych przez iov, a nastepnie zwalniala pamiec bufora. Funkcja glibc dla writev() wykonywala analogiczne zadanie, uzywajac bufora tymczasowego i wywolania funkcji write(2). Potrzeba tych dodatkowych dzialan funkcji opakowujacych glibc przestala istniec od Linuksa 2.2. Jednak glibc wciaz udostepnial to zachowanie do glibc 2.10. Poczynajac od wersji glibc 2.9, funkcje opakowujace wykonywaly to dzialanie tylko jesli biblioteka wykryla, ze system dziala pod kontrola jadra Linux starszego niz Linux 2.6.18 (wybor tej wersji jadra nie ma glebszej przyczyny). Od glibc 2.10 (wymagajacej co najmniej Linuksa 2.6.32) funkcje opakowujace glibc bezposrednio przywoluja wywolania systemowe. UWAGI POSIX.1 pozwala w implementacji umiescic ograniczenie liczby argumentow, ktore moga byc przekazane w iov. Implementacja moze rozglosic ten limit definiujac IOV_MAX w lub w czasie uruchomienia, zwracana wartoscia z sysconf(_SC_IOV_MAX). Na wspolczesnych systemach Linux limit ten wynosi 1024. W czasach Linuksa 2.0 wynosil 16. USTERKI Linux 5.9 i Linux 5.10 sa obarczone bledem: preadv2() ze znacznikiem RWF_NOWAIT moze zwrocic 0 nawet, gdy nie jest to koniec pliku. PRZYKLADY Nastepujacy przykladowy kod pokazuje uzycie funkcji writev(): char *str0 = "witaj "; char *str1 = "swiecie\n"; ssize_t nwritten; struct iovec iov[2]; iov[0].iov_base = str0; iov[0].iov_len = strlen(str0); iov[1].iov_base = str1; iov[1].iov_len = strlen(str1); nwritten = writev(STDOUT_FILENO, iov, 2); ZOBACZ TAKZE pread(2), read(2), write(2) TLUMACZENIE Tlumaczenie niniejszej strony podrecznika: Robert Luberda i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.18 22 lutego 2026 r. readv(2)