RENAME(2)

ИМЯ
rename - изменяет имя или расположение файла

ОБЗОР
#include <stdio.h>

int rename(const char *oldpath, const char *newpath);

ОПИСАНИЕ
rename() переименовывает файл и, если требуется, перемещает его из одного каталога в другой. Все прочие жёсткие ссылки на файл (созданные с помощью link(2)), не изменяются. Открытые файловые дескрипторы на oldpath также не изменяются. Если newpath уже существует, то он будет атомарно перезаписан (при определенных условиях, см. ОШИБКИ ниже) так, что другой процесс, пытающийся обратиться к newpath, не сможет определить его временное отсутствие. Если oldpath и newpath являются жёсткими ссылками на один и тот же файл, то rename() ничего не делает и возвращает код успешного завершения. Если newpath существует, но операция завершается ошибкой, то rename() гарантирует, что newpath останется нетронутым. В oldpath может быть задан каталог. В этом случае каталог в newpath должен или не существовать, или каталог должен быть пуст. Однако, при перезаписи будет временной промежуток, при котором оба значения, oldpath и newpath, ссылаются на переименовываемый файл. Если oldpath является символьной ссылкой, то она переименовывается; если newpath является символьной ссылкой, то будет вновь записан файл, на который она указывает.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

EACCES
    Запись в каталог, содержащий oldpath или newpath, запрещена, или в одном из каталогов пути oldpath или newpath нельзя производить поиск, или oldpath является каталогом, в который запрещена запись (требует обновления элемента ..). (Смотрите также path_resolution(7).)

EBUSY
    Переименование завершилось неудачно, так как oldpath или newpath является каталогом, который используется другим процессом (возможно в качестве текущего рабочего каталога или в качестве корневого каталога, или он открыт на чтение), или используется системой (например, в качестве точки монтирования), и система считает это ошибкой. (Заметим, что нет требования возвращать EBUSY в таких случаях — нет ничего неправильного в таком переименовании — но разрешается возвращать EBUSY, если система не может иначе обработать такие ситуации.)

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); или файловая система, содержащая pathname, не поддерживает переименования запрашиваемого типа.

EROFS
    Файл расположен в файловой системе, доступной только на чтение.

EXDEV
    Значения oldpath и newpath находятся в разных файловых системах. (Linux позволяет монтирование файловой система сразу в несколько точек монтирования, но rename() не работает в различных точках монтирования даже, если в обоих смонтирована одинаковая файловая система.)

СООТВЕТСТВИЕ СТАНДАРТАМ
4.3BSD, C89, C99, POSIX.1-2001.

ДЕФЕКТЫ
При работе с файловыми системами NFS нельзя считать, что если операция завершилась неудачно, то имя файла не изменилось. Если сервер производит операцию переименования, а затем аварийно останавливает свою работу, то перепосланный пакет RPC будет вновь обработан при восстановлении работы сервера, что вызовет сообщение об ошибке. Приложение в этой ситуации должно работать корректно. См. link(2), где описывается подобная проблема.

СМОТРИТЕ ТАКЖЕ
mv(1), chmod(2), link(2), renameat(2), symlink(2), unlink(2), path_resolution(7), symlink(7)