Print mount point. Return zero upon success, nonzero upon failure. */
| 986 | |
| 987 | /* Print mount point. Return zero upon success, nonzero upon failure. */ |
| 988 | NODISCARD |
| 989 | static bool |
| 990 | out_mount_point (char const *filename, char *pformat, size_t prefix_len, |
| 991 | const struct stat *statp) |
| 992 | { |
| 993 | |
| 994 | char const *np = "?", *bp = NULL; |
| 995 | char *mp = NULL; |
| 996 | bool fail = true; |
| 997 | |
| 998 | /* Look for bind mounts first. Note we output the immediate alias, |
| 999 | rather than further resolving to a base device mount point. */ |
| 1000 | if (follow_links || !S_ISLNK (statp->st_mode)) |
| 1001 | { |
| 1002 | char *resolved = canonicalize_file_name (filename); |
| 1003 | if (!resolved) |
| 1004 | { |
| 1005 | error (0, errno, _("failed to canonicalize %s"), quoteaf (filename)); |
| 1006 | goto print_mount_point; |
| 1007 | } |
| 1008 | bp = find_bind_mount (resolved); |
| 1009 | free (resolved); |
| 1010 | if (bp) |
| 1011 | { |
| 1012 | fail = false; |
| 1013 | goto print_mount_point; |
| 1014 | } |
| 1015 | } |
| 1016 | |
| 1017 | /* If there is no direct bind mount, then navigate |
| 1018 | back up the tree looking for a device change. |
| 1019 | Note we don't detect if any of the directory components |
| 1020 | are bind mounted to the same device, but that's OK |
| 1021 | since we've not directly queried them. */ |
| 1022 | if ((mp = find_mount_point (filename, statp))) |
| 1023 | { |
| 1024 | /* This dir might be bind mounted to another device, |
| 1025 | so we resolve the bound source in that case also. */ |
| 1026 | bp = find_bind_mount (mp); |
| 1027 | fail = false; |
| 1028 | } |
| 1029 | |
| 1030 | print_mount_point: |
| 1031 | |
| 1032 | out_string (pformat, prefix_len, bp ? bp : mp ? mp : np); |
| 1033 | free (mp); |
| 1034 | return fail; |
| 1035 | } |
| 1036 | |
| 1037 | /* Map a TS with negative TS.tv_nsec to {0,0}. */ |
| 1038 | static inline struct timespec |
no test coverage detected