-/* removes recursively the content of a directory */
-static int clean_dirfd(int dirfd)
-{
- int cr, fd;
- DIR *dir;
- struct dirent *ent;
- struct {
- struct dirent entry;
- char spare[PATH_MAX];
- } entry;
-
- dirfd = dup(dirfd);
- if (dirfd < 0) {
- ERROR("failed to dup the dirfd");
- return -1;
- }
- dir = fdopendir(dirfd);
- if (dir == NULL) {
- ERROR("fdopendir failed in clean_dirfd");
- return -1;
- }
-
- cr = -1;
- for (;;) {
- if (readdir_r(dir, &entry.entry, &ent) != 0) {
- ERROR("readdir_r failed in clean_dirfd");
- goto error;
- }
- if (ent == NULL)
- break;
- if (ent->d_name[0] == '.' && (ent->d_name[1] == 0
- || (ent->d_name[1] == '.' && ent->d_name[2] == 0)))
- continue;
- cr = unlinkat(dirfd, ent->d_name, 0);
- if (!cr)
- continue;
- if (errno != EISDIR) {
- ERROR("unlink of %s failed in clean_dirfd", ent->d_name);
- goto error;
- }
- fd = openat(dirfd, ent->d_name, O_DIRECTORY|O_RDONLY);
- if (fd < 0) {
- ERROR("opening directory %s failed in clean_dirfd", ent->d_name);
- goto error;
- }
- cr = clean_dirfd(fd);
- close(fd);
- if (cr)
- goto error;
- cr = unlinkat(dirfd, ent->d_name, AT_REMOVEDIR);
- if (cr) {
- ERROR("rmdir of %s failed in clean_dirfd", ent->d_name);
- goto error;
- }
- }
- cr = 0;
-error:
- closedir(dir);
- return cr;
-}
-
-/* removes recursively the content of a directory */
-static int clean_dir(const char *directory)
-{
- int fd, rc;
-
- fd = openat(AT_FDCWD, directory, O_DIRECTORY|O_RDONLY);
- if (fd < 0) {
- ERROR("opening directory %s failed in clean_dir", directory);
- return fd;
- }
- rc = clean_dirfd(fd);
- close(fd);
- return rc;
-}
-