]>
git.ipfire.org Git - thirdparty/git.git/blob - compat/fsmonitor/fsm-path-utils-darwin.c
2 #include "fsmonitor-path-utils.h"
9 int fsmonitor__get_fs_info(const char *path
, struct fs_info
*fs_info
)
12 if (statfs(path
, &fs
) == -1) {
13 int saved_errno
= errno
;
14 trace_printf_key(&trace_fsmonitor
, "statfs('%s') failed: %s",
15 path
, strerror(saved_errno
));
20 trace_printf_key(&trace_fsmonitor
,
21 "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'",
22 path
, fs
.f_type
, fs
.f_flags
, fs
.f_fstypename
);
24 if (!(fs
.f_flags
& MNT_LOCAL
))
25 fs_info
->is_remote
= 1;
27 fs_info
->is_remote
= 0;
29 fs_info
->typename
= xstrdup(fs
.f_fstypename
);
31 trace_printf_key(&trace_fsmonitor
,
33 path
, fs_info
->is_remote
);
37 int fsmonitor__is_fs_remote(const char *path
)
40 if (fsmonitor__get_fs_info(path
, &fs
))
49 * Scan the root directory for synthetic firmlinks that when resolved
50 * are a prefix of the path, stopping at the first one found.
52 * Some information about firmlinks and synthetic firmlinks:
53 * https://eclecticlight.co/2020/01/23/catalina-boot-volumes/
55 * macOS no longer allows symlinks in the root directory; any link found
56 * there is therefore a synthetic firmlink.
58 * If this function gets called often, will want to cache all the firmlink
59 * information, but for now there is only one caller of this function.
61 * If there is more than one alias for the path, that is another
64 int fsmonitor__get_alias(const char *path
, struct alias_info
*info
)
68 const char *const root
= "/";
72 struct strbuf points_to
= STRBUF_INIT
;
76 return error_errno(_("opendir('%s') failed"), root
);
78 strbuf_init(&alias
, 256);
80 while ((de
= readdir(dir
)) != NULL
) {
82 strbuf_addf(&alias
, "%s%s", root
, de
->d_name
);
84 if (lstat(alias
.buf
, &st
) < 0) {
85 error_errno(_("lstat('%s') failed"), alias
.buf
);
89 if (!S_ISLNK(st
.st_mode
))
92 if (strbuf_readlink(&points_to
, alias
.buf
, st
.st_size
) < 0) {
93 error_errno(_("strbuf_readlink('%s') failed"), alias
.buf
);
97 if (!strncmp(points_to
.buf
, path
, points_to
.len
) &&
98 (path
[points_to
.len
] == '/')) {
99 strbuf_addbuf(&info
->alias
, &alias
);
100 strbuf_addbuf(&info
->points_to
, &points_to
);
101 trace_printf_key(&trace_fsmonitor
,
102 "Found alias for '%s' : '%s' -> '%s'",
103 path
, info
->alias
.buf
, info
->points_to
.buf
);
108 retval
= 0; /* no alias */
111 strbuf_release(&alias
);
112 strbuf_release(&points_to
);
113 if (closedir(dir
) < 0)
114 return error_errno(_("closedir('%s') failed"), root
);
118 char *fsmonitor__resolve_alias(const char *path
,
119 const struct alias_info
*info
)
121 if (!info
->alias
.len
)
124 if ((!strncmp(info
->alias
.buf
, path
, info
->alias
.len
))
125 && path
[info
->alias
.len
] == '/') {
126 struct strbuf tmp
= STRBUF_INIT
;
127 const char *remainder
= path
+ info
->alias
.len
;
129 strbuf_addbuf(&tmp
, &info
->points_to
);
130 strbuf_add(&tmp
, remainder
, strlen(remainder
));
131 return strbuf_detach(&tmp
, NULL
);