write(2)

BEZEICHNUNG
write - in einen Dateideskriptor schreiben

BIBLIOTHEK
Standard-C-Bibliothek (libc, -lc)

ÜBERSICHT
#include <unistd.h>

ssize_t write(size_t Anzahl;
              int dd, const void Puffer[Anzahl], size_t Anzahl);

BESCHREIBUNG
write() versucht Anzahl Byte aus dem Puffer, der bei Puffer beginnt, in die Datei zu schreiben, auf die der Dateideskriptor dd weist.

Die Anzahl der geschriebenen Bytes kann geringer als Anzahl sein, wenn es beispielsweise nicht genügend Platz auf dem zugrunde liegenden physischen Medium gibt oder die RLIMIT_FSIZE-Ressourcenbeschränkung erreicht wird (siehe setrlimit(2)) oder der Aufruf von einem Signal Handler nach weniger als Anzahl geschriebenen Bytes unterbrochen wurde. (Siehe auch pipe(7))

Für eine Datei, auf die lseek(2) angewendet werden kann, (z. B. eine normale Datei) erfolgt das Schreiben am Datei-Offset. Dabei wird der Datei-Offset um die Anzahl der tatsächlich geschriebenen Bytes erhöht. Wenn die Datei mit open(2) und der Option O_APPEND geöffnet wurde, wird der Datei-Offset vor dem ersten Schreiben auf das Dateiende gesetzt. Die Einstellung des Datei-Offsets und die Schreibaktion werden als eine unteilbare (atomare) Aktion durchgeführt.

POSIX fordert, dass ein nachweisbar nach der Rückkehr von write() liegendes read(2) die neuen Daten liefert. Es sollte jedoch beachtet werden, dass nicht alle Dateisysteme zu POSIX konform sind.

Laut POSIX.1 hängt das Ergebnis von der Implementierung ab, falls Anzahl größer als SSIZE_MAX ist; siehe ANMERKUNGEN für die Obergrenze unter Linux.

RÜCKGABEWERT
Bei Erfolg wird die Anzahl der geschriebenen Bytes zurückgegeben. Bei einem Fehler wird -1 zurückgegeben und errno gesetzt, um den Fehler anzuzeigen.

Beachten Sie, dass ein erfolgreicher write() weniger als Anzahl Bytes übertragen könnte. Solche Teilschreibaktionen können aus verschiedenen Gründen auftreten. Beispielsweise gab es unzureichend Platz auf der Platte, um die gesamten angeforderten Bytes zu schreiben oder blockiertes write() wurde beim Schreiben in ein Socket, eine Pipe oder ähnliches durch einen Signal-Handler unterbrochen, nachdem es einige, aber bevor es alle angeforderten Bytes übertragen hatte. Im Falle einer Teilschreibaktion kann der Aufrufende einen weiteren write()-Aufruf durchführen, um sämtliche verbliebene Bytes zu übertragen. Der nachfolgende Aufruf wird entweder weitere Bytes übertragen oder zu einem Fehler führen (z.B. falls die Platte jetzt voll ist).

Wenn Anzahl gleich Null ist und dd auf eine normale Datei verweist, kann write() einen Fehlerstatus zurückgeben, falls einer der nachfolgenden Fehler erkannt wird. Wenn keine Fehler festgestellt werden oder keine Fehlererkennung durchgeführt wird, wird 0 zurückgegeben, ohne dass Nebenwirkungen eintreten. Wenn Anzahl gleich Null ist und dd sich nicht auf eine normale Datei bezieht, sind die Ergebnisse nicht festgelegt.

FEHLER

EAGAIN
    Der Dateideskriptor dd verweist auf eine Datei, die kein Socket und als nicht blockierend (O_NONBLOCK) gekennzeichnet ist - die Schreibaktionen würde daher blockieren. Siehe open(2) für weitere Details über den Schalter O_NONBLOCK.

EAGAIN oder EWOULDBLOCK
    Der Dateideskriptor dd verweist auf einen Socket und wurde als nicht blockierend (O_NONBLOCK) gekennzeichnet - die Schreibaktion würde daher blockieren. POSIX.1-2001 lässt für diesen Fall beide Fehlerstati zu und fordert nicht, dass beide Konstanten den gleichen Wert haben. Eine portable Anwendung sollte daher beide Möglichkeiten prüfen.

EBADF
    dd ist kein gültiger Dateideskriptor oder ist nicht zum Schreiben geöffnet.

EDESTADDRREQ
    dd verweist auf einen Datagramm-Socket, für den nicht mit connect(2) eine Peer-Adresse gesetzt wurde.

EDQUOT
    Das Benutzerkontingent an Plattenblöcken auf dem die Datei enthaltenden Dateisystem, auf welches sich dd bezieht, ist ausgeschöpft.

EFAULT
    Puffer liegt außerhalb Ihres adressierbaren Adressraums.

EFBIG
    Es wurde versucht, in eine Datei zu schreiben, die die implementations- oder prozessspezifische maximale Dateigröße überschreitet oder der maximal zulässige Offset wurde überschritten.

EINTR
    Der Aufruf wurde durch ein Signal unterbrochen, bevor irgendwelche Daten geschrieben wurden (siehe signal(7)).

