| 599 | } |
| 600 | |
| 601 | int ResolvePath(const char* rel, const char* abs, char res[/*MAXPATHLEN*/], bool isdir) { |
| 602 | char t[MAXPATHLEN * 2 + 3]; |
| 603 | size_t len; |
| 604 | |
| 605 | *res = 0; |
| 606 | if (!rel || !*rel) { |
| 607 | return EINVAL; |
| 608 | } |
| 609 | if (!IsAbsolutePath(rel) && IsAbsolutePath(abs)) { |
| 610 | len = strlcpy(t, abs, sizeof(t)); |
| 611 | if (len >= sizeof(t) - 3) { |
| 612 | return EINVAL; |
| 613 | } |
| 614 | if (t[len - 1] != LOCSLASH_C) { |
| 615 | t[len++] = LOCSLASH_C; |
| 616 | } |
| 617 | len += strlcpy(t + len, rel, sizeof(t) - len); |
| 618 | } else { |
| 619 | len = strlcpy(t, rel, sizeof(t)); |
| 620 | } |
| 621 | if (len >= sizeof(t) - 3) { |
| 622 | return EINVAL; |
| 623 | } |
| 624 | if (isdir && t[len - 1] != LOCSLASH_C) { |
| 625 | t[len++] = LOCSLASH_C; |
| 626 | t[len] = 0; |
| 627 | } |
| 628 | if (!realpath(t, res)) { |
| 629 | if (!isdir && realpath(GetDirName(t).data(), res)) { |
| 630 | len = strlen(res); |
| 631 | if (res[len - 1] != LOCSLASH_C) { |
| 632 | res[len++] = LOCSLASH_C; |
| 633 | res[len] = 0; |
| 634 | } |
| 635 | strcpy(res + len, GetBaseName(t).data()); |
| 636 | return 0; |
| 637 | } |
| 638 | return errno ? errno : ENOENT; |
| 639 | } |
| 640 | if (isdir) { |
| 641 | len = strlen(res); |
| 642 | if (res[len - 1] != LOCSLASH_C) { |
| 643 | res[len++] = LOCSLASH_C; |
| 644 | res[len] = 0; |
| 645 | } |
| 646 | } |
| 647 | return 0; |
| 648 | } |
| 649 | |
| 650 | TString ResolvePath(const char* rel, const char* abs, bool isdir) { |
| 651 | char buf[PATH_MAX]; |
no test coverage detected