]> git.proxmox.com Git - libgit2.git/blob - tests/clar/sandbox.h
2114819e4e77493bf0cf36952dc9883c3b4fea64
[libgit2.git] / tests / clar / sandbox.h
1 #ifdef __APPLE__
2 #include <sys/syslimits.h>
3 #endif
4
5 static char _clar_path[4096];
6
7 static int
8 is_valid_tmp_path(const char *path)
9 {
10 STAT_T st;
11
12 if (stat(path, &st) != 0)
13 return 0;
14
15 if (!S_ISDIR(st.st_mode))
16 return 0;
17
18 return (access(path, W_OK) == 0);
19 }
20
21 static int
22 find_tmp_path(char *buffer, size_t length)
23 {
24 #ifndef _WIN32
25 static const size_t var_count = 5;
26 static const char *env_vars[] = {
27 "CLAR_TMP", "TMPDIR", "TMP", "TEMP", "USERPROFILE"
28 };
29
30 size_t i;
31
32 for (i = 0; i < var_count; ++i) {
33 const char *env = getenv(env_vars[i]);
34 if (!env)
35 continue;
36
37 if (is_valid_tmp_path(env)) {
38 #ifdef __APPLE__
39 if (length >= PATH_MAX && realpath(env, buffer) != NULL)
40 return 0;
41 #endif
42 strncpy(buffer, env, length);
43 return 0;
44 }
45 }
46
47 /* If the environment doesn't say anything, try to use /tmp */
48 if (is_valid_tmp_path("/tmp")) {
49 #ifdef __APPLE__
50 if (length >= PATH_MAX && realpath("/tmp", buffer) != NULL)
51 return 0;
52 #endif
53 strncpy(buffer, "/tmp", length);
54 return 0;
55 }
56
57 #else
58 DWORD env_len = GetEnvironmentVariable("CLAR_TMP", buffer, (DWORD)length);
59 if (env_len > 0 && env_len < (DWORD)length)
60 return 0;
61
62 if (GetTempPath((DWORD)length, buffer))
63 return 0;
64 #endif
65
66 /* This system doesn't like us, try to use the current directory */
67 if (is_valid_tmp_path(".")) {
68 strncpy(buffer, ".", length);
69 return 0;
70 }
71
72 return -1;
73 }
74
75 static void clar_unsandbox(void)
76 {
77 if (_clar_path[0] == '\0')
78 return;
79
80 cl_must_pass(chdir(".."));
81
82 fs_rm(_clar_path);
83 }
84
85 static int build_sandbox_path(void)
86 {
87 #ifdef CLAR_TMPDIR
88 const char path_tail[] = CLAR_TMPDIR "_XXXXXX";
89 #else
90 const char path_tail[] = "clar_tmp_XXXXXX";
91 #endif
92
93 size_t len;
94
95 if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0)
96 return -1;
97
98 len = strlen(_clar_path);
99
100 #ifdef _WIN32
101 { /* normalize path to POSIX forward slashes */
102 size_t i;
103 for (i = 0; i < len; ++i) {
104 if (_clar_path[i] == '\\')
105 _clar_path[i] = '/';
106 }
107 }
108 #endif
109
110 if (_clar_path[len - 1] != '/') {
111 _clar_path[len++] = '/';
112 }
113
114 strncpy(_clar_path + len, path_tail, sizeof(_clar_path) - len);
115
116 #if defined(__MINGW32__)
117 if (_mktemp(_clar_path) == NULL)
118 return -1;
119
120 if (mkdir(_clar_path, 0700) != 0)
121 return -1;
122 #elif defined(_WIN32)
123 if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0)
124 return -1;
125
126 if (mkdir(_clar_path, 0700) != 0)
127 return -1;
128 #else
129 if (mkdtemp(_clar_path) == NULL)
130 return -1;
131 #endif
132
133 return 0;
134 }
135
136 static int clar_sandbox(void)
137 {
138 if (_clar_path[0] == '\0' && build_sandbox_path() < 0)
139 return -1;
140
141 if (chdir(_clar_path) != 0)
142 return -1;
143
144 return 0;
145 }
146
147 const char *clar_sandbox_path(void)
148 {
149 return _clar_path;
150 }
151