WRITE(2) | Manuale del programmatore di Linux | WRITE(2) |
write - Scrive su un descrittore di file
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
write() scrive fino a count byte dal buffer che inizia da buf nel file a cui fa riferimento il descrittore di file fd.
Il numero di byte scritti potrebbe essere meno di count se, per esempio, non c'è spazio sufficiente sul supporto fisico sottostante, o se si raggiunge il limite della risorsa RLIMIT_FSIZE (vedere setrlimit(2)), o se la chiamata è stata interrotta da un handler di segnale dopo che ha scritto meno di count byte (vedere anche pipe(7)).
Per un file che si può spostare (cioè un file a cui si può applicare lseek(2), per esempio un file regolare), la scrittura viene eseguita all'offset del file, e l'offset del file viene incrementato dal numero di byte effettivamente scritti. Se il file è stato aperto da open(2) con O_APPEND, l'offset del file viene prima impostato alla fine del file, e poi scritto. La regolazione dell'offset del file e l'operazione di scrittura vengono eseguite come un'operazione atomica.
POSIX richiede che una chiamata read(2) avvenuta dopo l'esecuzione di una chiamata write() restituisca i nuovi dati. Notare che non tutti i filesystem sono conformi a POSIX.
Secondo POSIX.1, se count è maggiore di SSIZE_MAX, il risultato è definito dall'implementazione; vedi NOTE per il limite superiore in Linux.
Se è andato tutto bene, la funzione restituisce il numero di byte scritti. In caso di errore viene restituito -1, e errno viene impostato per indicare la causa dell'errore.
Si noti che una chiamata write() andata a buon fine può trasferire meno di count byte. Tali scritture parziali possono avvenire per diverse ragioni; per esempio, perché lo spazio sul dispositivo del disco era insufficiente per scrivere tutti i byte richiesti, o perché una chiamata write() bloccata su un socket, una pipe, o simili è stata interrotta da un gestore di segnale dopo che aveva trasferito alcuni byte, ma prima di aver trasferito tutti quelli richiesti. Nel caso di un write parziale, il chiamante può fare un'altra chiamata a write() per trasferire i byte rimanenti. La chiamata successiva o trasferisce ulteriori byte o può determinare un errore (e.g., se il disco ora è pieno).
Se count è zero, e fd fa riferimento ad un file regolare, write() può restituire uno stato di insuccesso se viene rilevato uno degli errori descritti più avanti. Se non vengono rilevati errori, o se non la rilevazione degli errori non è eseguita, restituisce 0 senza causare altri effetti. Se count è zero e fd fa riferimento ad un file diverso da uno regolare, i risultati non sono specificati.
Possono accadere altri errori, in funzione dell'oggetto connesso a fd.
SVr4, 4.3BSD, POSIX.1-2001.
Sotto SVr4 una scrittura può essere interrotta e restituire EINTR in qualsiasi punto, non solo prima che venga scritto un dato.
Tipi size_t e ssize_t sono tipi di dati interi specificati da POSIX.1, rispettivamente senza segno e con segno.
Un ritorno con successo da write() non dà alcuna garanzia che i dati siano stati trasferiti sul disco. Su alcuni filesystem, compreso NFS, esso non garantisce che questo spazio sia stato riservato per i dati in modo corretto. In questo caso, alcuni errori potrebbero essere differiti fino a un futuro write(), fsync(2), o anche close(2). Il solo modo per essere sicuri è di chiamare fsync(2) dopo che si è eseguita la scrittura di tutti i propri dati.
Se una scrittura con write() viene interrotta da un handler di segnale prima che venga scritto qualunque byte, la chiamata fallisce con l'errore EINTR; se viene interrotta dopo aver scritto almeno un byte, la chiamata ha successo e restituisce il numero di byte scritti.
Su Linux, write() (e chiamate di sistema simili) trasferiranno al massimo 0x7ffff000 (2,147,479,552) byte, restituendo il numero di byte effettivamente trasferiti. (Questo è vero sia sui sistemi a 32 bit sia su quelli a 64 bit)
Un valore di errore restituito mentre si esegue una chiamata write() usando I/O diretto non significa che l'intera scrittura non abbia avuto successo. Possono venir scritti dati parziali e i dati all'offset del file sul quale è stata tentata la chiamata write() dovrebbe essere considerata incongruente.
Secondo POSIX.1-2008/SUSv4 Section XSI 2.9.7 ("Thread Interactions with Regular File Operations"):
Tra le API elencate susseguentemente ci sono write() e writev(2). E tra i risultati che dovrebbero essere atomici attraverso i thread (e i processi) ci sono gli aggiornamenti dell'offset dei file. Tuttavia, sulle versioni di Linux precedenti alla 3.14 non era così: se due processi che condividono una descrizione di file aperto (vedi open(2)) effettuano un write() (o writev(2)) allo stesso tempo, le operazioni I/O non erano atomiche rispetto all'offset del file, col risultato che i blocchi di dati in uscita dai due processi potrebbero (non correttamente) sovrapporsi. Questo problema è stato risolto in Linux 3.14.
close(2), fcntl(2), fsync(2), ioctl(2), lseek(2), open(2), pwrite(2), read(2), select(2), writev(2), fwrite(3)
Questa pagina fa parte del rilascio 5.10 del progetto Linux man-pages. Una descrizione del progetto, le istruzioni per la segnalazione degli errori, e l'ultima versione di questa pagina si trovano su https://www.kernel.org/doc/man-pages/.
La traduzione italiana di questa pagina di manuale è stata creata da Goffredo Baroncelli <kreijack@usa.net>, Giulio Daprelà <giulio@pluto.it>, Elisabetta Galli <lab@kkk.it> e Marco Curreli <marcocurreli@tiscali.it>
Questa traduzione è documentazione libera; leggere la GNU General Public License Versione 3 o successiva per le condizioni di copyright. Non ci assumiamo alcuna responsabilità.
Per segnalare errori nella traduzione di questa pagina di manuale inviare un messaggio a pluto-ildp@lists.pluto.it.
10 ottobre 2019 | Linux |