Returns 0 on successful rename, 1 if we successfully copied the file * across filesystems, -2 if copy_file() failed, and -1 on other errors. * If partialptr is not NULL and we need to do a copy, copy the file into * the active partial-dir instead of over the destination file. */
| 545 | * If partialptr is not NULL and we need to do a copy, copy the file into |
| 546 | * the active partial-dir instead of over the destination file. */ |
| 547 | int robust_rename(const char *from, const char *to, const char *partialptr, |
| 548 | int mode) |
| 549 | { |
| 550 | int tries = 4; |
| 551 | |
| 552 | /* A resumed in-place partial-dir transfer might call us with from and |
| 553 | * to pointing to the same buf if the transfer failed yet again. */ |
| 554 | if (from == to) |
| 555 | return 0; |
| 556 | |
| 557 | while (tries--) { |
| 558 | if (do_rename_at(from, to) == 0) |
| 559 | return 0; |
| 560 | |
| 561 | switch (errno) { |
| 562 | #ifdef ETXTBSY |
| 563 | case ETXTBSY: |
| 564 | if (robust_unlink(to) != 0) { |
| 565 | errno = ETXTBSY; |
| 566 | return -1; |
| 567 | } |
| 568 | errno = ETXTBSY; |
| 569 | break; |
| 570 | #endif |
| 571 | case EXDEV: |
| 572 | if (partialptr) { |
| 573 | if (!handle_partial_dir(partialptr,PDIR_CREATE)) |
| 574 | return -2; |
| 575 | to = partialptr; |
| 576 | } |
| 577 | if (copy_file(from, to, -1, mode) != 0) |
| 578 | return -2; |
| 579 | do_unlink_at(from); |
| 580 | return 1; |
| 581 | default: |
| 582 | return -1; |
| 583 | } |
| 584 | } |
| 585 | return -1; |
| 586 | } |
| 587 | |
| 588 | static pid_t all_pids[10]; |
| 589 | static int num_pids; |
no test coverage detected