rename, renameat, renameat2 - change the name or location of a file
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
#include <fcntl.h> /* Definition of AT_* constants */
#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);
//Both return: 0 if OK, -1 on error
ISO C中
rename
只用于文件(标准C不处理目录)。POSIX.1 扩展(expand)了其定义包含目录(directory)和链接文件(symbolic links)
There are several conditions to describe for these functions, depending on whether oldname
refers to a file, a directory, or a symbolic link. We must also describe what happens if newname
already exists.(oldname引用不同文件情况不同,newname
已经存在也会有些情况)
several conditions |
---|
If oldname specifies a file that is not a directory , then we are renaming a file or a symbolic link . In this case, if newname exists, it cannot refer to a directory. If newname exists and is not a directory , it is removed , and oldname is renamed to newname . We must have write permission for the directory containing oldname and the directory containing newname , since we are changing both directories. |
If oldname specifies a directory , then we are renaming a directory. If newname exists, it must refer to a directory, and that directory must be empty. (When we say that a directory is empty , we mean that the only entries in the directory are dot and dot-dot.) If newname exists and is an empty directory , it is removed, and oldname is renamed to newname . Additionally, when we’re renaming a directory, newname cannot contain a path prefix that names oldname . For example, we can’t rename /usr/foo to /usr/foo/testdir , because the old name (/usr/foo) is a path prefix of the new name and cannot be removed. |
If either oldname or newname refers to a symbolic link , then the link itself is processed, not the file to which it resolves. |
We can’t rename dot . or dot-dot .. More precisely, neither dot . nor dot-dot .. can appear as the last component of oldname or newname. |
As a special case, if oldname and newname refer to the same file, the function returns successfully without changing anything. |
If newname already exists, we need permissions as if we were deleting it. Also, because we’re removing the directory entry foroldname
and possibly creating a directory entry for newname
, we need write permission
and execute permission
in the directory containing oldname
and in the directory containing newname
.
renameat
The renameat
function provides the same functionality as the rename function, except when either oldname
ornewname
refers to a relative pathname. If oldname
specifies a relative pathname
, it is evaluated relative to the directory referenced by oldfd
. Similarly, newname
is evaluated relative to the directory referenced by newfd
if newname specifies a relative pathname. Either the oldfd or newfd arguments (or both) can be set to AT_FDCWD
to evaluate the corresponding pathname relative to the current directory.