]>
git.ipfire.org Git - thirdparty/git.git/blob - compat/fsmonitor/fsm-path-utils-darwin.c
2 #include "fsmonitor-path-utils.h"
10 int fsmonitor__get_fs_info(const char *path
, struct fs_info
*fs_info
)
13 if (statfs(path
, &fs
) == -1) {
14 int saved_errno
= errno
;
15 trace_printf_key(&trace_fsmonitor
, "statfs('%s') failed: %s",
16 path
, strerror(saved_errno
));
21 trace_printf_key(&trace_fsmonitor
,
22 "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'",
23 path
, fs
.f_type
, fs
.f_flags
, fs
.f_fstypename
);
25 if (!(fs
.f_flags
& MNT_LOCAL
))
26 fs_info
->is_remote
= 1;
28 fs_info
->is_remote
= 0;
30 fs_info
->typename
= xstrdup(fs
.f_fstypename
);
32 trace_printf_key(&trace_fsmonitor
,
34 path
, fs_info
->is_remote
);
38 int fsmonitor__is_fs_remote(const char *path
)
41 if (fsmonitor__get_fs_info(path
, &fs
))
50 * Scan the root directory for synthetic firmlinks that when resolved
51 * are a prefix of the path, stopping at the first one found.
53 * Some information about firmlinks and synthetic firmlinks:
54 * https://eclecticlight.co/2020/01/23/catalina-boot-volumes/
56 * macOS no longer allows symlinks in the root directory; any link found
57 * there is therefore a synthetic firmlink.
59 * If this function gets called often, will want to cache all the firmlink
60 * information, but for now there is only one caller of this function.
62 * If there is more than one alias for the path, that is another
65 int fsmonitor__get_alias(const char *path
, struct alias_info
*info
)
69 const char *const root
= "/";
73 struct strbuf points_to
= STRBUF_INIT
;
77 return error_errno(_("opendir('%s') failed"), root
);
79 strbuf_init(&alias
, 256);
81 while ((de
= readdir(dir
)) != NULL
) {
83 strbuf_addf(&alias
, "%s%s", root
, de
->d_name
);
85 if (lstat(alias
.buf
, &st
) < 0) {
86 error_errno(_("lstat('%s') failed"), alias
.buf
);
90 if (!S_ISLNK(st
.st_mode
))
93 if (strbuf_readlink(&points_to
, alias
.buf
, st
.st_size
) < 0) {
94 error_errno(_("strbuf_readlink('%s') failed"), alias
.buf
);
98 if (!strncmp(points_to
.buf
, path
, points_to
.len
) &&
99 (path
[points_to
.len
] == '/')) {
100 strbuf_addbuf(&info
->alias
, &alias
);
101 strbuf_addbuf(&info
->points_to
, &points_to
);
102 trace_printf_key(&trace_fsmonitor
,
103 "Found alias for '%s' : '%s' -> '%s'",
104 path
, info
->alias
.buf
, info
->points_to
.buf
);
109 retval
= 0; /* no alias */
112 strbuf_release(&alias
);
113 strbuf_release(&points_to
);
114 if (closedir(dir
) < 0)
115 return error_errno(_("closedir('%s') failed"), root
);
119 char *fsmonitor__resolve_alias(const char *path
,
120 const struct alias_info
*info
)
122 if (!info
->alias
.len
)
125 if ((!strncmp(info
->alias
.buf
, path
, info
->alias
.len
))
126 && path
[info
->alias
.len
] == '/') {
127 struct strbuf tmp
= STRBUF_INIT
;
128 const char *remainder
= path
+ info
->alias
.len
;
130 strbuf_addbuf(&tmp
, &info
->points_to
);
131 strbuf_add(&tmp
, remainder
, strlen(remainder
));
132 return strbuf_detach(&tmp
, NULL
);