void
rm_r(int rootfd, const char *path, uid_t uid)
{
int dirfd;
DIR *d;
struct dirent *e;
struct stat st;
if (*path == '/')
path++;
dirfd = openat(rootfd, path, O_DIRECTORY);
if (dirfd == -1) {
return;
}
d = fdopendir(dirfd);
while ((e = readdir(d)) != NULL) {
if (strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0)
continue;
if (fstatat(dirfd, e->d_name, &st, AT_SYMLINK_NOFOLLOW) != 0)
continue;
if (S_ISDIR(st.st_mode))
rm_r(dirfd, e->d_name, uid);
else if (S_ISLNK(st.st_mode) || st.st_uid == uid)
unlinkat(dirfd, e->d_name, 0);
}
closedir(d);
if (fstatat(rootfd, path, &st, AT_SYMLINK_NOFOLLOW) != 0)
return;
unlinkat(rootfd, path, S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0);
}