Changeset 8c35ebd in mainline for uspace/app/cmpdirs/cmpdirs.c


Ignore:
Timestamp:
2026-03-17T12:37:37Z (27 hours ago)
Author:
Vít Skalický <skalicky@…>
Children:
7952b336
Parents:
128a311
git-author:
Vít Skalický <skalicky@…> (2026-03-16 19:31:23)
git-committer:
Vít Skalický <skalicky@…> (2026-03-17 12:37:37)
Message:

Modified cmpdirs to use the dirent.h

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/cmpdirs/cmpdirs.c

    r128a311 r8c35ebd  
    3535 */
    3636
     37#include <dirent.h>
    3738#include <getopt.h>
    3839#include <stdbool.h>
     
    5152/** When reading the content of a file for comparison, how large should one chunk be. */
    5253#define CHUNK_SIZE 0x4000
    53 /** File names longer than this will be truncated. */
    54 #define NAME_BUFFER_SIZE 256
    5554
    5655// Macros to make handling errors less cumbersome
     
    212211        (*entry_out) = s->buffer[s->size];
    213212        return EOK;
    214 }
    215 
    216 /** Writes the name of the entry at position pos in the directory represented by the handle into buffer out_name_buffer
    217  * and writes the number of byte written to the buffer into out_name_len. The name should be null-terminated, unless it was too long.
    218  *
    219  * It assumes:
    220  *      - handle is open for reading (vfs_open())
    221  *
    222  * There is no function for listing a directory in vfs.h and the functions from dirent.h kinda suck, so here I have my own. */
    223 static errno_t list_dir(int handle, aoff64_t pos, size_t buffer_size, char* out_name_buffer, ssize_t *out_name_len) {
    224         errno_t rc = EOK;
    225         rc = vfs_read_short(handle, pos, out_name_buffer, buffer_size, out_name_len);
    226         return rc;
    227213}
    228214
     
    290276        check_ok(rc, close2, "No memory for file buffer #2 (%d bytes needed)\n", CHUNK_SIZE);
    291277
    292         char name_buffer[NAME_BUFFER_SIZE];
    293 
    294278        // While there is something in the stack
    295279        for (struct entry item = {root_handle1, root_handle2}; // initial item
     
    341325                        // 4. add both new handles to stack
    342326
    343                         for (ssize_t pos = 0;
    344                                 ((size_t) pos) < stat1.size;
    345                                 ) {
    346                                 // 1.
    347                                 ssize_t read;
    348                                 rc = list_dir(item.handle1, pos, NAME_BUFFER_SIZE, name_buffer, &read);
    349                                 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Read directory entry name: result %s, read size: %"PRIdn".", str_error_name(rc), read);
    350                                 check_ok_break(rc, "Failed (1) to list handle %d, pos %"PRIdn", total size of directory: %"PRIu64"\n", item.handle1, pos, stat1.size);
     327                        // Since the directories represented by handle1 and handle2 have equal size and all entries in handle1 are
     328                        // also present in handle2, then all entries in handle2 must also be present in handle1. Therefore they are equal.
     329
     330                        struct dirent *dp;
     331                        DIR *dirp = opendir_handle(item.handle1);
     332                        if (!dirp) {
     333                                rc = errno;
     334                                assert(rc != EOK);
     335                        }
     336                        check_ok(rc, close_inner, "Failed to open directory (handle %d", item.handle1);
     337
     338                        while ((dp = readdir(dirp))) { // 1.
    351339                                // Calculate the real length of the entry name (excluding null-terminator)
    352                                 size_t name_size = str_nsize(name_buffer, NAME_BUFFER_SIZE);
     340                                size_t name_buffer_size = sizeof(dp->d_name);
     341                                size_t name_size = str_nsize(dp->d_name, name_buffer_size);
    353342                                // check that the string is null-terminated before the end of the buffer
    354                                 if (name_size >= NAME_BUFFER_SIZE) {
     343                                if (name_size >= name_buffer_size) {
    355344                                        rc = ENAMETOOLONG;
    356345                                }
    357                                 check_ok_break(rc, "Name too long (limit is %d excluding null-terminator)", NAME_BUFFER_SIZE);
    358                                 // advance pos to after the name of the entry (add 1 for null-terminator)
    359                                 pos += read; // NOLINT(*-narrowing-conversions) because name_size < NAME_BUFFER_SIZE
    360                                 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Listed %d: pos %"PRIdn", name: %s\n", item.handle1, pos, name_buffer);
     346                                check_ok_break(rc, "Name too long (limit is %"PRIdn" excluding null-terminator)", name_buffer_size);
    361347                                // 2.
    362348                                int entry_handle1; // don't forget to put
    363                                 rc = vfs_walk(item.handle1, name_buffer, 0, &entry_handle1);
    364                                 check_ok_break(rc, "(0) Failed to find entry \"%s\" in directory of handle %d\n", name_buffer, item.handle1);
     349                                rc = vfs_walk(item.handle1, dp->d_name, 0, &entry_handle1);
     350                                check_ok_break(rc, "(0) Failed to find entry \"%s\" in directory of handle %d\n", dp->d_name, item.handle1);
    365351                                // 3.
    366352                                int entry_handle2; // must be put
    367                                 rc= vfs_walk(item.handle2, name_buffer, 0, &entry_handle2);
     353                                rc= vfs_walk(item.handle2, dp->d_name, 0, &entry_handle2);
    368354                                if (rc != EOK) {
    369355                                        errno_t rc2 = vfs_put(entry_handle1);
     
    374360                                                break;
    375361                                        }
    376                                         check_ok_break(rc, "(1) Failed to find entry \"%s\" in directory of handle %d\n", name_buffer, item.handle2);
     362                                        check_ok_break(rc, "(1) Failed to find entry \"%s\" in directory of handle %d\n", dp->d_name, item.handle2);
    377363                                }
    378364
     
    388374                                check_ok_break(rc, "Failed to append to stack\n");
    389375                        }
     376                        closedir(dirp);
    390377                        if (rc != EOK) goto close_inner;
    391378                }
     
    401388                }
    402389                if (rc != EOK) goto close_start;
    403         }
    404         assert(rc == EEMPTY);
     390                if (!equal) break;
     391        }
     392        assert(rc == EEMPTY || !equal);
    405393        rc = EOK;
    406394close_start:
Note: See TracChangeset for help on using the changeset viewer.