rename(2) System Calls Manual rename(2) NAZWA rename, renameat, renameat2 - zmienia nazwe lub polozenie pliku BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int rename(const char *oldpath, const char *newpath); #include /* Definicja stalych AT_* */ #include int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); int renameat2(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags); Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)): renameat(): Od glibc 2.10: _POSIX_C_SOURCE >= 200809L Przed glibc 2.10: _ATFILE_SOURCE renameat2(): _GNU_SOURCE OPIS rename() zmienia nazwe pliku, przenoszac go pomiedzy katalogami, jesli to konieczne. Nie wplywa to na wszelkie inne zwykle (twarde) dowiazania do pliku (jak utworzone przez link(2)). Nie ma wplywu rowniez na deskryptory pliku otwartego na oldpath. Na to, czy operacja zmiany nazwy sie powiedzie, wplywa wiele ograniczen: zob. BLEDY nizej. Jesli newpath juz istnieje, zostanie zastapiona w sposob niepodzielny tak, ze w zadnym momencie, gdy inny proces sprobuje uzyskac dostep do newpath, nie zastanie jej nieistniejacej. Jednak prawdopodobnie wystapi okno czasowe, w ktorym oldpath i newpath beda odnosic sie do przemianowywanego pliku. Jesli oldpath i newpath sa istniejacymi dowiazaniami zwyklymi (twardymi), odnoszacymi sie do tego pliku, to rename() nic nie robi i zwraca status powodzenia. Jesli newpath istnieje, lecz operacja z jakiegos powodu sie nie powiedzie, rename() daje gwarancje pozostawienia wystapienia newpath bez zmian. oldpath moze okreslac katalog. W tym przypadku, newpath musi albo nie istniec, albo musi okreslac pusty katalog. Jesli oldpath odnosi sie do dowiazania symbolicznego, dowiazaniu temu zostanie zmieniona nazwa; jesli newpath odnosi sie do dowiazania symbolicznego, dowiazanie zostanie nadpisane. renameat() Wywolanie systemowe renameat() operuje w dokladnie taki sam sposob jak rename(), z wyjatkiem roznic opisanych tutaj. Jesli sciezka podana w oldpath jest wzgledna, jest to interpretowane w odniesieniu do katalogu do ktorego odnosi sie deskryptor pliku olddirfd (zamiast w odniesieniu do biezacego katalogu roboczego procesu wywolujacego, jak w stosunku do sciezek wzglednych robi to rename()). Jesli oldpath jest wzgledna a olddirfd ma wartosc specjalna AT_FDCWD, to oldpath jest interpretowana w odniesieniu do biezacego katalogu roboczego procesu wywolujacego (jak rename()). Jesli oldpath jest bezwzgledna, to olddirfd jest ignorowane. Interpretacja newpath jest taka sama jak oldpath, z tym wyjatkiem, ze sciezka wzgledna jest interpretowana wzgledem katalogu, do ktorego odnosi sie deskryptor pliku newdirfd. Wiecej informacji o potrzebie wprowadzenia renameat() mozna znalezc w podreczniku openat(2). renameat2() renameat2() ma dodatkowy argument flags. Wywolanie renameat2() z zerowym argumentem flags jest rownowazne renameat(). Argument flags jest maska bitowa skladajaca sie z zera lub wiecej nastepujacych znacznikow: RENAME_EXCHANGE Niepodzielnie wymienia oldpath i newpath. Obie sciezki musza istniec, lecz moga byc roznego typu (np. jedna moze byc niepustym katalogiem, a druga dowiazaniem symbolicznym). RENAME_NOREPLACE Nie nadpisuje newpath przy zmianie nazwy. Zwraca blad, gdy newpath juz istnieje. RENAME_NOREPLACE nie mozna laczyc z RENAME_EXCHANGE. RENAME_NOREPLACE wymaga obslugi w systemie plikow. Pojawiala sie ona zgodnie z ponizszym wykazem: o ext4 (Linux 3.15); o btrfs, tmpfs i cifs (Linux 3.17); o xfs (Linux 4.0); o Obsluge wielu innych systemow plikow dodano w Linuksie 4.9, w tym ext2, minix, reiserfs, jfs, vfat i bpf. RENAME_WHITEOUT (od Linuksa 3.18) Operacja ta ma sens tylko w implementacjach systemu plikow typu nakladka/unia (overlay/union). Podanie RENAME_WHITEOUT tworzy obiekt ,,zaciemniajacy" w miejscu zrodla zmiany nazwy w momencie dokonywania zmiany nazwy. Cala operacja jest niepodzielna, tak wiec jesli zmiana nazwy sie powiedzie, to utworzone zostanie rowniez zaciemnienie. Obiekt ,,zaciemniajacy" ma specjalne znaczenie w systemach plikow typu nakladka/unia. Istnieje tam wiele warstw i jedyna, ktora jest kiedykolwiek modyfikowana, jest najwyzsza. Zaciemnienie na wyzszej warstwie, efektywnie ukrywa odpowiedni plik w nizszej warstwie, dajac wrazenie, ze plik nie istnieje. Jesli plikowi istniejacemu w nizszej warstwie zmieniana jest nazwa, plik jest najpierw kopiowany w gore (jesli nie jest jeszcze na wyzszej warstwie), a nastepnie zmieniana jest mu nazwa na wyzszej warstwie, bedacej do odczytu i zapisu. W tym samym czasie plik zrodlowy musi byc ,,zaciemniony" (dzieki czemu wersja pliku zrodlowego w nizszej warstwie staje sie niewidoczna). Cala operacja musi byc niepodzielna. Gdy nie jest czescia nakladki/unii, zaciemnienie jest widoczne jako urzadzenie znakowe z numerem urzadzenia {0,0} (prosze zauwazyc, ze inne implementacje nakladki/unii moga uzywac odmiennych metod do przechowywania zaciemnionych wpisow; w szczegolnosci, unie BSD korzystaja z oddzielnego typu i-wezla, ktory, choc obslugiwany przez niektore systemy plikow dostepne w Linuksie, takie jak CODA i XFS, jest ignorowany przez zaciemniajacy kod jadra, przynajmniej wedlug stanu na Linuksa 4.19). RENAME_WHITEOUT wymaga tych samym przywilejow, co utworzenie wezla urzadzenia (tj. przywileju CAP_MKNOD). RENAME_WHITEOUT nie mozna laczyc z RENAME_EXCHANGE. RENAME_WHITEOUT musi byc obslugiwane przez przedmiotowy system plikow. Posrod obslugujacych systemow plikow sa: tmpfs (od Linuksa 3.18), ext4 (od Linuksa 3.18), XFS (od Linuksa 4.1), f2fs (od Linuksa 4.2), btrfs (od Linuksa 4.7) oraz ubifs (od Linuksa 4.9). WARTOSC ZWRACANA Po pomyslnym zakonczeniu zwracane jest zero. Po bledzie zwracane jest -1 i ustawiane errno, wskazujac blad. BLEDY EACCES Odmowiono uprawnienia zapisu dla katalogu zawierajacego oldpath lub newpath; albo odmowiono uprawnienia przeszukiwania dla jednego z katalogow w przedrostku sciezki oldpath lub newpath; albo oldpath jest katalogiem i nie zezwala na uprawnienie zapisu (potrzebne do zaktualizowania wpisu ..). Zob. tez path_resolution(7). EBUSY Zmiana nazwy nie powiodla sie, poniewaz oldpath lub newpath jest katalogiem, ktory jest uzywany przez jakis proces (byc moze jako biezacy katalog roboczy albo katalog glowny, albo poniewaz byl otwarty do odczytu) lub jest uzywany przez system (np. jako punkt montowania), a system uwaza to za blad (prosze zauwazyc, ze nie ma obowiazku zwracania w takim przypadku EBUSY -- nie ma niczego zlego w dokonaniu wowczas zmiany nazwy -- lecz mozna zwrocic EBUSY, jesli system nie moze jednak obsluzyc takich sytuacji). EDQUOT Przydzial blokow dyskowych uzytkownika dotyczacy systemu plikow zostal wyczerpany. EFAULT oldpath lub newpath wskazuje poza dostepna dla uzytkownika przestrzen adresowa. EINVAL Nowa sciezka zawierala przedrostek sciezki starej lub, ogolniej, probowano utworzyc katalog lub podkatalog siebie samego. EISDIR newpath jest istniejacym katalogiem, lecz oldpath nie jest katalogiem. ELOOP Podczas rozwiazywania oldpath lub newpath napotkano zbyt wiele dowiazan symbolicznych. EMLINK Do oldpath osiagnieto juz maksymalna dowiazan lub byl to katalog, a katalog zawierajacy newpath ma maksymalna liczbe dowiazan. ENAMETOOLONG oldpath lub newpath bylo zbyt dlugie. ENOENT Dowiazanie o nazwie oldpath nie istnieje; lub skladowa katalogu w newpath nie istnieje; lub oldpath albo newpath jest lancuchem pustym. ENOMEM Brak pamieci jadra. ENOSPC Na urzadzeniu zawierajacym plik nie ma miejsca na kolejny wpis w katalogu. ENOTDIR Skladowa uzywana jako katalog w oldpath lub newpath nie jest faktycznie katalogiem; lub oldpath jest katalogiem, a newpath istnieje, lecz nie jest katalogiem. ENOTEMPTY lub EEXIST newpath jest niepustym katalogiem tj. zawiera wpisy inne niz ,,." oraz ,,..". EPERM lub EACCES Katalog zawierajacy oldpath ma ustawiony bit lepkosci (S_ISVTX), a efektywny identyfikator uzytkownika procesu nie jest ani identyfikatorem uzytkownika usuwanego pliku, ani katalogu go zawierajacego oraz proces nie jest uprzywilejowany (Linux: nie ma przywileju CAP_FOWNER); albo: newpath jest istniejacym plikiem, katalog go zawierajacy ma ustawiony bit lepkosci, a efektywny identyfikator uzytkownika procesu nie jest ani identyfikatorem uzytkownika usuwanego pliku, ani katalogu go zawierajacego oraz proces nie jest uprzywilejowany (Linux: nie ma przywileju CAP_FOWNER); albo: system plikow zawierajacy oldpath nie obsluguje zmiany nazwy zadanego typu. EROFS Plik lezy w systemie plikow tylko do odczytu. EXDEV oldpath i newpath nie sa polozone w zamontowanym tak samo systemie plikow (Linux zezwala na zamontowanie systemu plikow w wielu punktach, ale rename() nie dziala poprzez rozne punkty montowania, nawet jesli w obu zamontowany jest ten sam system plikow). W przypadku renameat() i renameat2() moga wystapic nastepujace, dodatkowe bledy: EBADF oldpath (newpath) jest wzgledna, lecz olddirfd (newdirfd) nie jest prawidlowym deskryptorem pliku. ENOTDIR oldpath jest wzgledna, a olddirfd jest deskryptorem pliku odnoszacym sie do pliku innego niz katalog; lub analogicznie dla newpath i newdirfd Nastepujace dodatkowe bledy moga wystapic w przypadku renameat2(): EEXIST flags zawiera RENAME_NOREPLACE, a newpath juz istnieje. EINVAL We flags podano nieprawidlowy znacznik. EINVAL We flags podano rownoczesnie RENAME_NOREPLACE i RENAME_EXCHANGE. EINVAL We flags podano rownoczesnie RENAME_WHITEOUT i RENAME_EXCHANGE. EINVAL System plikow nie obsluguje jednego ze znacznikow z flags. ENOENT flags zawiera RENAME_EXCHANGE, a newpath nie istnieje. EPERM We flags podano RENAME_WHITEOUT, lecz wywolujacy nie ma przywileju CAP_MKNOD. STANDARDY rename() C11, POSIX.1-2008. renameat() POSIX.1-2008. renameat2() Linux. HISTORIA rename() 4.3BSD, C89, POSIX.1-2001. renameat() Linux 2.6.16, glibc 2.4. renameat2() Linux 3.15, glibc 2.28. Uwagi dla glibc W starszych jadrach, gdzie renameat() jest niedostepne, funkcja opakowujaca korzysta zapasowo z rename(). Gdy oldpath i newpath sa sciezkami wzglednymi, glibc tworzy sciezki w oparciu o dowiazania symboliczne w /proc/self/fd, ktore sa zwiazane z argumentami olddirfd i newdirfd. USTERKI W systemach plikow NFS nie mozna zakladac, ze przy niepowodzeniu operacji, nazwa pliku nie ulegla zmianie. Jesli serwer dokonuje operacji zmiany nazwy, a nastepnie sie zalamie, ponowna transmisja RPC, ktora nastapi po podniesieniu sie serwera, spowoduje blad. Oczekuje sie, ze aplikacje maja sobie z tym radzic. Podobny problem wystepuje w link(2). ZOBACZ TAKZE mv(1), rename(1), chmod(2), link(2), symlink(2), unlink(2), path_resolution(7), symlink(7) TLUMACZENIE Tlumaczenie niniejszej strony podrecznika: Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.15 17 maja 2025 r. rename(2)