Stat a path, skipping symlinks. Returns 0 on success, -1 to skip. * On POSIX, lstat + S_ISLNK avoids following symlink cycles. On Windows * we use the UTF-8-safe wide stat (mirroring discover.c's wide_stat); * reparse points (junctions/symlinks) are detected separately by * pkgmap_is_reparse_point below before we descend. Mirrors discover.c's * safe_stat. */
| 1056 | * pkgmap_is_reparse_point below before we descend. Mirrors discover.c's |
| 1057 | * safe_stat. */ |
| 1058 | static int pkgmap_safe_stat(const char *abs_path, struct stat *st) { |
| 1059 | #ifdef _WIN32 |
| 1060 | wchar_t *wpath = cbm_path_to_wide(abs_path); |
| 1061 | if (!wpath) { |
| 1062 | return CBM_NOT_FOUND; |
| 1063 | } |
| 1064 | struct _stat64 wst; |
| 1065 | int ret = _wstat64(wpath, &wst); |
| 1066 | free(wpath); |
| 1067 | if (ret != 0) { |
| 1068 | return CBM_NOT_FOUND; |
| 1069 | } |
| 1070 | st->st_mode = wst.st_mode; |
| 1071 | st->st_size = wst.st_size; |
| 1072 | st->st_mtime = wst.st_mtime; |
| 1073 | return 0; |
| 1074 | #else |
| 1075 | if (lstat(abs_path, st) != 0) { |
| 1076 | return CBM_NOT_FOUND; |
| 1077 | } |
| 1078 | if (S_ISLNK(st->st_mode)) { |
| 1079 | return CBM_NOT_FOUND; |
| 1080 | } |
| 1081 | return 0; |
| 1082 | #endif |
| 1083 | } |
| 1084 | |
| 1085 | /* True if abs_path is a Windows reparse point (directory junction or |
| 1086 | * symlink). Following these is the documented cause of the historic CI |
no test coverage detected