From 84eee57a363363f1a94a1fed3f63861ba276c6b8 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 24 Mar 2023 15:56:41 +0000 Subject: [PATCH] file: Be smarter when removing files Before, when we tried to remove a file from the filesystem, we tried to call unlink() and if that failed, we tried rmdir() instead. This patch changes that we will call rmdir() in the first place for directories and unlink() for everything else so that we can catch error codes more granulary. Signed-off-by: Michael Tremer --- src/libpakfire/file.c | 61 ++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index f49e9a9ae..47ad18fab 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -1335,6 +1335,8 @@ int pakfire_file_compute_digests(struct pakfire_file* file, const int types) { } int pakfire_file_remove(struct pakfire_file* file) { + int r; + if (!*file->abspath) { errno = EINVAL; return 1; @@ -1342,22 +1344,51 @@ int pakfire_file_remove(struct pakfire_file* file) { DEBUG(file->pakfire, "Removing %s...\n", file->path); - int r = remove(file->abspath); - if (r) { - switch (errno) { - // Ignore when we could not remove directories - case ENOTEMPTY: - return 0; - - // Ignore if the file didn't exist - case ENOENT: - return 0; - - default: - break; - } + switch (file->st.st_mode & S_IFMT) { + // Call rmdir() for directories + case S_IFDIR: + r = rmdir(file->abspath); + if (r) { + switch (errno) { + // Ignore when the directory is not empty + case ENOTEMPTY: + r = 0; + break; + + // Ignore if the directory didn't exist + case ENOENT: + r = 0; + break; + + // Ignore if the directory changed type + case ENOTDIR: + r = 0; + break; + + // Log anything else + default: + ERROR(file->pakfire, "Could not remove directory %s: %m\n", file->path); + break; + } + } + break; - ERROR(file->pakfire, "Could not remove %s (%s): %m\n", file->path, file->abspath); + // Call unlink() for everything else + default: + r = unlink(file->abspath); + if (r) { + switch (errno) { + // Ignore if the file didn't exist + case ENOENT: + r = 0; + break; + + default: + ERROR(file->pakfire, "Could not remove %s: %m\n", file->path); + break; + } + } + break; } return r; -- 2.39.5