Welcome to little lamb

Code » limb » master » tree

[master] / src / liblimb / djbunix.h / rm_rf_in_tmpat.c

/* 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);
}