]> git.proxmox.com Git - libgit2.git/blob - tests/clar/clar/sandbox.h
New upstream version 1.5.0+ds
[libgit2.git] / tests / clar / clar / sandbox.h
1 #ifdef __APPLE__
2 #include <sys/syslimits.h>
3 #endif
4
5 static char _clar_path[4096 + 1];
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 - 1);
43 buffer[length - 1] = '\0';
44 return 0;
45 }
46 }
47
48 /* If the environment doesn't say anything, try to use /tmp */
49 if (is_valid_tmp_path("/tmp")) {
50 #ifdef __APPLE__
51 if (length >= PATH_MAX && realpath("/tmp", buffer) != NULL)
52 return 0;
53 #endif
54 strncpy(buffer, "/tmp", length - 1);
55 buffer[length - 1] = '\0';
56 return 0;
57 }
58
59 #else
60 DWORD env_len = GetEnvironmentVariable("CLAR_TMP", buffer, (DWORD)length);
61 if (env_len > 0 && env_len < (DWORD)length)
62 return 0;
63
64 if (GetTempPath((DWORD)length, buffer))
65 return 0;
66 #endif
67
68 /* This system doesn't like us, try to use the current directory */
69 if (is_valid_tmp_path(".")) {
70 strncpy(buffer, ".", length - 1);
71 buffer[length - 1] = '\0';
72 return 0;
73 }
74
75 return -1;
76 }
77
78 static void clar_unsandbox(void)
79 {
80 if (_clar_path[0] == '\0')
81 return;
82
83 cl_must_pass(chdir(".."));
84
85 fs_rm(_clar_path);
86 }
87
88 static int build_sandbox_path(void)
89 {
90 #ifdef CLAR_TMPDIR
91 const char path_tail[] = CLAR_TMPDIR "_XXXXXX";
92 #else
93 const char path_tail[] = "clar_tmp_XXXXXX";
94 #endif
95
96 size_t len;
97
98 if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0)
99 return -1;
100
101 len = strlen(_clar_path);
102
103 #ifdef _WIN32
104 { /* normalize path to POSIX forward slashes */
105 size_t i;
106 for (i = 0; i < len; ++i) {
107 if (_clar_path[i] == '\\')
108 _clar_path[i] = '/';
109 }
110 }
111 #endif
112
113 if (_clar_path[len - 1] != '/') {
114 _clar_path[len++] = '/';
115 }
116
117 strncpy(_clar_path + len, path_tail, sizeof(_clar_path) - len);
118
119 #if defined(__MINGW32__)
120 if (_mktemp(_clar_path) == NULL)
121 return -1;
122
123 if (mkdir(_clar_path, 0700) != 0)
124 return -1;
125 #elif defined(_WIN32)
126 if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0)
127 return -1;
128
129 if (mkdir(_clar_path, 0700) != 0)
130 return -1;
131 #else
132 if (mkdtemp(_clar_path) == NULL)
133 return -1;
134 #endif
135
136 return 0;
137 }
138
139 static int clar_sandbox(void)
140 {
141 if (_clar_path[0] == '\0' && build_sandbox_path() < 0)
142 return -1;
143
144 if (chdir(_clar_path) != 0)
145 return -1;
146
147 return 0;
148 }
149
150 const char *clar_sandbox_path(void)
151 {
152 return _clar_path;
153 }
154