文件或目录可以用rename函数或者renameat函数进行重命名。
#include <stdio.h> int rename(const char * oldname, const char * newname); int renameat(int oldfd, const char *oldname, int newfd, const char *newpath); 两个函数的返回值:若成功,返回0;若出错,返回-1. |
根据oldname是指文件、目录还是符号链接,有几种情况需要加以说明。我们也必须说明如果newname已经存在时将会发生什么。
(1)如果oldname指的是一个文件而不是目录,那么为该文件或符号链接重命名。在这种情况下,如果newname已存在,则它不能引用一个目录。如果newname已存在,而且不是一个目录,则先将该目录项删除然后将oldname重命名为newname。对包含oldname的目录以及包含newname的目录,调用进程必须具有写权限,因为将更改这两个目录。
(2)如若oldname指的是一个目录,那么为该目录重命名。如果newname已存在,则它必须引用一个目录,而且该目录应当时空目录(空目录指的是该目录中只有.和..项)。如果newname存在(而且是一个空目录),则先将其删除,然后将oldname重命名为newname。另外,当为一个目录重命名时,newname不能包含oldname作为其路径前缀。例如,不能将/usr/foo重命名为/usr/foo/testdir,因为旧名字(/usr/foo)是新名字的路径前缀,因而不能将其删除。
(3)如若oldname或newname引用符号链接,则处理的是符号链接本身,而不是它所引用的文件。
(4)不能对.和..重命名。更确切地说,.和..都不能出现在oldname和newname的最后部分。
(5)作为一个特例,如果oldname和newname引用同一文件,则函数不做任何更改而成功返回。
如若newname已经存在,则调用进程对它需要有写权限(如同删除情况一样)。另外,调用进程将删除oldname目录项,并可能要创建newname目录项,所以它需要对包含oldname及包含newname的目录具有写和执行权限。
除了当oldname或newname指向相对路径名时,其他情况下renameat函数与rename函数功能相同。如果oldname参数指定了相对路径,就相对于oldfd参数引用的目录来计算oldname。类似地,如果newname指定了相对路径,就相对于newfd引用的目录来计算newname。oldfd或newfd参数(或两者)都能设置成AT_FDCWD,此时相对于当前目录来计算相应的路径名。