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