ИМЯ
rename, renameat, renameat2 -
изменяет
имя или
расположение
файла
Standard C library (libc, -lc)
СИНТАКСИС
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
#include <fcntl.h> /* определения констант AT_* */
#include <stdio.h>
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);
renameat():
Since glibc 2.10:
_POSIX_C_SOURCE >= 200809L
Before glibc 2.10:
_ATFILE_SOURCE
renameat2():
_GNU_SOURCE
ОПИСАНИЕ
Вызов rename()
переименовывает
файл и, если
требуется,
перемещает
его из
одного
каталога в
другой. Все
прочие
жёсткие
ссылки на
файл
(созданные
с помощью
link(2)), не
изменяются.
Открытые
файловые
дескрипторы
на oldpath также
не
изменяются.
На
успешность
выполнения
операции
переименования
влияют
различные
ограничения:
смотрите
ОШИБКИ
далее.
Если newpath
уже
существует,
то он будет
атомарно
перезаписан
так, что
другой
процесс,
пытающийся
в этот
момент
обратиться
к newpath, не
сможет
определить
его
временное
отсутствие.
Однако
будет
промежуток
времени,
когда oldpath и
newpath
указывают
на один
файл.
Если oldpath и
newpath
являются
жёсткими
ссылками
на один и
тот же файл,
то rename()
ничего не
делает и
возвращает
код
успешного
выполнения.
Если newpath
существует,
но
операция
завершается
ошибкой, то
rename()
гарантирует,
что newpath
останется
нетронутым.
В oldpath может
быть
указан
каталог. В
этом
случае
каталог в
newpath должен
или не
существовать,
или должен
быть пуст.
Если oldpath
является
символьной
ссылкой, то
она
переименовывается;
если newpath
является
символьной
ссылкой, то
будет
вновь
записан
файл, на
который
она
указывает.
Системный
вызов renameat()
работает
также как
системный
вызов rename(), за
исключением
случаев,
описанных
далее.
Если в oldpath
указан
относительный
путь, то он
считается
относительно
каталога,
на который
ссылается
файловый
дескриптор
olddirfd (а не
относительно
текущего
рабочего
каталога
вызывающего
процесса,
как это
делается в
rename()).
Если в oldpath
указан
относительный
путь и olddirfd
равно
специальному
значению
AT_FDCWD, то oldpath
рассматривается
относительно
текущего
рабочего
каталога
вызывающего
процесса
(как rename()).
Если в oldpath
указан
абсолютный
путь, то olddirfd
игнорируется.
Значение
newpath
интерпретируется
как oldpath, за
исключением
того, что
относительный
путь
интерпретируется
относительно
каталога,
на который
ссылается
файловый
дескриптор
newdirfd.
Смотрите
в openat(2)
объяснение
необходимости
renameat().
Вызов renameat2()
имеет
дополнительный
аргумент
flags. Если
значение
flags равно
нулю, то renameat2()
эквивалентен
renameat().
Аргумент
flags
является
битовой
маской,
состоящей
из нуля или
более
следующих
флагов:
- RENAME_EXCHANGE
- Атомарно
обменять
oldpath и newpath. Оба
пути
должны
существовать,
но могут
быть
различных
типов
(например,
один может
быть
непустым
каталогом,
а другой
символической
ссылкой).
- RENAME_NOREPLACE
- Не
перезаписывать
newpath.
Возвращать
ошибку,
если newpath уже
существует.
- RENAME_NOREPLACE не
может быть
применен
вместе с
RENAME_EXCHANGE.
- Для RENAME_NOREPLACE
требуется
поддержка
в файловой
системе;
она есть
только у
нескольких
файловых
систем:
- •
- ext4 (начиная
с Linux 3.15);
- •
- btrfs, tmpfs, and cifs (Linux 3.17);
- •
- xfs (начиная
с Linux 4.0);
- •
- Поддержка
для других
файловых
систем
была
добавлена
в Linux 4.9: ext2, minix, reiserfs, jfs, vfat и bpf.
- RENAME_WHITEOUT
(начиная с Linux
3.18)
- Эта
операция
применима
только для
реализаций
оверлейных/объединённых
файловых
систем.
- При
указании
RENAME_WHITEOUT для
источника
переименования
одновременно
с
выполнением
переименования
создаётся
«замазанный»
объект (whiteout object).
Вся
операция
атомарна, и
при
успешном
выполнении
переименования
создаётся
и замазка.
- «Замазка»
— это
объект,
имеющий
специальное
предназначение
в
оверлейных/объединённых
файловых
системах. В
них
существует
несколько
слоёв, и
для
изменения
доступен
только
верхний.
Замазка на
верхнем
слое
эффективно
скрывает
файл из
нижнего
слоя, и
кажется,
что файл не
существует.
- Когда
переименовывается
файл,
существующий
в нижнем
слое, то
первым
действием
он
переписывается
(если его
уже нет в
верхнем
слое) и
переименовывается
в верхнем,
доступном
на
чтение-запись
слое.
Одновременно
с этим,
исходный
файл
требуется
«замазать»
(что
исходный
файл в
нижнем
слое
отражался
невидимым).
Вся
операция
должна
выполняться
атомарно.
- При
отсутствии
объединения/оверлея
замазка
появляется
в виде
символьного
устройства
с номером
устройства
{0,0} (заметим,
что в
других
реализациях
объединения/оверлея
могут
использоваться
другие
методы
хранения
элементов
замазки; в
частности,
в BSD для
объединения
монтирования
используется
специальный
тип иноды,
DT_WHT, который,
хотя и
поддерживается
некоторыми
файловыми
системами,
доступными
в Linux,
например CODA
и XFS, но
игнорируется
кодом
поддержки
замазки в
ядре, по
крайней
мере, в Linux 4.19).
- Для RENAME_WHITEOUT
требуются
те же
права, что
и для
создания
узла
устройства
(т. е.,
мандата
CAP_MKNOD).
- RENAME_WHITEOUT не
может быть
применён
вместе с
RENAME_EXCHANGE.
- RENAME_WHITEOUT requires support from the underlying filesystem.
Among the filesystems that support it are tmpfs (since Linux 3.18), ext4
(since Linux 3.18), XFS (since Linux 4.1), f2fs (since Linux 4.2), btrfs
(since Linux 4.7), and ubifs (since Linux 4.9).
ВОЗВРАЩАЕМОЕ
ЗНАЧЕНИЕ
On success, zero is returned. On error, -1 is returned, and
errno is set to indicate the error.
ОШИБКИ
- EACCES
- Запись в
каталог,
содержащий
oldpath или newpath,
запрещена,
или в одном
из
каталогов
пути oldpath или
newpath нельзя
производить
поиск, или
oldpath
является
каталогом,
в который
запрещена
запись
(требует
обновления
элемента
..);
смотрите
также path_resolution(7)).
- EBUSY
- The rename fails because oldpath or newpath is a directory
that is in use by some process (perhaps as current working directory, or
as root directory, or because it was open for reading) or is in use by the
system (for example as a mount point), while the system considers this an
error. (Note that there is no requirement to return EBUSY in such
cases—there is nothing wrong with doing the rename
anyway—but it is allowed to return EBUSY if the system
cannot otherwise handle such situations.)
- EDQUOT
- Исчерпана
пользовательская
квота на
дисковые
блоки
файловой
системы.
- EFAULT
- Значения
oldpath и newpath
указывают
за пределы
доступного
адресного
пространства.
- EINVAL
- Новый путь
содержит
префикс
старого
пути или, в
более
общем
смысле,
выполняется
попытка
сделать
каталог
подкаталогом
самого
себя.
- EISDIR
- Каталог newpath
уже
существует,
но oldpath не
является
каталогом.
- ELOOP
- Во время
определения
oldpath или newpath
встретилось
слишком
много
символьных
ссылок.
- EMLINK
- В oldpath уже
имеется
максимальное
количество
ссылок, или
каталог,
содержащий
newpath, уже
имеет
максимальное
количество
ссылок.
- ENAMETOOLONG
- Слишком
длинное
значение
аргумента
oldpath или newpath.
- ENOENT
- Ссылка, на
которую
ссылается
oldpath, не
существует;
компонент
каталога в
newpath не
существует;
в oldpath или newpath
указана
пустая
строка.
- ENOMEM
- Недостаточное
количество
памяти
ядра.
- ENOSPC
- На
устройстве,
содержащем
файл, нет
места для
создания
нового
элемента
каталога.
- ENOTDIR
- Компонент,
используемый
как
каталог в
oldpath или newpath, в
действительности
не
является
каталогом.
Или oldpath
является
каталогом
и
существует
newpath, который
не
является
каталогом.
- ENOTEMPTY
или EEXIST
- Значение
newpath
является
непустым
каталогом,
то есть
содержит
элементы,
отличные
от «.» и «..».
- EPERM
или EACCES
- Каталог,
содержащийся
в oldpath, имеет
закрепляющий
бит (S_ISVTX) и
эффективный
идентификатор
процесса
не
совпадает
с
идентификатором
пользователя
удаляемого
файла или
каталога,
его
содержащего,
и процесс
не имеет
прав (Linux: нет
мандата
CAP_FOWNER); или newpath
является
существующим
файлом и
каталог,
содержащий
его, имеет
закрепляющий
бит и
эффективный
идентификатор
процесса
не
совпадает
с
идентификатором
пользователя
замещаемого
файла или
каталога,
его
содержащего,
и процесс
не имеет
прав (Linux: нет
мандата
CAP_FOWNER); или
файловая
система,
содержащая
oldpath, не
поддерживает
переименования
запрашиваемого
типа.
- EROFS
- Файл
расположен
в файловой
системе,
доступной
только для
чтения.
- EXDEV
- Элементы
oldpath и newpath
находятся
не в одной
смонтированной
файловой
системе (Linux
позволяет
монтировать
файловую
систему в
несколько
точек, но rename()
не
работает с
различающимися
точками
монтирования,
даже если в
них
смонтирована
идентичная
файловая
система).
В renameat() и renameat2()
дополнительно
могут
возникнуть
следующие
ошибки:
- EBADF
- oldpath (newpath) is relative but olddirfd
(newdirfd) is not a valid file descriptor.
- ENOTDIR
- Значение
oldpath
содержит
относительный
путь и olddirfd
содержит
файловый
дескриптор,
указывающий
на файл, а
не на
каталог;
или
произошло
тоже самое
с newpath и newdirfd.
В renameat2()
дополнительно
могут
возникнуть
следующие
ошибки:
- EEXIST
- Значение
flags
содержит
RENAME_NOREPLACE, а newpath уже
существует.
- EINVAL
- В flags указан
неверный
флаг.
- EINVAL
- В flags
указаны
оба флага,
RENAME_NOREPLACE и RENAME_EXCHANGE.
- EINVAL
- В flags
указаны
оба флага,
RENAME_WHITEOUT и RENAME_EXCHANGE.
- EINVAL
- Файловая
система не
поддерживает
один из
флагов в
flags.
- ENOENT
- В flags
содержится
RENAME_EXCHANGE, но newpath не
существует.
- EPERM
- В flags указан
флаг RENAME_WHITEOUT , но
вызывающий
не имеет
мандата
CAP_MKNOD.
ВЕРСИИ
renameat() was added in Linux 2.6.16; library support was
added in glibc 2.4.
renameat2() was added in Linux 3.15; library support was
added in glibc 2.28.
СТАНДАРТЫ
rename(): 4.3BSD, C99, POSIX.1-2001, POSIX.1-2008.
renameat(): POSIX.1-2008.
Вызов renameat2()
есть
только в Linux.
ЗАМЕЧАНИЯ
Замечания
по glibc
В старых
ядрах, где
renameat()
отсутствует,
обёрточная
функция glibc
использует
rename(). Если oldpath и
newpath
являются
относительными
путями, то glibc
собирает
пути
относительно
символической
ссылки в
/proc/self/fd,
которая
соответствует
аргументам
olddirfd и newdirfd.
ДЕФЕКТЫ
При
работе с
файловыми
системами NFS
нельзя
считать,
что если
операция
завершилась
неудачно,
то имя
файла не
изменилось.
Если
сервер
производит
операцию
переименования,
а затем
аварийно
останавливает
свою
работу, то
перепосланный
пакет RPC
будет
вновь
обработан
при
восстановлении
работы
сервера,
что
вызовет
сообщение
об ошибке.
Приложение
в этой
ситуации
должно
работать
корректно.
Смотрите
link(2), где
описывается
подобная
проблема.
ПЕРЕВОД
Русский
перевод
этой
страницы
руководства
был сделан
aereiae <aereiae@gmail.com>, Azamat Hackimov
<azamat.hackimov@gmail.com>, Dmitriy S. Seregin
<dseregin@59.ru>, Katrin Kutepova <blackkatelv@gmail.com>,
Lockal <lockalsash@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>,
Баринов
Владимир и
Иван
Павлов
<pavia00@gmail.com>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
man-pages-ru-talks@lists.sourceforge.net.