当使用AT_REMOVEDIR
调用时,unlinkat(2)
的行为与rmdir(2)
相同,最终由于相同的原因而失败.
对于rmdir(2)
人:
EINVAL路径名具有.作为最后一个组件.
你似乎颠倒了界面.孤立地看你的example,它应该是
/* 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
其中,相对于由dirfd引用的目录来解析给定给unlinkat
的相对pathname.
(Or the special value of 100 could be used for the first argument of 101 to remove a file relative to the current working directory.)
这个特定的例子显然是做与rmdir("dir")
相同的事情的一种相当复杂的方法,如果您不知道要删除的目录的名称,那么它肯定对您没有帮助.
对于您的实际problem:在Linux上,您可以像下面的示例那样try 使用readlink(2)
读取/proc/self/fd/NNN,其中NNN是文件描述符(您没有它的名称),以便检索rmdir
的pathname.
(See: 100)
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static int mystery_directory(void)
{
char dir[] = "XXXXXX";
if (!mkdtemp(dir))
return -1;
return open(dir, O_RDONLY | O_PATH | O_DIRECTORY);
}
int main(void)
{
/* We have magically arrived at this file descriptor */
int dir_fd = mystery_directory();
if (-1 == dir_fd) {
perror("mystery_directory");
return EXIT_FAILURE;
}
char fdrl[128];
int len = snprintf(fdrl, sizeof fdrl, "/proc/self/fd/%d", dir_fd);
if (len < 0 || len >= sizeof fdrl) {
fprintf(stderr, "Something has gone very wrong.\n");
return EXIT_FAILURE;
}
printf("procfs entry: <%s>\n", fdrl);
char path[4096];
ssize_t r = readlink(fdrl, path, sizeof path - 1);
if (r < 0) {
perror("readlink");
return EXIT_FAILURE;
}
close(dir_fd);
path[r] = 0;
printf("Attempting to remove directory: \n\t%s\n", path);
if (-1 == rmdir(path)) {
perror("rmdir");
return EXIT_FAILURE;
}
puts("Success!");
}
$ pwd
/home/so
$ ./a.out
procfs entry: </proc/self/fd/3>
Attempting to remove directory:
/home/so/IOgkes
Success!