write(2) write(2)
NAME
write, writev - In eine Datei schreiben
SYNTAX
#include <unistd.h>
ssizet write(int fildes, const void *buf, sizet nbyte);
#include <sys/types.h>
#include <sys/uio.h>
int writev(int fildes, const struct iovec *iov, int iovcnt);
BESCHREIBUNG
write() versucht, nbyte Bytes vom Puffer, auf den buf zeigt, in die zu
fildes gehörende Datei zu schreiben. Wenn nbyte Null und die Datei
eine reguläre Datei ist, gibt write() Null zurück und hat keine ande-
ren Ergebnisse. fildes ist ein Dateideskriptor, der von einem
creat()-, open()-, dup()-, fcntl()- oder pipe()-Systemaufruf geliefert
wird.
writev() macht dasselbe wie write(), sammelt aber die Ausgabedaten der
iovcnt-Puffer, die durch die Mitglieder der iov-Felder (iov[0],
iov[1], ..., iov[iovcnt-1]) festgelegt sind. iovcnt ist gültig, wenn
es größer als 0 und kleiner oder gleich IOVMAX ist.
Für writev() enthält die Struktur iovec folgende Komponenten:
caddrt iovbase;
int iovlen;
Jeder iovec-Eintrag gibt die Basisadresse und die Länge eines Spei-
cherbereichs an, aus dem Daten geschrieben werden sollen. writev()
schreibt immer einen vollständigen Bereich, bevor es zum nächsten
übergeht.
Bei Geräten, die positionieren können, beginnt das tatsächliche
Schreiben der Daten an der Stelle in der Datei, auf die der Schreib-
/Lesezeiger zeigt. Nach Rückkehr von write() wird der Schreib-/Lese-
zeiger um die Anzahl der tatsächlich geschriebenen Bytes erhöht. Bei
einer regulären Datei wird die Länge der Datei auf den neuen Schreib-
/Lesezeiger gesetzt, wenn der erhöhte Schreib-/Lesezeiger größer als
die Dateilänge ist.
Bei Geräten, die nicht positionieren können, beginnt das Schreiben
immer an der aktuellen Position. Der Wert eines zu einem derartigen
Gerät gehörigen Schreib-/Lesezeigers ist undefiniert.
Ist das Flag OAPPEND des Dateistatus-Bytes gesetzt, dann wird der
Schreib-/Lesezeiger vor jedem write() auf das Ende der Datei gesetzt.
Die Datei wird zwischen dem Setzen des Schreib-/Lesezeigers und dem
Beginn von write() nicht modifiziert.
Seite 1 Reliant UNIX 5.44 Gedruckt 11/98
write(2) write(2)
Wenn das Flag OSYNC des Dateistatus-Bytes bei regulären Dateien
gesetzt ist, kehrt write() erst dann wieder zurück, wenn Dateidaten
und Dateistatus physisch aktualisiert worden sind. Diese Funktion ist
für besondere Anwendungen bestimmt, die eine zusätzliche Zuverlässig-
keit auf Kosten der Leistung erfordern. Wenn OSYNC bei blockorien-
tierten Dateien gesetzt wird, kehrt write() erst dann wieder zurück,
wenn die Daten physisch aktualisiert worden sind.
Ein write() in eine reguläre Datei wird blockiert, wenn das obligato-
rische Sperren von Dateien und Dateisätzen gesetzt ist [siehe
chmod(2)] und eine Datensatzsperre, die einem anderen Prozeß gehört,
auf das Segment der Datei gesetzt ist, in das geschrieben werden soll.
- Wenn ONDELAY oder ONONBLOCK gesetzt ist, gibt write() -1 zurück
und setzt errno auf EAGAIN.
- Wenn weder ONDELAY noch ONONBLOCK gesetzt ist, schläft write(),
bis alle blockierenden Sperren aufgehoben werden oder write() durch
ein Signal beendet wird.
Wenn ein write()-Aufruf verlangt, daß mehr Bytes geschrieben werden
als Speicher vorhanden ist - zum Beispiel, wenn das Schreiben die
Obergrenze für Dateigrößen des Prozesses [siehe getrlimit(2) und
ulimit(2)], die Obergrenze für Dateigrößen des Systems oder den freien
Speicherplatz auf dem Gerät überschreitet - werden nur so viele Bytes
geschrieben, wie Speicherplatz vorhanden ist. Nehmen wir zum Beispiel
an, daß in einer Datei noch Platz für 20 Bytes ist, bevor man an eine
Grenze stößt. Ein write() von 512 Bytes gibt dann 20 zurück. Das näch-
ste write() mit einer Byteanzahl ungleich Null gibt dann einen Fehler
zurück (außer bei Pipes und FIFO-Dateien), und die Implementierung
erzeugt ein Signal SIGXFSZ für den Prozeß.
Wenn nbyte größer ist als SSIZEMAX, ist das Ergebnis von der Imnple-
mentierung abhängig.
Nachdem write() erfolgreich ausgeführt wurde, werden bei jedem Aufruf
von read() von jeder Byteposition der modifizierten Datei die von
write() spezifizierten Daten zurückgegeben, bis diese Bytepositionen
erneut modifiziert werden. Jedes folgende write() auf die gleiche
Byteposition in einer Datei überschreibt diese Daten der Datei.
Schreibanfragen an eine Pipe oder an eine FIFO-Datei werden wie solche
an reguläre Dateien behandelt, dabei sind allerdings folgende Ausnah-
men zu beachten:
- Es gibt kein Datei-Offset bei Pipes, folglich wird jede Schreiban-
frage am Ende der Pipe angehängt. Es ist garantiert, daß es bei
Schreibanfragen von PIPEBUF oder weniger Bytes nicht zu einer
Überlappung mit Daten von anderen Prozessen kommt, die auf die
gleiche Pipe schreiben (atomare Schreiboperation). Bei Schreibauf-
trägen, die größer als PIPEBUF Bytes sind, kann es an willkürli-
chen Grenzen zu Überlappungen mit Schreibaufträgen anderer Prozesse
Seite 2 Reliant UNIX 5.44 Gedruckt 11/98
write(2) write(2)
kommen, egal, ob die ONONBLOCK- oder ONDELAY-Optionen gesetzt
sind oder nicht.
- Wenn ONONBLOCK und ONDELAY nicht gesetzt sind, kann ein Schreib-
auftrag den Prozeß blockieren, aber bei normaler Beendigung wird
nbyte zurückgegeben.
- Wenn ONONBLOCK gesetzt ist, werden write()-Anfragen folgendermaßen
behandelt: Schreibanfragen für PIPEBUF oder weniger Bytes werden
entweder vollständig ausgeführt und geben nbyte zurück, oder sie
geben -1 zurück und setzen errno auf EAGAIN. Eine write()-Anforde-
rung für mehr als PIPEBUF Bytes überträgt entweder soviel er kann
und gibt die Anzahl der geschriebenen Bytes zurück, oder er über-
trägt keine Daten, gibt -1 zurück und setzt errno auf EAGAIN. Auch
wenn eine Anforderung größer als PIPEBUF Bytes ist und alle vorher
in die Pipe geschriebenen Daten schon gelesen worden sind, über-
trägt write() mindestens PIPEBUF Bytes.
- Wenn ONDELAY gesetzt ist, werden write()-Anforderungen folgender-
maßen behandelt: write() blockiert nicht den Prozeß; Schreibanfor-
derungen für PIPEBUF oder weniger Bytes werden entweder vollstän-
dig ausgeführt und geben nbyte zurück, oder sie geben 0 zurück.
Eine write()-Anforderung für mehr als PIPEBUF Bytes überträgt ent-
weder alles, was sie kann, und gibt die Anzahl der geschriebenen
Bytes zurück, oder überträgt keine Daten und gibt 0 zurück. Wenn
eine Anforderung größer als PIPEBUF Bytes ist und alle vorher in
die Pipe geschriebenen Daten schon gelesen worden sind, überträgt
write() mindestens PIPEBUF Bytes.
Beim Versuch, auf einen Dateideskriptor zu schreiben (keine Pipe oder
FIFO-Datei), der nichtblockierendes Schreiben unterstützt und die
Daten nicht sofort annehmen kann, passiert folgendes:
- Wenn ONONBLOCK und ONDELAY nicht gesetzt sind, blockiert write(),
bis die Daten angenommen werden können.
- Wenn ONONBLOCK oder ONDELAY gesetzt ist, blockiert write() nicht
den Prozeß. Wenn einige Daten geschrieben werden können, ohne den
Prozeß zu blockieren, schreibt die write()-Anforderung soviel sie
kann und gibt dann die Anzahl der geschriebenen Bytes zurück.
Sonst, wenn ONONBLOCK gesetzt ist, wird -1 zurückgegeben und errno
auf EAGAIN gesetzt oder, wenn ONDELAY gesetzt ist, wird 0 zurück-
gegeben.
Bei STREAMS-Dateien wird die Wirkung von write() durch die Werte der
unteren und oberen Grenze für den Bereich von nbyte ("Paketgröße")
bestimmt, die vom Stream angenommen werden. Diese Werte sind im ober-
sten Stream-Modul enthalten. Solange der Benutzer dieses oberste Modul
nicht auf den Stream setzt [siehe IPUSH in streamio(7)], können diese
Werte auf Benutzerebene nicht gesetzt oder getestet werden. Wenn nbyte
im zulässigen Größenbereich liegt, werden nbyte Bytes geschrieben.
Seite 3 Reliant UNIX 5.44 Gedruckt 11/98
write(2) write(2)
Wenn nbyte nicht in diesem Bereich liegt und der Wert der Mindestpa-
ketgröße Null ist, zerlegt write() den Puffer in Segmente maximaler
Paketgröße, bevor die Daten stream-abwärts geschickt werden (das
letzte Segment kann kleiner als die maximale Paketgröße sein). Wenn
nbyte nicht im Bereich liegt und der Mindestwert ungleich Null ist,
ist write() erfolglos und setzt errno auf ERANGE. Das Schreiben eines
Puffers der Länge Null (nbyte ist Null) auf ein STREAMS-Gerät bewirkt,
daß eine Meldung der Länge Null gesendet und Null zurückgegeben wird.
Wenn jedoch ein Puffer der Länge Null in eine Pipe oder FIFO-Datei
geschrieben wird, wird keine Meldung gesendet und Null zurückgegeben.
Das Benutzerprogramm kann ISWROPT im ioctl-Aufruf verwenden, um zu
ermöglichen, daß leere Meldungen über eine Pipe oder eine FIFO-Datei
gesendet werden [siehe streamio(7)].
Beim Schreiben auf einen Stream werden Meldungen mit dem Prioritätsbe-
reich Null erzeugt. Beim Schreiben auf einen Stream, der keine Pipe
oder FIFO-Datei ist, geschieht folgendes:
- Wenn ONDELAY und ONONBLOCK nicht gesetzt sind und der Stream
keine Daten annehmen kann (die Stream-Schreibschlange ist aufgrund
von internen Bedingungen zur Datenflußsteuerung voll), blockiert
write(), bis Daten angenommen werden können.
- Wenn ONDELAY oder ONONBLOCK gesetzt ist und der Stream keine
Daten annehmen kann, gibt write() -1 zurück und setzt errno auf
EAGAIN.
- Wenn ONDELAY oder ONONBLOCK gesetzt und ein Teil des Puffers
schon geschrieben worden ist und dann eine Bedingung auftritt, in
der der Stream keine zusätzlichen Daten annehmen kann, wird write()
beendet und gibt die Anzahl der geschriebenen Bytes zurück.
Bei regulären Dateien erfolgt kein Datentransfer über das Offset-Maxi-
mum hinaus, das in der fildes zugeordneten internen Beschreibung der
offenen Datei festgelegt ist.
FEHLER
Die folgenden Beschreibungen der Fehlercodes sind funktionsspezifisch.
Eine allgemeingültige Beschreibung finden Sie in introprm2(2) bzw. in
errno(5).
write() und writev() sind erfolglos, und der Schreib-/Lesezeiger
bleibt unverändert, wenn eine oder mehrere der folgenden Bedingungen
zutreffen:
EAGAIN Obligatorisches Sperren von Dateien und Dateisätzen ist
gesetzt, ONDELAY oder ONONBLOCK ist gesetzt, und eine
blockierende Datensatzsperre ist vorhanden.
EAGAIN Der Systemspeicher, der für "raw"-Ein-/Ausgabe zur Verfü-
gung steht, ist vorübergehend nicht ausreichend.
Seite 4 Reliant UNIX 5.44 Gedruckt 11/98
write(2) write(2)
EAGAIN Es wurde versucht, in einen Stream zu schreiben, der bei
gesetztem Anzeiger ONDELAY oder ONONBLOCK keine Daten
akzeptieren kann.
EAGAIN Es wurde versucht, eine write-Anforderung von PIPEBUF
Bytes oder weniger auf eine Pipe oder FIFO-Datei zu geben,
und es waren weniger als nbytes freier Speicherbereich
vorhanden.
EBADF fildes ist kein gültiger Dateideskriptor für eine zum
Schreiben geöffnete Datei.
EDEADLK Die Funktion write() schläft, und löst dadurch einen Dead-
lock aus.
EFAULT buf weist über den zugewiesenen Adreßraum des Prozesses
hinaus.
EFBIG Es wurde versucht, eine Datei zu schreiben, die über die
zulässige Grenze für den Prozeß oder die maximale Datei-
größe des Prozesses hinausgeht [siehe getrlimit(2) und
ulimit(2)].
Die Datei ist eine reguläre Datei, nbyte ist größer als 0
und die Anfangsposition ist größer oder gleich dem Off-
set-Maximum, das in der fildes zugeordneten internen
Beschreibung der offenen Datei festgelegt ist.
EINTR Die Schreiboperation wurde aufgrund eines Signals beendet,
und keine Daten wurden übertragen.
EINVAL Der STREAM oder Multiplexer, auf den fildes verweist, ist
(direkt oder indirekt) stream-abwärts von einem Multiple-
xer verbunden.
EIO Ein physischer E/A-Fehler ist aufgetreten.
EIO Der Prozeß ist im Hintergrund und versucht, auf sein steu-
erndes Terminal zu schreiben, dessen TOSTOP-Option gesetzt
ist; der Prozeß ignoriert weder SIGTTOU-Signale, noch
blockiert er sie, und seine Prozeßgruppe ist verwaist.
ENOLCK Die Tabelle der Systemdatensatzsperren war voll, und daher
kann die write()-Funktion erst schlafen, wenn die blockie-
rende Datensatzsperre aufgehoben wird.
ENOLINK fildes ist auf einem fernen Rechner, und die Verbindung zu
diesem Rechner ist nicht mehr aktiv.
ENOSR Es wurde versucht, auf einen Stream mit ungenügend
STREAMS-Speicherplatz im System zu schreiben.
Seite 5 Reliant UNIX 5.44 Gedruckt 11/98
write(2) write(2)
ENOSPC Während eines write() in eine reguläre Datei ist kein
freier Speicher mehr auf dem Rechner.
ENXIO Anforderung eines nicht existierenden Geräts beziehungs-
weise Anforderung jenseits der Leistungsgrenzen des
Geräts.
ENXIO Ein Hangup ist aufgetreten, während auf den Stream
geschrieben wird.
EPIPE Es wurde versucht, in eine Pipeline oder FIFO-Datei zu
schreiben, die nicht zum Lesen oder nur an einem Ende
geöffnet ist. Ein SIGPIPE-Signal wird an den Prozeß gesen-
det.
ERANGE Es wurde versucht, in einen Stream mit nbyte außerhalb der
vorgegebenen Mindest- und Höchstgrenzen zu schreiben, und
der Mindestwert ist ungleich Null.
ENOLCK Erzwungenes Satzsperren war erlaubt, und keine weiteren
Dateisatzsperren stehen zur Verfügung (zuviele Dateiseg-
mente gesperrt), weil das Maximum des Systems überschrit-
ten wurde.
Zusätzlich kann writev() den folgenden Fehler zurückgeben:
EINVAL iovcnt war kleiner oder gleich 0 oder größer gleich 16,
oder einer der iovlen-Werte im iov-Feld war negativ, oder
die Summe der iovlen-Werte im iov-Feld erzeugt einen
Überlauf bei einer 32-Bit-Ganzzahl.
Ein write() in eine STREAMS-Datei kann erfolglos sein, wenn am
Stream-Kopf eine Fehlermeldung erhalten wurde. In diesem Fall wird
errno auf den Wert gesetzt, der in der Fehlermeldung enthalten ist.
Bei erfolgreicher Ausführung kennzeichnen write() und writev() die
Felder stctime und stmtime der Datei zur Aktualisierung.
ERGEBNIS
Bei erfolgreicher Ausführung gibt write() die Anzahl der Bytes zurück,
die tatsächlich in die Datei, auf die fildes verweist, geschrieben
wurden. Diese Anzahl kann niemals größer als nbyte sein. Andernfalls
wird -1 zurückgegeben und errno zur Anzeige des Fehlers gesetzt.
Bei erfolgreicher Ausführung gibt writev() die Anzahl der tatsächlich
geschriebenen Bytes zurück. Andernfalls wird -1 zurückgegeben, der
Dateizeiger bleibt unverändert, und errno wird zur Anzeige des Fehlers
gesetzt.
Seite 6 Reliant UNIX 5.44 Gedruckt 11/98
write(2) write(2)
HINWEISE
write() and writev() führen aufgrund des Offset-Maximums möglicher-
weise ein "partielles Lesen oder Schreiben" aus. Dies bedeutet, daß
der zurückgegebene Wert möglicherweise unter nbyte liegt, wenn die
Anzahl der verbleibenden Bytes, die übertragen werden kann, unter
nbyte liegt.
SIEHE AUCH
chmod(2), creat(2), dup(2), fcntl(2), getrlimit(2), lseek(2), open(2),
pipe(2), ulimit(2), limits(4), unistd(4), lfs(5), stropts(5),
types(5), uio(5).
Seite 7 Reliant UNIX 5.44 Gedruckt 11/98