git

Форк
0
/
fsm-path-utils-darwin.c 
138 строк · 3.4 Кб
1
#include "git-compat-util.h"
2
#include "fsmonitor-ll.h"
3
#include "fsmonitor-path-utils.h"
4
#include "gettext.h"
5
#include "trace.h"
6
#include <dirent.h>
7
#include <errno.h>
8
#include <fcntl.h>
9
#include <sys/param.h>
10
#include <sys/mount.h>
11

12
int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info)
13
{
14
	struct statfs fs;
15
	if (statfs(path, &fs) == -1) {
16
		int saved_errno = errno;
17
		trace_printf_key(&trace_fsmonitor, "statfs('%s') failed: %s",
18
				 path, strerror(saved_errno));
19
		errno = saved_errno;
20
		return -1;
21
	}
22

23
	trace_printf_key(&trace_fsmonitor,
24
			 "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'",
25
			 path, fs.f_type, fs.f_flags, fs.f_fstypename);
26

27
	if (!(fs.f_flags & MNT_LOCAL))
28
		fs_info->is_remote = 1;
29
	else
30
		fs_info->is_remote = 0;
31

32
	fs_info->typename = xstrdup(fs.f_fstypename);
33

34
	trace_printf_key(&trace_fsmonitor,
35
				"'%s' is_remote: %d",
36
				path, fs_info->is_remote);
37
	return 0;
38
}
39

40
int fsmonitor__is_fs_remote(const char *path)
41
{
42
	struct fs_info fs;
43
	if (fsmonitor__get_fs_info(path, &fs))
44
		return -1;
45

46
	free(fs.typename);
47

48
	return fs.is_remote;
49
}
50

51
/*
52
 * Scan the root directory for synthetic firmlinks that when resolved
53
 * are a prefix of the path, stopping at the first one found.
54
 *
55
 * Some information about firmlinks and synthetic firmlinks:
56
 * https://eclecticlight.co/2020/01/23/catalina-boot-volumes/
57
 *
58
 * macOS no longer allows symlinks in the root directory; any link found
59
 * there is therefore a synthetic firmlink.
60
 *
61
 * If this function gets called often, will want to cache all the firmlink
62
 * information, but for now there is only one caller of this function.
63
 *
64
 * If there is more than one alias for the path, that is another
65
 * matter altogether.
66
 */
67
int fsmonitor__get_alias(const char *path, struct alias_info *info)
68
{
69
	DIR *dir;
70
	int retval = -1;
71
	const char *const root = "/";
72
	struct stat st;
73
	struct dirent *de;
74
	struct strbuf alias;
75
	struct strbuf points_to = STRBUF_INIT;
76

77
	dir = opendir(root);
78
	if (!dir)
79
		return error_errno(_("opendir('%s') failed"), root);
80

81
	strbuf_init(&alias, 256);
82

83
	while ((de = readdir(dir)) != NULL) {
84
		strbuf_reset(&alias);
85
		strbuf_addf(&alias, "%s%s", root, de->d_name);
86

87
		if (lstat(alias.buf, &st) < 0) {
88
			error_errno(_("lstat('%s') failed"), alias.buf);
89
			goto done;
90
		}
91

92
		if (!S_ISLNK(st.st_mode))
93
			continue;
94

95
		if (strbuf_readlink(&points_to, alias.buf, st.st_size) < 0) {
96
			error_errno(_("strbuf_readlink('%s') failed"), alias.buf);
97
			goto done;
98
		}
99

100
		if (!strncmp(points_to.buf, path, points_to.len) &&
101
			(path[points_to.len] == '/')) {
102
			strbuf_addbuf(&info->alias, &alias);
103
			strbuf_addbuf(&info->points_to, &points_to);
104
			trace_printf_key(&trace_fsmonitor,
105
				"Found alias for '%s' : '%s' -> '%s'",
106
				path, info->alias.buf, info->points_to.buf);
107
			retval = 0;
108
			goto done;
109
		}
110
	}
111
	retval = 0; /* no alias */
112

113
done:
114
	strbuf_release(&alias);
115
	strbuf_release(&points_to);
116
	if (closedir(dir) < 0)
117
		return error_errno(_("closedir('%s') failed"), root);
118
	return retval;
119
}
120

121
char *fsmonitor__resolve_alias(const char *path,
122
	const struct alias_info *info)
123
{
124
	if (!info->alias.len)
125
		return NULL;
126

127
	if ((!strncmp(info->alias.buf, path, info->alias.len))
128
		&& path[info->alias.len] == '/') {
129
		struct strbuf tmp = STRBUF_INIT;
130
		const char *remainder = path + info->alias.len;
131

132
		strbuf_addbuf(&tmp, &info->points_to);
133
		strbuf_add(&tmp, remainder, strlen(remainder));
134
		return strbuf_detach(&tmp, NULL);
135
	}
136

137
	return NULL;
138
}
139

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.