Changeset 74c69dc in mainline for uspace/app/cmpdirs/cmpdirs.c
- Timestamp:
- 2026-03-17T12:43:08Z (28 hours ago)
- Children:
- 4a0bfcf0
- Parents:
- b017885
- File:
-
- 1 edited
-
uspace/app/cmpdirs/cmpdirs.c (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/cmpdirs/cmpdirs.c
rb017885 r74c69dc 64 64 /** Returns true if all directories and files in the filesystem tree of handle1 also exist in the filesystem tree of 65 65 * handle2 and in reverse and all their contents and metadata is equal. 66 * hande1 and handle2 are handles to a directory (or file). */ 67 static errno_t trees_equal(int handle1, int handle2, bool* equal_out); 66 * hande1 and handle2 are handles to a directory (or file). 67 */ 68 static errno_t trees_equal(int handle1, int handle2, bool *equal_out); 68 69 69 70 int main(int argc, char *argv[]) … … 109 110 // initialize logging 110 111 rc = log_init(NAME); 111 if (rc != EOK) goto close_end; 112 if (rc != EOK) 113 goto close_end; 112 114 logctl_set_log_level(NAME, LVL_DEBUG2); 113 115 … … 124 126 bool equal; 125 127 rc = trees_equal(handle1, handle2, &equal); 126 if (rc != EOK) goto close2; 128 if (rc != EOK) 129 goto close2; 127 130 close2: 128 131 vfs_put(handle2); … … 132 135 133 136 if (rc != EOK) { 134 fprintf(stderr, "%d\n", rc);137 fprintf(stderr, "%d\n", rc); 135 138 fprintf(stderr, "An error occurred: %s: %s\n", str_error_name(rc), str_error(rc)); 136 139 return 2; … … 159 162 160 163 /** Create a new growable stack. Don't forget to free it using stack_free when you are done using it. */ 161 static errno_t stack_new(struct stack* s) { 164 static errno_t stack_new(struct stack *s) 165 { 162 166 s->size = 0; 163 167 s->capacity = STACK_INIT_CAPACITY; … … 170 174 171 175 /** Destroy a growable stack and free its memory */ 172 static void stack_free(struct stack* s) { 176 static void stack_free(struct stack *s) 177 { 173 178 if (s->buffer != NULL) { 174 179 free(s->buffer); … … 180 185 181 186 /** Append an entry to the stack. Allocates larger memory if needed. */ 182 static errno_t stack_append(struct stack *s, struct entry e) { 187 static errno_t stack_append(struct stack *s, struct entry e) 188 { 183 189 if (s->capacity == 0 || s->buffer == NULL) { 184 190 // stack has already been freed before … … 204 210 205 211 /** Returns the last entry in the stack and removes it from it. Does not free any memory. */ 206 static errno_t stack_pop(struct stack *s, struct entry *entry_out) { 212 static errno_t stack_pop(struct stack *s, struct entry *entry_out) 213 { 207 214 if (s->size == 0) { 208 215 return EEMPTY; … … 214 221 215 222 /** Compares two vfs_stat_t structures in the sense that they represent the same data possibly across different filesystems. */ 216 static bool stat_equal(vfs_stat_t a, vfs_stat_t b) { 223 static bool stat_equal(vfs_stat_t a, vfs_stat_t b) 224 { 217 225 return a.is_file == b.is_file && 218 a.is_directory == b.is_directory &&219 a.size == b.size;226 a.is_directory == b.is_directory && 227 a.size == b.size; 220 228 } 221 229 … … 224 232 * - both files have the same size 225 233 * - both buffers are the size CHUNK_SIZE 226 * - both handles are open for reading */ 227 static errno_t content_equal(int handle1, vfs_stat_t stat1, char* buffer1, int handle2, vfs_stat_t stat2, char* buffer2, bool *equal_out) { 234 * - both handles are open for reading 235 */ 236 static errno_t content_equal(int handle1, vfs_stat_t stat1, char *buffer1, int handle2, vfs_stat_t stat2, char *buffer2, bool *equal_out) 237 { 228 238 errno_t rc = EOK; 229 239 bool equal = true; … … 254 264 } 255 265 256 static errno_t trees_equal(int root_handle1, int root_handle2, bool* equal_out) { 266 static errno_t trees_equal(int root_handle1, int root_handle2, bool *equal_out) 267 { 257 268 // todo Check once again that all file handles are put at the end 258 269 // Performs a depth-first search on handle1 and compares it to handle2. … … 269 280 270 281 char *file_buffer1 = malloc(CHUNK_SIZE); 271 if (file_buffer1 == NULL) rc = ENOMEM; 282 if (file_buffer1 == NULL) 283 rc = ENOMEM; 272 284 check_ok(rc, close1, "No memory for file buffer #1 (%d bytes needed)\n", CHUNK_SIZE); 273 285 274 286 char *file_buffer2 = malloc(CHUNK_SIZE); 275 if (file_buffer2 == NULL) rc = ENOMEM; 287 if (file_buffer2 == NULL) 288 rc = ENOMEM; 276 289 check_ok(rc, close2, "No memory for file buffer #2 (%d bytes needed)\n", CHUNK_SIZE); 277 290 278 291 // While there is something in the stack 279 for (struct entry item = {root_handle1, root_handle2}; // initial item 280 rc != EEMPTY; // was pop successful? 281 rc = stack_pop(&s, &item) 282 ) { 292 for (struct entry item = { root_handle1, root_handle2 }; // initial item 293 rc != EEMPTY; // was pop successful? 294 rc = stack_pop(&s, &item)) { 283 295 if (rc != EOK) { 284 296 // other error than EEMPTY … … 315 327 bool equal2; 316 328 rc = content_equal(item.handle1, stat1, file_buffer1, item.handle2, stat2, file_buffer2, &equal2); 317 if (rc != EOK) goto close_inner; 329 if (rc != EOK) 330 goto close_inner; 318 331 equal = equal && equal2; 319 } else {332 } else { 320 333 // check directory listing and add its items to the stack 321 334 … … 344 357 rc = ENAMETOOLONG; 345 358 } 346 check_ok_break(rc, "Name too long (limit is %" PRIdn" excluding null-terminator)", name_buffer_size);359 check_ok_break(rc, "Name too long (limit is %" PRIdn " excluding null-terminator)", name_buffer_size); 347 360 // add slash to the beginning of the name, because vfs_walk requires the path to be absolute (will be 348 361 // resolved relatively to the starting directory) 349 char name_with_slash[name_buffer_size +1];362 char name_with_slash[name_buffer_size + 1]; 350 363 name_with_slash[0] = '/'; 351 364 str_cpy(name_with_slash + 1, name_size + 1, dp->d_name); … … 356 369 // 3. 357 370 int entry_handle2; // must be put 358 rc = vfs_walk(item.handle2, name_with_slash, 0, &entry_handle2);371 rc = vfs_walk(item.handle2, name_with_slash, 0, &entry_handle2); 359 372 if (rc != EOK) { 360 373 errno_t rc2 = vfs_put(entry_handle1); … … 369 382 370 383 // 4. 371 struct entry newitem = { entry_handle1, entry_handle2};384 struct entry newitem = { entry_handle1, entry_handle2 }; 372 385 rc = stack_append(&s, newitem); 373 386 if (rc != EOK) { … … 380 393 } 381 394 closedir(dirp); 382 if (rc != EOK) goto close_inner; 395 if (rc != EOK) 396 goto close_inner; 383 397 } 384 398 … … 392 406 (void) rc2; // if put failed, I guess there is nothing I can do about it 393 407 } 394 if (rc != EOK) goto close_start; 395 if (!equal) break; 408 if (rc != EOK) 409 goto close_start; 410 if (!equal) 411 break; 396 412 } 397 413 assert(rc == EEMPTY || !equal); … … 404 420 close1: 405 421 (void) 0; // Clangd is not happy about declaration right after a label, so here is a dummy statement. 406 struct entry item = { };422 struct entry item = { }; 407 423 for (errno_t for_rc = stack_pop(&s, &item); 408 for_rc != EEMPTY; // was pop successful?409 for_rc = stack_pop(&s, &item)){410 errno_t rc2 = vfs_put(item.handle1);411 (void) rc2; // if put failed, I guess there is nothing I can do about it412 rc2 = vfs_put(item.handle2);413 (void) rc2; // if put failed, I guess there is nothing I can do about it424 for_rc != EEMPTY; // was pop successful? 425 for_rc = stack_pop(&s, &item)) { 426 errno_t rc2 = vfs_put(item.handle1); 427 (void) rc2; // if put failed, I guess there is nothing I can do about it 428 rc2 = vfs_put(item.handle2); 429 (void) rc2; // if put failed, I guess there is nothing I can do about it 414 430 } 415 431 416 432 stack_free(&s); 417 433 close_end: 418 if (rc == EOK) *equal_out = equal; 434 if (rc == EOK) 435 *equal_out = equal; 419 436 return rc; 420 437 } 421 422 438 423 439 static void print_usage(void)
Note:
See TracChangeset
for help on using the changeset viewer.
