Beschreibung | write() versucht, nbyte Bytes aus dem Puffer, auf den buf zeigt, in die dem Dateideskriptor fildes zugeordnete Datei zu schreiben.
BS2000 SAM-Dateien werden mit elementaren Funktionen stets als Textdateien verarbeitet. (Ende) In einer Datei, in der positioniert werden kann, beginnt die Schreiboperation an der Stelle in der Datei, die durch den mit fildes verbundenen Lese-/Schreibzeiger bestimmt ist. Vor einer erfolgreichen Rückkehr von write() wird der Zeiger um die Anzahl von Bytes erhöht, die tatsächlich geschrieben wurden. Wenn in einer normalen Datei der erhöhte Zeiger über das Dateiende hinauszeigt, wird die Dateilänge mit der Zeigerposition gleichgesetzt. Wenn als Dateistatus-Flag O_SYNC gesetzt ist und fildes auf eine normale Datei zeigt, kehrt ein erfolgreicher write -Aufruf erst dann zurück, wenn die Daten physikalisch aktualisiert wurden. In einer Datei, in der nicht positioniert werden kann, findet das Schreiben immer an der aktuellen Position statt. Der Wert des Lese-/Schreibzeigers, der einem solchen Gerät zugeordnet ist, ist undefiniert. Wenn als Dateistatus-Flag O_APPEND gesetzt ist, wird der Lese-/Schreibzeiger vor jeder Schreiboperation auf das Dateiende gesetzt. Die Datei wird zwischen dem Setzen des Lese-/Schreibzeigers und dem Beginn der write() -Operation nicht verändert. Wenn write() mehr Bytes schreiben will, als Platz zur Verfügung steht (z.B. wegen uulimit() oder dem physikalischen Ende eines Mediums), werden nur so viel Bytes geschrieben, wie noch Platz haben. Angenommen, in einer Datei ist noch Platz für 20 Bytes vorhanden, bevor eine Grenze erreicht wird. Eine Schreiboperation von 512 Bytes liefert dann den Returnwert 20. Die nächste Schreiboperation mit einer Byteanzahl ungleich 0 würde dann ein Fehlerergebnis liefern (außer in den unten beschriebenen Fällen) und dem Prozess ein SIGXFSZ-Signal schicken. Wenn write() von einem Signal unterbrochen wird, bevor es Daten geschrieben hat, wird -1 zurückgegeben und errno auf EINTR gesetzt. Wenn write() von einem Signal unterbrochen wird, nachdem es Daten erfolgreich geschrieben hat, wird die Anzahl der geschriebenen Bytes zurückgegeben. Wenn write() erfolgreich in eine normale Datei geschrieben hat, gilt Folgendes: Jeder erfolgreiche read -Aufruf von jeder Byteposition in der durch eine Schreiboperation veränderten Datei liefert die von write() für diese Position spezifizierten Daten zurück, bis diese Bytepositionen erneut geändert werden. Jeder folgende write -Aufruf für dieselbe Byteposition in der Datei überschreibt diese Daten.
Eine Schreibanforderung für eine Pipe oder FIFO wird genauso behandelt wie solche für eine normale Datei, mit folgenden Ausnahmen: Es gibt keine Dateiposition, die einer Pipe zugeordnet ist, da jede Schreibanforderung an das Ende der Datei angefügt wird. Schreibanforderungen von {PIPE_BUF} oder weniger Bytes werden nicht mit Daten anderer Prozesse gemischt, die auf dieselbe Datei schreiben. Eine Schreiboperation von mehr als {PIPE_BUF} Bytes kann, in bestimmten Grenzen, mit Schreiboperationen anderer Prozesse gemischt werden, gleichgültig, ob das Flag O_NONBLOCK im System-Dateistatus-Byte gesetzt ist oder nicht. Wenn das Flag O_NONBLOCK nicht gesetzt ist, kann eine Schreibanforderung den Prozess blockieren, aber eine normale Beendigung liefert das Ergebnis nbyte. Wenn das Flag O_NONBLOCK gesetzt ist, wird die Anforderung von write() verschieden behandelt, wie folgt: write() blockiert den Prozess nicht.
Eine Schreibanforderung für {PIPE_BUF} oder weniger Bytes hat eine der folgenden Auswirkungen: Wenn in der Pipe genügend Platz zur Verfügung steht, überträgt write() alle Daten und gibt die Anzahl der angeforderten Bytes zurück. Wenn in der Pipe nicht genügend Platz zur Verfügung steht, überträgt write() keine Daten, liefert den Wert -1 zurück und setzt errno gleich EAGAIN .
Eine Schreibanforderung mit mehr als {PIPE_BUF} Bytes hat eine der folgenden Auswirkungen: Wenn mindestens 1 Byte geschrieben werden kann, überträgt write() so viel Daten wie möglich und gibt die Anzahl der geschriebenen Bytes zurück. Wenn alle vorher in eine Pipe geschriebenen Daten gelesen wurden, werden zumindest {PIPE_BUF} Bytes übertragen. Wenn keine Daten geschrieben werden können, überträgt write() keine Daten, liefert den Wert -1 und setzt errno gleich EAGAIN .
Wenn eine Anforderung größer als {PIPE_BUF} Bytes ist und alle Daten, die vorher in diese Datei geschrieben wurden, bereits gelesen sind, überträgt write() mindestens {PIPE_BUF} Bytes. Wenn versucht wird, auf einen Dateideskriptor zu schreiben, der keine Pipe oder FIFO ist und nichtblockierendes Schreiben unterstützt, geschieht Folgendes: Wenn das Flag O_NONBLOCK nicht gesetzt ist, blockiert write() solange, bis die Daten akzeptiert werden können. Wenn das Flag O_NONBLOCK gesetzt ist, blockiert write() den Prozess nicht. Wenn einige Daten ohne ein Blockieren des Prozesses geschrieben werden können, schreibt write() so viel wie möglich und liefert die Anzahl der übertragenen Bytes. Andernfalls liefert die Funktion den Wert -1 und errno wird gleich EAGAIN gesetzt.
Bei erfolgreicher Beendigung, wobei nbyte größer als 0 ist, markiert write() die Strukturkomponenten st_ctime und st_mtime der Datei zur Änderung; die Dateistatus-Flags S_ISUID und S_ISGID werden gelöscht, wenn der Prozess keine Sonderrechte besitzt. Wenn fildes einen STREAM bezeichnet, wird die Schreiboperation durch die minimalen und maximalen Werte für nbyte bestimmt („Paketgröße“), die vom STREAM akzeptiert werden. Diese Werte werden vom obersten STREAM-Modul festgelegt. Wenn nbyte in der zugelassenen Paketgröße liegt, werden nbyte Bytes geschrieben. Wenn nbyte nicht im Bereich der Paketgröße liegt, und die kleinste Paketgröße gleich 0 ist, spaltet write() den Puffer in Segmente mit maximaler Paketgröße auf, bevor die Daten stromabwärts gesendet werden (das letzte Segment kann kleiner sein). Wenn nbyte nicht im Bereich der Paketgröße liegt, und die kleinste Paketgröße ungleich 0 ist, schlägt write() fehl und setzt errno auf ERANGE . Wird ein Puffer mit Länge 0 (nbyte = 0) auf einen STREAM geschrieben, sendet write() eine Nachricht der Länge 0 und gibt den Wert 0 zurück. Wird jedoch ein Puffer mit Länge 0 auf eine STREAM-basierte Pipe oder eine FIFO-Datei geschrieben, wird nichts gesendet und 0 zurückgegeben. Der Prozess kann I_SWROPT ioctl() verwenden, wenn Nachrichten mit Länge 0 über die Pipe oder FIFO-Datei gesendet werden sollen. Wenn write() auf einen STREAM schreibt, werden Nachrichten der Prioritätsklasse 0 erzeugt. Es gelten die folgenden Regeln, wenn write() auf einen STREAM schreibt, der weder eine Pipe noch eine FIFO-Datei ist: Wenn das Flag O_NONBLOCK nicht gesetzt ist, und der STREAM keine Daten akzeptiert (weil die STREAM-Schreibschlange wegen interner Kontrollflussbedingungen voll ist) blockiert write() solange, bis die Daten akzeptiert werden können. Wenn das Flag O_NONBLOCK gesetzt ist, und der STREAM keine Daten akzeptiert, schlägt write() fehl, gibt -1 zurück und setzt errno auf EAGAIN . Wenn das Flag O_NONBLOCK gesetzt ist, und write() bereits einen Teil des Puffers geschrieben hat, wenn eine Bedingung auftritt, unter der der STREAM keine Daten mehr akzeptiert, beendet sich write() und gibt die Anzahl der tatsächlich geschriebenen Bytes zurück.
Werden Threads verwendet, so wirkt sich die Funktion auf den Prozess oder auf einen Thread wie folgt aus: Bytes in Datei schreiben Eine Schreibanforderung für eine Pipe oder FIFO wird genauso behandelt wie solche für eine normale Datei, mit folgenden Ausnahmen: Wenn das Flag O_NONBLOCK nicht gesetzt ist, kann eine Schreibanforderung den Thread blockieren, aber eine normale Beendigung liefert das Ergebnis nbyte. Wenn das Flag O_NONBLOCK gesetzt ist, wird die Anforderung von write() verschieden behandelt, wie folgt: write() blockiert den Thread nicht.
Wenn versucht wird, auf einen Dateideskriptor zu schreiben, der keine Pipe oder FIFO ist und nichtblockierendes Schreiben unterstützt, geschieht Folgendes: - Wenn das Flag
O_NONBLOCK nicht gesetzt ist, blockiert write() den aufrufenden Thread solange, bis die Daten akzeptiert werden können. EAGAIN - das Flag O_NONBLOCK ist für den Dateideskriptor gesetzt und der Thread würde durch die Schreiboperation angehalten werden.
Ferner wird beim EPIPE -Fehler das Signal SIGPIPE nicht an den Prozess, sondern an den aufrufenden Thread gesendet.
|
Hinweise | Um sicherzugehen, dass Ihre Angabe in nbyte die Größe des Puffers nicht überschreitet, sollten Sie die Funktion sizeof() verwenden. BS2000 Nach jedem write -Aufruf sollte die tatsächlich geschriebene Byteanzahl überprüft werden: Wenn das Ergebnis kleiner als die Angabe in nbyte ist, liegt im Allgemeinen ein Fehler vor. Wenn das Ergebnis größer als die Angabe in nbyte ist, wurden Tabulatorzeichen (\t ) in eine Textdatei geschrieben. Tabulatorzeichen werden dabei in die entsprechenden Leerzeichen umgesetzt und bei der Ergebnisanzahl berücksichtigt.
Die Daten werden nicht sofort in die externe Datei geschrieben, sondern in einem C-internen Puffer zwischengespeichert (siehe Abschnitt "Pufferung von Datenströmen“). Bei der Ausgabe in Textdateien werden die Steuerzeichen für Zwischenraum (\n , \t , etc.) je nach Art der Textdatei in ihre entsprechende Wirkung umgesetzt (siehe Abschnitt "Zwischenraumzeichen“). Bei Textdateien mit der Zugriffsart SAM und variabler Satzlänge, für die zusätzlich eine maximale Satzlänge angegeben ist, gilt: Wenn bei open() die Angabe O_NOSPLIT gemacht wurde, werden Sätze, die länger als die maximale Satzlänge sind, beim Schreiben auf die maximale Satzlänge gekürzt. Standardmäßig (also ohne die Angabe O_NOSPLIT) werden diese Sätze in mehrere Sätze aufgeteilt. Hat ein Satz genau die maximale Satzlänge, wird nach diesem ein Satz der Länge Null geschrieben. (Ende) |