]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-fs-util.c
2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "alloc-util.h"
28 #include "path-util.h"
30 #include "string-util.h"
34 static void test_chase_symlinks(void) {
35 _cleanup_free_
char *result
= NULL
;
36 char temp
[] = "/tmp/test-chase.XXXXXX";
37 const char *top
, *p
, *q
;
40 assert_se(mkdtemp(temp
));
42 top
= strjoina(temp
, "/top");
43 assert_se(mkdir(top
, 0700) >= 0);
45 p
= strjoina(top
, "/dot");
46 assert_se(symlink(".", p
) >= 0);
48 p
= strjoina(top
, "/dotdot");
49 assert_se(symlink("..", p
) >= 0);
51 p
= strjoina(top
, "/dotdota");
52 assert_se(symlink("../a", p
) >= 0);
54 p
= strjoina(temp
, "/a");
55 assert_se(symlink("b", p
) >= 0);
57 p
= strjoina(temp
, "/b");
58 assert_se(symlink("/usr", p
) >= 0);
60 p
= strjoina(temp
, "/start");
61 assert_se(symlink("top/dot/dotdota", p
) >= 0);
63 /* Paths that use symlinks underneath the "root" */
65 r
= chase_symlinks(p
, NULL
, 0, &result
);
67 assert_se(path_equal(result
, "/usr"));
69 result
= mfree(result
);
70 r
= chase_symlinks(p
, temp
, 0, &result
);
71 assert_se(r
== -ENOENT
);
73 q
= strjoina(temp
, "/usr");
75 r
= chase_symlinks(p
, temp
, CHASE_NONEXISTENT
, &result
);
77 assert_se(path_equal(result
, q
));
79 assert_se(mkdir(q
, 0700) >= 0);
81 result
= mfree(result
);
82 r
= chase_symlinks(p
, temp
, 0, &result
);
84 assert_se(path_equal(result
, q
));
86 p
= strjoina(temp
, "/slash");
87 assert_se(symlink("/", p
) >= 0);
89 result
= mfree(result
);
90 r
= chase_symlinks(p
, NULL
, 0, &result
);
92 assert_se(path_equal(result
, "/"));
94 result
= mfree(result
);
95 r
= chase_symlinks(p
, temp
, 0, &result
);
97 assert_se(path_equal(result
, temp
));
99 /* Paths that would "escape" outside of the "root" */
101 p
= strjoina(temp
, "/6dots");
102 assert_se(symlink("../../..", p
) >= 0);
104 result
= mfree(result
);
105 r
= chase_symlinks(p
, temp
, 0, &result
);
106 assert_se(r
> 0 && path_equal(result
, temp
));
108 p
= strjoina(temp
, "/6dotsusr");
109 assert_se(symlink("../../../usr", p
) >= 0);
111 result
= mfree(result
);
112 r
= chase_symlinks(p
, temp
, 0, &result
);
113 assert_se(r
> 0 && path_equal(result
, q
));
115 p
= strjoina(temp
, "/top/8dotsusr");
116 assert_se(symlink("../../../../usr", p
) >= 0);
118 result
= mfree(result
);
119 r
= chase_symlinks(p
, temp
, 0, &result
);
120 assert_se(r
> 0 && path_equal(result
, q
));
122 /* Paths that contain repeated slashes */
124 p
= strjoina(temp
, "/slashslash");
125 assert_se(symlink("///usr///", p
) >= 0);
127 result
= mfree(result
);
128 r
= chase_symlinks(p
, NULL
, 0, &result
);
130 assert_se(path_equal(result
, "/usr"));
132 result
= mfree(result
);
133 r
= chase_symlinks(p
, temp
, 0, &result
);
135 assert_se(path_equal(result
, q
));
139 result
= mfree(result
);
140 r
= chase_symlinks("/etc/./.././", NULL
, 0, &result
);
142 assert_se(path_equal(result
, "/"));
144 result
= mfree(result
);
145 r
= chase_symlinks("/etc/./.././", "/etc", 0, &result
);
146 assert_se(r
> 0 && path_equal(result
, "/etc"));
148 result
= mfree(result
);
149 r
= chase_symlinks("/etc/machine-id/foo", NULL
, 0, &result
);
150 assert_se(r
== -ENOTDIR
);
152 /* Path that loops back to self */
154 result
= mfree(result
);
155 p
= strjoina(temp
, "/recursive-symlink");
156 assert_se(symlink("recursive-symlink", p
) >= 0);
157 r
= chase_symlinks(p
, NULL
, 0, &result
);
158 assert_se(r
== -ELOOP
);
160 /* Path which doesn't exist */
162 p
= strjoina(temp
, "/idontexist");
163 r
= chase_symlinks(p
, NULL
, 0, &result
);
164 assert_se(r
== -ENOENT
);
166 r
= chase_symlinks(p
, NULL
, CHASE_NONEXISTENT
, &result
);
168 assert_se(path_equal(result
, p
));
169 result
= mfree(result
);
171 p
= strjoina(temp
, "/idontexist/meneither");
172 r
= chase_symlinks(p
, NULL
, 0, &result
);
173 assert_se(r
== -ENOENT
);
175 r
= chase_symlinks(p
, NULL
, CHASE_NONEXISTENT
, &result
);
177 assert_se(path_equal(result
, p
));
178 result
= mfree(result
);
180 /* Path which doesn't exist, but contains weird stuff */
182 p
= strjoina(temp
, "/idontexist/..");
183 r
= chase_symlinks(p
, NULL
, 0, &result
);
184 assert_se(r
== -ENOENT
);
186 r
= chase_symlinks(p
, NULL
, CHASE_NONEXISTENT
, &result
);
187 assert_se(r
== -ENOENT
);
189 p
= strjoina(temp
, "/target");
190 q
= strjoina(temp
, "/top");
191 assert_se(symlink(q
, p
) >= 0);
192 p
= strjoina(temp
, "/target/idontexist");
193 r
= chase_symlinks(p
, NULL
, 0, &result
);
194 assert_se(r
== -ENOENT
);
196 assert_se(rm_rf(temp
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);
199 static void test_unlink_noerrno(void) {
200 char name
[] = "/tmp/test-close_nointr.XXXXXX";
203 fd
= mkostemp_safe(name
);
205 assert_se(close_nointr(fd
) >= 0);
210 assert_se(unlink_noerrno(name
) >= 0);
211 assert_se(errno
== -42);
212 assert_se(unlink_noerrno(name
) < 0);
213 assert_se(errno
== -42);
217 static void test_readlink_and_make_absolute(void) {
218 char tempdir
[] = "/tmp/test-readlink_and_make_absolute";
219 char name
[] = "/tmp/test-readlink_and_make_absolute/original";
220 char name2
[] = "test-readlink_and_make_absolute/original";
221 char name_alias
[] = "/tmp/test-readlink_and_make_absolute-alias";
224 assert_se(mkdir_safe(tempdir
, 0755, getuid(), getgid()) >= 0);
225 assert_se(touch(name
) >= 0);
227 assert_se(symlink(name
, name_alias
) >= 0);
228 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
229 assert_se(streq(r
, name
));
231 assert_se(unlink(name_alias
) >= 0);
233 assert_se(chdir(tempdir
) >= 0);
234 assert_se(symlink(name2
, name_alias
) >= 0);
235 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
236 assert_se(streq(r
, name
));
238 assert_se(unlink(name_alias
) >= 0);
240 assert_se(rm_rf(tempdir
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);
243 static void test_get_files_in_directory(void) {
244 _cleanup_strv_free_
char **l
= NULL
, **t
= NULL
;
246 assert_se(get_files_in_directory("/tmp", &l
) >= 0);
247 assert_se(get_files_in_directory(".", &t
) >= 0);
248 assert_se(get_files_in_directory(".", NULL
) >= 0);
251 static void test_var_tmp(void) {
252 _cleanup_free_
char *tmpdir_backup
= NULL
, *temp_backup
= NULL
, *tmp_backup
= NULL
;
253 const char *tmp_dir
= NULL
, *t
;
255 t
= getenv("TMPDIR");
257 tmpdir_backup
= strdup(t
);
258 assert_se(tmpdir_backup
);
263 temp_backup
= strdup(t
);
264 assert_se(temp_backup
);
269 tmp_backup
= strdup(t
);
270 assert_se(tmp_backup
);
273 assert(unsetenv("TMPDIR") >= 0);
274 assert(unsetenv("TEMP") >= 0);
275 assert(unsetenv("TMP") >= 0);
277 assert_se(var_tmp_dir(&tmp_dir
) >= 0);
278 assert_se(streq(tmp_dir
, "/var/tmp"));
280 assert_se(setenv("TMPDIR", "/tmp", true) >= 0);
281 assert_se(streq(getenv("TMPDIR"), "/tmp"));
283 assert_se(var_tmp_dir(&tmp_dir
) >= 0);
284 assert_se(streq(tmp_dir
, "/tmp"));
286 assert_se(setenv("TMPDIR", "/88_does_not_exist_88", true) >= 0);
287 assert_se(streq(getenv("TMPDIR"), "/88_does_not_exist_88"));
289 assert_se(var_tmp_dir(&tmp_dir
) >= 0);
290 assert_se(streq(tmp_dir
, "/var/tmp"));
293 assert_se(setenv("TMPDIR", tmpdir_backup
, true) >= 0);
294 assert_se(streq(getenv("TMPDIR"), tmpdir_backup
));
298 assert_se(setenv("TEMP", temp_backup
, true) >= 0);
299 assert_se(streq(getenv("TEMP"), temp_backup
));
303 assert_se(setenv("TMP", tmp_backup
, true) >= 0);
304 assert_se(streq(getenv("TMP"), tmp_backup
));
308 static void test_dot_or_dot_dot(void) {
309 assert_se(!dot_or_dot_dot(NULL
));
310 assert_se(!dot_or_dot_dot(""));
311 assert_se(!dot_or_dot_dot("xxx"));
312 assert_se(dot_or_dot_dot("."));
313 assert_se(dot_or_dot_dot(".."));
314 assert_se(!dot_or_dot_dot(".foo"));
315 assert_se(!dot_or_dot_dot("..foo"));
318 int main(int argc
, char *argv
[]) {
319 test_unlink_noerrno();
320 test_get_files_in_directory();
321 test_readlink_and_make_absolute();
323 test_chase_symlinks();
324 test_dot_or_dot_dot();