Changeset 8c35ebd in mainline
- Timestamp:
- 2026-03-17T12:37:37Z (22 hours ago)
- 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)
- File:
-
- 1 edited
-
uspace/app/cmpdirs/cmpdirs.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/cmpdirs/cmpdirs.c
r128a311 r8c35ebd 35 35 */ 36 36 37 #include <dirent.h> 37 38 #include <getopt.h> 38 39 #include <stdbool.h> … … 51 52 /** When reading the content of a file for comparison, how large should one chunk be. */ 52 53 #define CHUNK_SIZE 0x4000 53 /** File names longer than this will be truncated. */54 #define NAME_BUFFER_SIZE 25655 54 56 55 // Macros to make handling errors less cumbersome … … 212 211 (*entry_out) = s->buffer[s->size]; 213 212 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_buffer217 * 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;227 213 } 228 214 … … 290 276 check_ok(rc, close2, "No memory for file buffer #2 (%d bytes needed)\n", CHUNK_SIZE); 291 277 292 char name_buffer[NAME_BUFFER_SIZE];293 294 278 // While there is something in the stack 295 279 for (struct entry item = {root_handle1, root_handle2}; // initial item … … 341 325 // 4. add both new handles to stack 342 326 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. 351 339 // 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); 353 342 // 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) { 355 344 rc = ENAMETOOLONG; 356 345 } 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); 361 347 // 2. 362 348 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); 365 351 // 3. 366 352 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); 368 354 if (rc != EOK) { 369 355 errno_t rc2 = vfs_put(entry_handle1); … … 374 360 break; 375 361 } 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); 377 363 } 378 364 … … 388 374 check_ok_break(rc, "Failed to append to stack\n"); 389 375 } 376 closedir(dirp); 390 377 if (rc != EOK) goto close_inner; 391 378 } … … 401 388 } 402 389 if (rc != EOK) goto close_start; 403 } 404 assert(rc == EEMPTY); 390 if (!equal) break; 391 } 392 assert(rc == EEMPTY || !equal); 405 393 rc = EOK; 406 394 close_start:
Note:
See TracChangeset
for help on using the changeset viewer.
