/* This file is part of limb https://lila.oss/limb
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <limb/djbunix.h>
int
rm_rf_in_tmpat(int fd, stralloc *sa, size_t offset)
{
/* try basic unlinking */
if (!unlinkat(fd, sa->s + offset, 0) || errno == ENOENT)
return 0;
/* two possible errno-s (Linux & POSIX) for not unlinking a directory */
if (errno != EISDIR && errno != EPERM)
return -1;
/* might be that it's a dir, so let's empty it */
if (rmstar_in_tmpat(fd, sa, offset) < 0) {
/* ENOTDIR means it's not a directory (couldn't be listed) so restore
* the previous errno */
if (errno == ENOTDIR)
errno = EPERM;
return -1;
}
/* remove the now empty directory */
return unlinkat(fd, sa->s + offset, AT_REMOVEDIR);
}