rename, renameat, renameat2 - den Namen oder die Lage einer Datei
ändern
Standard-C-Bibliothek (libc, -lc)
ÜBERSICHT
#include <stdio.h>
int rename(const char *alterpfad, const char *neuerpfad);
#include <fcntl.h> /* Definition der AT_*-Konstanten */
#include <stdio.h>
int renameat(int altVerzdd, const char *alterpfad,
int neuVerzdd, const char *neuerpfad);
int renameat2(int altVerzdd, const char *alterpfad,
int neuVerzdd, const char *neuerpfad, unsigned int Schalter);
renameat():
Seit Glibc 2.10:
_POSIX_C_SOURCE >= 200809L
Vor Glibc 2.10:
_ATFILE_SOURCE
renameat2():
_GNU_SOURCE
rename() benennt eine Datei um und verschiebt sie in ein
anderes Verzeichnis, wenn nötig. Alle anderen Hardlinks (erstellt
mittels link(2)) sind nicht betroffen, ebenso offene
Dateideskriptoren für alterpfad.
Verschiedene Einschränkungen bestimmen, ob die
Umbenennungsaktion erfolgreich ist oder nicht; siehe FEHLER unten.
Falls neuerpfad schon existiert, wird er in einem atomaren
Schritt überschrieben, so dass ein anderer Prozess jederzeit auf
neuerpfad zugreifen kann. Allerdings wird es wahrscheinlich ein
Fenster geben, in dem sowohl alterpfad als auch neuerpfad sich
auf die umzubenennende Datei beziehen.
Falls alterpfad und neuerpfad bestehende Hardlinks
zu derselben Datei sind, tut rename() nichts und meldet eine
erfolgreiche Ausführung.
Wenn neuerpfad schon existiert, aber das Umbenennen aus
irgendeinem Grund fehlschlägt, garantiert rename(), dass
neuerpfad an Ort und Stelle erhalten bleibt.
alterpfad kann ein Verzeichnis angeben. In diesem Fall darf
neuerpfad nicht existieren oder muss ein leeres Verzeichnis
angeben.
Falls alterpfad auf einen symbolischen Link zeigt, wird der
Link umbenannt; falls neuerpfad auf einen symbolischen Link zeigt,
wird der Link überschrieben.
Der Systemaufruf renameat() funktioniert genauso wie
rename(), außer den hier beschriebenen Unterschieden.
Falls der in alterpfad übergebene Pfadname relativ
ist wird er als relativ zu dem im Dateideskriptor altVerzdd
referenzierten Verzeichnis interpretiert (statt relativ zum aktuellen
Arbeitsverzeichnis des aufrufenden Prozesses, wie es bei rename()
für einen relativen Pfadnamen erfolgt).
Falls alterpfad relativ ist und altVerzdd den
besonderen Wert AT_FDCWD annimmt wird alterpfad als relativ
zum aktuellen Arbeitsverzeichnis des aufrufenden Prozesses interpretiert
(wie rename()).
Falls alterpfad absolut ist wird altVerzdd
ignoriert.
Die Interpretation von neuerpfad ist wie bei
alterpfad, außer dass ein relativer Pfadname als relativ zu
dem Verzeichnis interpretiert wird, auf das der Dateideskriptor
neuVerzdd verweist.
Lesen Sie openat(2) für eine Beschreibung der
Notwendigkeit von renameat().
renameat2() hat ein zusätzliches Argument
Schalter. Ein Aufruf von renameat2() mit einem leeren Argument
Schalter ist äquivalent zu renameat().
Das Argument Schalter ist eine Bitmaske, die aus null oder
mehr der folgenden Schalter besteht:
- RENAME_EXCHANGE
- tauscht alterpfad und neuerpfad atomisch aus. Beide
Pfadnamen müssen existieren, können aber verschiedenen Typs
sein. Beispielsweise kann ein Pfad ein nicht-leeres Verzeichnis und der
andere ein symbolischer Link sein.
- RENAME_NOREPLACE
- überschreibt neuerpfad beim Umbenennen nicht. Ein Fehler
wird zurückgegeben, wenn neuerpfad bereits existiert.
- RENAME_NOREPLACE kann nicht zusammen mit RENAME_EXCHANGE
eingesetzt werden.
- RENAME_NOREPLACE benötigt Unterstützung vom
zugrundeliegenden Dateisystem. Die Unterstützung für
verschiedene Dateisysteme wurde wie folgt hinzugefügt:
- •
- Ext4 (Linux 3.15);
- •
- Btrfs, Tmpfs und Cifs (Linux 3.17);
- •
- XFS (Linux 4.0);
- •
- Die Unterstützung für viele andere Dateisysteme wurde in
Linux 4.9 hinzugefügt, einschließlich Ext2, Minix, Reiserfs,
Jfs, Vfat und Bpf.
- RENAME_WHITEOUT
(seit Linux 3.18)
- Diese Aktion ergibt nur für Implementierungen von
Overlay/Union-Dateisystemen Sinn.
- Durch Angabe von RENAME_WHITEOUT wird ein
»whiteout«-Objekt bei der Quelle der Umbenennung zum
gleichen Zeitpunkt der Durchführung der Umbenennung erzeugt. Die
gesamte Aktion ist atomar, so dass der Whiteout erstellt sein wird, wenn
die Umbenennung erfolgreich war.
- Ein »Whiteout« ist ein Objekt, das in
Union/Overlay-Dateisystemkonstrukten eine besondere Bedeutung hat. In
diesen Konstrukten existieren mehrere Ebenen, wobei jedoch nur die oberste
Ebene jemals verändert wird. Ein »Whiteout« in einer
der oberen Ebenen versteckt eine entsprechende Datei in der unteren Ebene,
wodurch es so aussieht, als würde die Datei nicht existieren.
- Wenn eine Datei auf einer unteren Ebene umbenannt wird, wird die Datei
zuerst hochkopiert (falls sie nicht bereits auf der oberen Ebene ist) und
dann auf der oberen, lese-schreibbaren Ebene umbenannt. Gleichzeitig muss
die Quelldatei »whiteouted« werden (so dass die Version der
Quelldatei in der unteren Ebene unsichtbar gemacht wird). Die gesamte
Aktion muss atomar sein.
- Wenn es nicht Teil eines Union/Overlay-Dateisystems ist, dann erscheint
ein »Whiteout« als zeichenorientiertes Gerät mit
einer Gerätenummer {0,0}. Beachten Sie, dass andere
Union/Overlay-Implementierungen anders mit der Speicherung von
»Whiteout«-Einträgen umgehen könnten.
Insbesondere verwendet »Union mount« auf BSD-Systemen einen
separaten Inode-Typ DT_WHT. Dieser wird – zumindest in Linux
4.19 – vom »Whiteout«-Support-Code des Kernels
ignoriert, obwohl er von einigen unter Linux verfügbaren
Dateisystemen, wie CODA und XFS, dennoch unterstützt wird
- RENAME_WHITEOUT benötigt die gleichen Privilegien wie zum
Erstellen eines Geräteknotens (d.h. die Capability
CAP_MKNOD).
- RENAME_WHITEOUT kann nicht zusammen mit RENAME_EXCHANGE
eingesetzt werden.
- RENAME_WHITEOUT benötigt die Unterstützung vom
darunterliegenden Dateisystem. Unter den Dateisystemen, die die
Unterstützung anbieten, sind Tmpfs (seit Linux 3.18), Ext4 (seit
Linux 3.18), XFS (seit Linux 4.1), F2fs (seit Linux 4.2), Btrfs (seit
Linux 4.7) und Ubifs (seit Linux 4.9).
Bei Erfolg wird Null zurückgegeben. Bei einem Fehler wird
-1 zurückgegeben und errno gesetzt, um den Fehler
anzuzeigen.
- EACCES
- Für das Verzeichnis, das alterpfad oder neuerpfad
enthält, wurden Schreibrechte verweigert oder für eines der
Verzeichnisse im Pfad-Präfix von alterpfad oder
neuerpfad wurde nicht gestattet, dort zu suchen oder
alterpfad ist ein Verzeichnis und verwehrt die Schreiberlaubnis
(benötigt, um den Eintrag .. zu aktualisieren). (Siehe auch
path_resolution(7).)
- EBUSY
- Das Umbenennen scheitert, weil alterpfad oder neuerpfad ein
Verzeichnis ist, das von einem anderen Prozess (vielleicht als aktuelles
Arbeitsverzeichnis oder als Wurzelverzeichnis oder weil es zum Lesen
geöffnet ist) oder vom System genutzt wird (zum Beispiel als
Einhängepunkt) und das System dies als Fehler betrachtet. (Beachten
Sie, dass es keine Verpflichtung gibt, in solchen Fällen
EBUSY zurückzugeben – es ist nichts falsch daran, die
Umbenennung trotzdem durchzuführen – aber es ist erlaubt,
EBUSY zurückzugeben, wenn das System solche Situationen
nicht anderweitig verarbeiten kann.)
- EDQUOT
- Das Plattenkontingent (Quota) des Benutzers an Plattenblöcken auf
dem Dateisystem ist erschöpft.
- EFAULT
- alterpfad oder neuerpfad zeigt aus dem für Sie
zugänglichen Adressraum heraus.
- EINVAL
- Der neue Pfadname enthielt ein Pfad-Präfix des alten, oder
allgemeiner, es wurde versucht, ein Verzeichnis als Unterverzeichnis von
sich selbst zu erzeugen.
- EISDIR
- neuerpfad ist ein existierendes Verzeichnis, aber alterpfad
ist kein Verzeichnis.
- ELOOP
- Bei der Auflösung von alterpfad oder neuerpfad wurden
zu viele symbolische Links gefunden.
- EMLINK
- alterpfad hat schon die maximale Anzahl Links, oder es war ein
Verzeichnis und das Verzeichnis, welches neuerpfad enthält,
hat schon die maximale Anzahl Links.
- ENAMETOOLONG
- alterpfad oder neuerpfad war zu lang.
- ENOENT
- Der von alterpfad angegebene Link existiert nicht oder eine
Verzeichniskomponente von neuerpfad existiert nicht oder
alterpfad oder neuerpfad ist eine leere Zeichenkette.
- ENOMEM
- Es war nicht genügend Kernelspeicher verfügbar.
- ENOSPC
- Das Gerät, das die die Datei enthält, hat keinen Platz
für einen neuen Verzeichniseintrag.
- ENOTDIR
- Eine als Verzeichnis benutzte Komponente von alterpfad oder
neuerpfad ist in der Tat kein Verzeichnis. Oder alterpfad
ist ein Verzeichnis und neuerpfad existiert, ist aber kein
Verzeichnis.
- ENOTEMPTY
oder EEXIST
- neuerpfad ist ein nicht leeres Verzeichnis, d.h. es enthält
außer ».« und »..« weitere
Einträge.
- EPERM oder
EACCES
- Das Verzeichnis, das alterpfad enthält, hat das Sticky-Bit
(S_ISVTX) gesetzt und die effektive Benutzerkennung des Prozesses
ist weder die Benutzerkennung der zu löschenden Datei noch die des
beinhaltenden Verzeichnisses und der Prozess ist nicht privilegiert
(Linux: verfügt nicht über die
CAP_FOWNER-Capability); oder neuerpfad ist eine vorhandene
Datei und ihr übergeordnetes Verzeichnis hat das Sticky-Bit gesetzt
und die effektive Benutzerkennung des Prozesses ist weder die
Benutzerkennung der zu ersetzenden Datei noch des beherbergenden
Verzeichnisses und der Prozess ist nicht privilegiert (Linux:
verfügt nicht über die CAP_FOWNER-Capability) oder
das alterpfad beherbergende Dateisystem unterstützt nicht
die Umbenennung des angeforderten Typs.
- EROFS
- Die Datei befindet sich auf einem nur lesbaren Dateisystem.
- EXDEV
- alterpfad und neuerpfad befinden sich nicht auf demselben
eingehängten Dateisystem. (Linux erlaubt es Dateisystemen, an
mehreren Stellen eingehängt zu sein, aber rename()
funktioniert nicht über verschiedene Einhängepunkte hinweg,
selbst falls dasselbe Dateisystem an beiden Stellen eingehängt
ist.)
Die folgenden zusätzlichen Fehler können bei
renameat() und renameat2() auftreten:
- EBADF
- alterpfad (neuerpfad) ist relativ, aber altVerzdd
(neuVerzdd) ist kein zulässiger Dateideskriptor.
- ENOTDIR
- alterpfad ist relativ und altVerzdd ist ein Dateideskriptor,
der sich auf eine Datei bezieht, die kein Verzeichnis ist; gilt analog
für neuerpfad und neuVerzdd.
Die folgenden zusätzlichen Fehler können bei
renameat2() auftreten:
- EEXIST
- Schalter enthält RENAME_NOREPLACE und
neuerpfad existiert bereits.
- EINVAL
- In Schalter wurde ein ungültiger Schalter angegeben.
- EINVAL
- Sowohl RENAME_NOREPLACE als auch RENAME_EXCHANGE wurden in
Schalter angegeben.
- EINVAL
- Sowohl RENAME_WHITEOUT als auch RENAME_EXCHANGE wurden in
Schalter angegeben.
- EINVAL
- Das Dateisystem unterstützt einen der Schalter in Schalter
nicht.
- ENOENT
- Schalter enthält RENAME_EXCHANGE und neuerpfad
existiert nicht.
- EPERM
- RENAME_WHITEOUT wurde in Schalter angegeben, aber der
Aufrufende verfügte nicht über die Capability
CAP_MKNOD.
renameat2() wurde zu Linux in Version 3.15
hinzugefügt; Bibliotheksunterstützung wurde zu Glibc 2.28
hinzugefügt.
renameat2() wurde zu Linux in Version 3.15
hinzugefügt; Bibliotheksunterstützung wurde zu Glibc 2.28
hinzugefügt.
rename(): 4.3BSD, C99, POSIX.1-2001, POSIX.1-2008.
renameat(): POSIX.1-2008.
renameat2() ist Linux-spezifisch.
Mit älteren Kerneln, wenn renameat() nicht
verfügbar ist, weicht die Glibc-Wrapper-Funktion auf rename()
aus. Wenn alterpfad und neuerpfad relative Pfadnamen sind,
konstruiert die Glibc Pfadnamen auf Basis der symbolischen Links in
/proc/self/fd, die den Argumenten altVerzdd und
neuVerzdd entsprechen.
Auf NFS-Dateisystemen kann bei einer fehlgeschlagenen Operation
nicht davon ausgegangen werden, dass die Datei nicht umbenannt wurde. Falls
der Server die Datei umbenennt und dann abstürzt, gibt der erneut
übertragene RPC, der nach dem Wiederanlaufen des Servers verarbeitet
wird, einen Fehler zurück. Von der Anwendung wird erwartet, dies zu
berücksichtigen. Siehe link(2) für ein ähnliches
Problem.
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von
Elmar Jansen <ej@pumuckel.gun.de>, Martin Eberhard Schauer
<Martin.E.Schauer@gmx.de>, Helge Kreutzmann
<debian@helgefjell.de> und Mario Blättermann
<mario.blaettermann@gmail.com> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die
GNU General
Public License Version 3 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.