write(2) System Calls Manual write(2) NAZWA write - zapisuje do deskryptora pliku BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include ssize_t write(int fd, const void buf[.count], size_t count); OPIS write() zapisuje do count bajtow, z bufora rozpoczynajacego sie w buf, do pliku okreslonego przez deskryptor pliku fd. Liczba bajtow zapisanych moze byc mniejsza niz count jezeli na przyklad: nie ma wystarczajacej ilosci wolnej przestrzeni na urzadzeniu fizycznym; zasoby RLIMIT_FSIZE zostaly wyczerpane (patrz setrlimit(2)); wywolanie zostalo przerwane przez obsluge sygnalu, po zapisaniu mniej niz count bajtow (zob. rowniez podrecznik pipe(7)). Dla przeszukiwalnych plikow (tj. takich, na ktorych mozna uzyc lseek(2) np. zwyklych plikow) zapis ma miejsce w danym przesunieciu pliku i to przesuniecie jest zwiekszane o ilosc aktualnie zapisanych danych. Jezeli plik zostal otwarty (open(2)) z O_APPEND wtedy, przed zapisem, przesuniecie jest ustawiane na koniec pliku. Dostosowanie przesuniecia pliku i operacja zapisu sa wykonywane jako nierozdzielne (atomowe). Standard POSIX wymaga, aby odczyt (read(2)), ktory moze nastapic po zapisie (write()) zwrocil nowe dane. Prosimy zauwazyc, ze nie wszystkie systemy plikow sa zgodne z POSIX. Zgodnie z POSIX.1, jesli count jest wieksze niz SSIZE_MAX, wynik zalezy od definicji w implementacji; zob. UWAGI odnosnie gornego limitu w Linuksie. WARTOSC ZWRACANA Po pomyslnym zakonczeniu zwracana jest liczba zapisanych bajtow. Po bledzie zwracane jest -1 i ustawiane errno, wskazujac blad. Prosze zauwazyc, ze pomyslne write() moze przetransferowac mniej bajtow, niz count. Takie czesciowe zapisy moga wystapic z roznych powodow np. z powodu zbyt malej dostepnej przestrzeni na urzadzeniu dyskowym, do zapisu wszystkich zadanych bajtow; albo ze wzgledu na przerwanie, zablokowanego write() zapisujacego do gniazda, potoku itp., przez procedure obslugi sygnalu, po transferze czesci, ale nie wszystkich zadanych danych. W przypadku zapisu czesciowego, wywolujacy moze wykonac kolejne write(), aby przetransferowac pozostale bajty. Kolejne wywolanie albo dokona transferu dalszych bajtow, albo moze zawiesc z bledem (np. gdy dysk jest teraz pelny). Jezeli count jest zerem a fd wskazuje na zwykly plik, wtedy write() moze zwrocic status niepowodzenia jezeli zostanie wykryty jeden z ponizszych bledow. Jezeli nie wykryto bledow lub nie dokonano proby wykrycia bledow, 0 jest zwracane bez zadnych innych skutkow. Jezeli count jest zerem, a fd odwoluje sie do pliku innego typu niz zwykly, skutki nie sa sprecyzowane. BLEDY EAGAIN Deskryptor pliku fd odwoluje sie do gniazda i zostal oznaczony jako nieblokujacy (O_NONBLOCK), a zapis go zablokuje. Zob. open(2) aby dowiedziec sie wiecej o znaczniku O_NONBLOCK. EAGAIN lub EWOULDBLOCK Deskryptor pliku fd odwoluje sie do gniazda i zostal oznaczony jako nieblokujacy (O_NONBLOCK), a zapis go zablokuje. POSIX.1-2001 pozwala w tej sytuacji na zwrocenie bledu ale nie wymaga aby ta stala miala taka sama wartosc, portowalna aplikacja powinna sprawdzac obie mozliwosci. EBADF fd nie jest prawidlowym deskryptorem pliku lub nie jest otwarty do zapisu. EDESTADDRREQ fd odwoluje sie do gniazda datagramowego dla ktorego adres nie zostal ustalony przy uzyciu connect(2). EDQUOT Przydzial blokow dyskowych uzytkownika, dotyczacy systemu plikow zawierajacego plik wskazany przez fd, zostal wyczerpany. EFAULT buf jest poza dostepna przestrzenia adresowa. EFBIG Dokonano proby zapisu pliku, ktory przekracza zdefiniowane w implementacji maksymalne rozmiary pliku, rozmiary pliku procesu lub zapis na pozycje wykraczajaca poza maksymalne dozwolone przesuniecie. EINTR Wywolanie zostalo przerwane przez sygnal, przed zapisaniem jakichkolwiek danych, patrz signal(7). EINVAL fd jest dolaczony do obiektu nieodpowiedniego do zapisu, plik zostal otwarty ze znacznikiem O_DIRECT, a adres podany w buf badz wartosc count lub przesuniecie nie zostaly odpowiednio dopasowane. EIO Wystapil niskopoziomowy blad wejscia/wyjscia podczas modyfikacji i-wezla. Blad ten moze byc zwiazany z konczeniem zapisywania danych wczesniejszego write(), ktore moglo byc wydane wobec innego deskryptora pliku odnoszacego sie do tego samego pliku. Od Linuksa 4.13, bledy wynikajace z konczenia zapisywania wczesniejszego wywolania moga byc zgloszone przez kolejne zadanie write() i beda zgloszone przez kolejne fsync(2) (niezaleznie od ewentualnego wczesniejszego zgloszenia przez write()). Alternatywnym powodem bledu EIO w sieciowych systemach plikow, moze byc zdjecie blokady doradczej z deskryptora pliku i zagubienie tej blokady. Wiecej informacji w rozdziale Zagubione blokady w podreczniku fcntl(2). ENOSPC Urzadzenie zawierajace plik wskazany przez fd nie ma miejsca na dane. EPERM Operacja zablokowana, z powodu zapieczetowania pliku (ang. file seal); zob. fcntl(2). EPIPE fd jest podlaczony do potoku lub gniazda, ktorego koniec do odczytu jest zamkniety. Gdy taka sytuacja nastepuje, proces zapisujacy rowniez otrzyma sygnal SIGPIPE (wiec wartosc zwracana przez zapisujacego jest widziana tylko wowczas, gdy program obsluguje, blokuje lub ignoruje ten sygnal). Zaleznie od obiektu podlaczonego do fd, moga takze zajsc inne (nieopisane) bledy. STANDARDY POSIX.1-2008. HISTORIA SVr4, 4.3BSD, POSIX.1-2001. Pod SVr4 zapis moze byc przerwany, a blad EINTR zwrocony, w dowolnym momencie, nie tylko tuz przed zapisem jakichkolwiek danych. UWAGI Pomyslny powrot z write() nie daje gwarancji, ze dane zostaly faktycznie zapisane na urzadzeniu. W niektorych systemach plikow, w tym NFS, nie ma nawet pewnosci, ze przestrzen potrzebna do zapisu zostala pomyslnie zarezerwowana. W takim przypadku, niektore bledy moga byc odlozone do kolejnego wywolania write(), fsync(2) lub nawet close(2). Jedynym sposobem, aby miec pewnosc, ze dane zostaly zapisane, jest wywolanie fsync(2), po zakonczeniu zapisywania wszystkich danych przez write(). Jezeli write() zostanie przerwany przez obsluge sygnalu przed zapisaniem jakichkolwiek danych, wtedy wywolanie nie powiedzie sie i zwracany jest blad EINTR; jezeli przerwanie nastapi po zapisaniu co najmniej jednego bajtu danych, wywolanie powiedzie sie i zwroci ilosc zapisanych bajtow danych. W Linuksie, write() (i podobne wywolania systemowe) moga dokonac transferu co najwyzej 0x7ffff000 (2 147 479 552) bajtow, zwracajac liczbe bajtow rzeczywiscie przetransferowanych (jest to prawdziwe zarowno dla systemow 32 jak i 64-bitowych). Blad zwracany przy wykonywaniu write(), uzywajacego bezposredniego wejscia/wyjscia, nie oznacza, ze caly zapis sie nie powiodl. Czesc danych mogla byc zapisana, dlatego dane na przesunieciu pliku, na ktorym write() probowal zapisywac, nalezy uwazac za niespojne. USTERKI Zgodnie z POSIX.1-2008/SUSv4 Section XSI 2.9.7 (,,Thread Interactions with Regular File Operations"): Wszystkie ponizsze funkcje powinny byc atomowe w odniesieniu do innych, biorac pod uwage wyniki okreslone w POSIX.1-2008, gdy dzialaja na zwyklych plikach lub dowiazaniach symbolicznych: ... Sposrod wymienionych tam dalej API sa miedzy innymi write() i writev(2). I sposrod efektow, ktore powinny byc atomowe pomiedzy watkami (i procesami) jest aktualizacja przesuniecia pliku. Jednak przed Linuksem 3.14 tak sie nie dzialo: jesli dwa procesy dzielace otwarty deskryptor pliku (zob. open(2)) przeprowadzaly write() (lub writev(2)) w tym samym czasie, to operacje wejscia/wyjscia nie byly atomowe w odniesieniu do aktualizacji przesuniecia pliku, co powodowalo, ze bloki danych wypisywane przez dwa procesy mogly sie (nieprawidlowo) nakladac. Problem zostal naprawiony w Linuksie 3.14. ZOBACZ TAKZE close(2), fcntl(2), fsync(2), ioctl(2), lseek(2), open(2), pwrite(2), read(2), select(2), writev(2), fwrite(3) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Artur Kruszewski , Michal Kulach i Robert Luberda 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.8 2 maja 2024 r. write(2)