]> git.ipfire.org Git - pakfire.git/commitdiff
file: Be smarter when removing files
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 24 Mar 2023 15:56:41 +0000 (15:56 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 24 Mar 2023 15:58:37 +0000 (15:58 +0000)
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 <michael.tremer@ipfire.org>
src/libpakfire/file.c

index f49e9a9aef8fbeee087b84711fe3ed4b834370d6..47ad18fabe553dd337e8adc6f57f09112003e428 100644 (file)
@@ -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;