EINVAL
    dd wurde einem nicht beschreibbaren Objekt zugeordnet oder die Datei wurde mit dem Schalter O_DIRECT geöffnet und entweder die in Puffer angegebene Adresse, der in Anzahl angegebene Wert oder der Datei-Offset ist nicht geeignet ausgerichtet.

EIO Ein system-/hardwarenaher E/A-Fehler trat beim Verändern der Inode auf. Dieser Fehler kann sich auf das Zurückschreiben von Daten, die durch ein früheres write() geschrieben wurden, beziehen, welcher sich auf einen anderen Dateideskriptor auf der gleichen Datei bezog. Seit Linux 4.13 kommen Fehler beim Zurückschreiben mit dem Versprechen, dass sie von einer nachfolgenden write()-Anfrage berichtet werden können, und dass sie von einem nachfolgenden fsync(2) berichtet werden (unabhängig davon, ob sie von einem write() berichtet wurden). Eine andere mögliche Ursache von EIO bei Netzwerkdateisystemen sind empfohlene Sperren, die aus dem Dateideskriptor herausgenommen wurden, und diese Sperre dann verloren gegangen ist. Siehe den Abschnitt Verlorene Sperren von fcntl(2) für weitere Details.

ENOSPC
    Das Gerät, welches die Datei enthält, auf die sich dd bezieht, hat keinen Platz für die Daten.

EPERM
    Die Aktion wurde durch eine Dateiversiegelung verhindert; siehe fcntl(2).

EPIPE
    dd ist mit einer Pipe oder einem Socket verbunden, dessen lesendes Ende geschlossen ist. In diesem Fall empfängt der schreibende Prozess auch ein SIGPIPE-Signal. (Somit wird der Rückgabewert von write() nur sichtbar/wirksam/gesehen, wenn das Programm das Signal abfängt, blockiert oder ignoriert.)

Abhängig von dem mit dd verbundenen Objekt können andere Fehler auftreten.

STANDARDS
POSIX.1-2024.

GESCHICHTE
SVr4, 4.3BSD, POSIX.1-2001.

Unter SVr4 kann ein Schreiben jederzeit unterbrochen werden und EINTR zurückgeben, nicht nur vor dem Schreiben von Daten.

ANMERKUNGEN
Eine erfolgreiche Rückkehr aus write() garantiert nicht, dass Daten an die Festplatte übergeben wurden. Auf einigen Dateisystemen, darunter NFS, garantiert es nicht einmal, dass der Speicher für die Daten erfolgreich reserviert wurde. In diesem Fall können einige Fehler bis zu einem späteren write(2), fsync(2) oder sogar close(2) verzögert werden. Der einzig sichere Weg ist der Aufruf von fsync(2), nachdem Sie alle Ihre Daten geschrieben haben.

Wenn ein write() von einem Signal-Handler unterbrochen wird, bevor irgendwelche Bytes geschrieben wurden, wird der Auruf mit dem Fehler EINTR enden. Wird das write() unterbrochen, nachdem mindestens ein Byte geschrieben wurde, kehrt die Funktion erfolgreich zurück und der Rückgabewert ist die Anzahl der geschriebenen Bytes.

Unter Linux wird write() (und ähnliche Systemaufrufe) höchstens 0x7ffff000 (2.147.479.552) Byte übertragen und die Anzahl der tatsächlich übertragenen Bytes zurückliefern. Dies trifft sowohl auf 32- als auch auf 64-Bit-Systemen zu.

Wird bei der Durchführung eines write() während direkter E/A ein Fehler zurückgeliefert, bedeutet dies nicht, dass die gesamte Schreibaktion fehlschlug. Teildaten können geschrieben worden sein und die Daten am Datei-Offset, an dem der write() versucht wurde, sollte als inkonsistent betrachtet werden.

FEHLER
Laut POSIX.1-2008/SUSv4 Abschnitt XSI 2.9.7 (»Thread Interactions with Regular File Operations«):

    Alle der folgenden Funktionen müssen im Hinblick aufeinander atomar bezüglich der in POSIX.1-2008 angegebenen Effekte sein, wenn sie auf regulären Dateien oder symbolischen Links arbeiten: …

Unter den im Folgenden aufgeführten APIs sind write() und writev(2). Und unter den Effekten, die über Threads (und Prozesse) hinweg atomar sein sollten, ist die Aktualisierung des Dateiversatzes. Unter Linux vor Version 3.14 war das allerdings nicht der Fall: Falls zwei Prozesse, die eine offene Dateideskription gemeinsam nutzten (siehe open(2)) gleichzeitig einen write() (oder writev(2)) durchführten, waren die E/A-Aktionen im Hinblick auf die Aktualisierung des Dateiversatzes nicht atomar. Das Ergebnis war, dass die ausgegebenen Datenblöcken in den zwei Prozessen sich (inkorrekterweise) überlappten. Dieses Problem wurde in Linux 3.14 behoben.

SIEHE AUCH
close(2), fcntl(2), fsync(2), ioctl(2), lseek(2), open(2), pwrite(2), read(2), select(2), writev(2), fwrite(3)

ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Martin Eberhard Schauer <Martin.E.Schauer@gmx.de>, Mario Blättermann <mario.blaettermann@gmail.com> und Helge Kreutzmann <debian@helgefjell.de> erstellt.

Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 (https://www.gnu.org/licenses/gpl-3.0.html) oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Übersetzer (debian-l10n-german@lists.debian.org).