我需要取消空目录的链接
unlinkat(dir_fd, ".", AT_REMOVEDIR)
并且我得到
EINVAL errno
,根据 GNU 官方文档,这必定意味着“在 flags
中指定了无效的标志值”,但事实并非如此,因为 AT_REMOVEDIR
是(唯一)允许的标志。
SSCCE 如下。请注意,在最简单的代码中,我确实有目录名称,所以我可以使用
rmdir
。在真实情况下,我没有名称,我只有描述符,到一个空目录,我需要删除它 - 所以我必须使用 unlinkat
.
foobar.c
:
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int dir_fd =
open("dir", O_RDONLY | O_PATH | O_DIRECTORY);
if (-1 == dir_fd) {
perror("open");
return(1);
}
if (unlinkat(dir_fd, ".", AT_REMOVEDIR)) {
perror("unlinkat");
fprintf(stderr, "errno %d\n", errno);
return(1);
}
}
我得到了这种行为:
$mkdir dir
$gcc -lc foobar.c
$./a.out
unlinkat: Invalid argument
errno 22
$errno 22
EINVAL 22 Invalid argument
和 GNU 文档
unlinkat
说
EINVAL 在标志中指定了无效的标志值。
当使用
AT_REMOVEDIR
调用时,unlinkat(2)
的行为与 rmdir(2)
相同,最终会因为同样的原因而失败。
对于
rmdir(2)
:
EINVAL 路径名具有 .作为最后一个组件。
你貌似把界面翻了,真的应该用做
/* foobar.c */
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int dir_fd = open(".", O_RDONLY | O_PATH | O_DIRECTORY);
if (-1 == dir_fd) {
perror("open");
return(1);
}
if (unlinkat(dir_fd, "dir", AT_REMOVEDIR)) {
perror("unlinkat");
fprintf(stderr, "errno %d\n", errno);
return(1);
}
close(dir_fd);
}
$ mkdir dir
$ ./a.out
(或者
AT_FDCWD
的特殊值应该用于unlinkat
的第一个参数来删除相对于当前工作目录的文件。)
如果您不知道要删除的目录的名称,这显然对您没有帮助。