Provided by: manpages-ru-dev_4.18.1-1_all bug

ИМЯ

       rename, renameat, renameat2 - изменяет имя или расположение файла

LIBRARY

       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);

   Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

       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()
       Системный  вызов  renameat()  работает  также как системный вызов rename(), за исключением
       случаев, описанных далее.

       Если в oldpath указан относительный  путь,  то  он  считается  относительно  каталога,  на
       который  ссылается  файловый  дескриптор  olddirfd  (а  не  относительно текущего рабочего
       каталога вызывающего процесса, как это делается в rename()).

       Если в oldpath указан относительный путь и olddirfd равно специальному значению  AT_FDCWD,
       то  oldpath  рассматривается  относительно текущего рабочего каталога вызывающего процесса
       (как rename()).

       Если в oldpath указан абсолютный путь, то olddirfd игнорируется.

       Значение newpath интерпретируется как oldpath, за исключением того, что относительный путь
       интерпретируется относительно каталога, на который ссылается файловый дескриптор newdirfd.

       Смотрите в openat(2) объяснение необходимости renameat().

   renameat2()
       Вызов  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), где описывается подобная проблема.

СМ. ТАКЖЕ

       mv(1), rename(1), chmod(2), link(2), symlink(2), unlink(2), path_resolution(7), symlink(7)

ПЕРЕВОД

       Русский  перевод  этой страницы руководства был сделан 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 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе  этой  страницы  руководства,  пожалуйста,  отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.