1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include "alloc-util.h"
28 //#include "path-util.h"
29 //#include "process-util.h"
30 #include "random-util.h"
31 #include "string-util.h"
34 static void test_close_many(void) {
36 char name0[] = "/tmp/test-close-many.XXXXXX";
37 char name1[] = "/tmp/test-close-many.XXXXXX";
38 char name2[] = "/tmp/test-close-many.XXXXXX";
40 fds[0] = mkostemp_safe(name0);
41 fds[1] = mkostemp_safe(name1);
42 fds[2] = mkostemp_safe(name2);
46 assert_se(fcntl(fds[0], F_GETFD) == -1);
47 assert_se(fcntl(fds[1], F_GETFD) == -1);
48 assert_se(fcntl(fds[2], F_GETFD) >= 0);
57 static void test_close_nointr(void) {
58 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
61 fd = mkostemp_safe(name);
63 assert_se(close_nointr(fd) >= 0);
64 assert_se(close_nointr(fd) < 0);
69 #if 0 /// UNNEEDED by elogind
70 static void test_same_fd(void) {
71 _cleanup_close_pair_ int p[2] = { -1, -1 };
72 _cleanup_close_ int a = -1, b = -1, c = -1;
74 assert_se(pipe2(p, O_CLOEXEC) >= 0);
75 assert_se((a = dup(p[0])) >= 0);
76 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
77 assert_se((c = dup(a)) >= 0);
79 assert_se(same_fd(p[0], p[0]) > 0);
80 assert_se(same_fd(p[1], p[1]) > 0);
81 assert_se(same_fd(a, a) > 0);
82 assert_se(same_fd(b, b) > 0);
84 assert_se(same_fd(a, p[0]) > 0);
85 assert_se(same_fd(p[0], a) > 0);
86 assert_se(same_fd(c, p[0]) > 0);
87 assert_se(same_fd(p[0], c) > 0);
88 assert_se(same_fd(a, c) > 0);
89 assert_se(same_fd(c, a) > 0);
91 assert_se(same_fd(p[0], p[1]) == 0);
92 assert_se(same_fd(p[1], p[0]) == 0);
93 assert_se(same_fd(p[0], b) == 0);
94 assert_se(same_fd(b, p[0]) == 0);
95 assert_se(same_fd(p[1], a) == 0);
96 assert_se(same_fd(a, p[1]) == 0);
97 assert_se(same_fd(p[1], b) == 0);
98 assert_se(same_fd(b, p[1]) == 0);
100 assert_se(same_fd(a, b) == 0);
101 assert_se(same_fd(b, a) == 0);
105 static void test_open_serialization_fd(void) {
106 _cleanup_close_ int fd = -1;
108 fd = open_serialization_fd("test");
111 assert_se(write(fd, "test\n", 5) == 5);
114 static void test_acquire_data_fd_one(unsigned flags) {
115 char wbuffer[196*1024 - 7];
116 char rbuffer[sizeof(wbuffer)];
119 fd = acquire_data_fd("foo", 3, flags);
123 assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 3);
124 assert_se(streq(rbuffer, "foo"));
128 fd = acquire_data_fd("", 0, flags);
132 assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 0);
133 assert_se(streq(rbuffer, ""));
137 random_bytes(wbuffer, sizeof(wbuffer));
139 fd = acquire_data_fd(wbuffer, sizeof(wbuffer), flags);
143 assert_se(read(fd, rbuffer, sizeof(rbuffer)) == sizeof(rbuffer));
144 assert_se(memcmp(rbuffer, wbuffer, sizeof(rbuffer)) == 0);
149 static void test_acquire_data_fd(void) {
151 test_acquire_data_fd_one(0);
152 test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL);
153 test_acquire_data_fd_one(ACQUIRE_NO_MEMFD);
154 test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD);
155 test_acquire_data_fd_one(ACQUIRE_NO_PIPE);
156 test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_PIPE);
157 test_acquire_data_fd_one(ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
158 test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
159 test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE|ACQUIRE_NO_TMPFILE);
162 static void test_fd_move_above_stdio(void) {
163 int original_stdin, new_fd;
165 original_stdin = fcntl(0, F_DUPFD, 3);
166 assert_se(original_stdin >= 3);
167 assert_se(close_nointr(0) != EBADF);
169 new_fd = open("/dev/null", O_RDONLY);
170 assert_se(new_fd == 0);
172 new_fd = fd_move_above_stdio(new_fd);
173 assert_se(new_fd >= 3);
175 assert_se(dup(original_stdin) == 0);
176 assert_se(close_nointr(original_stdin) != EBADF);
177 assert_se(close_nointr(new_fd) != EBADF);
180 static void test_rearrange_stdio(void) {
184 r = safe_fork("rearrange", FORK_WAIT|FORK_LOG, &pid);
188 _cleanup_free_ char *path = NULL;
193 safe_close(STDERR_FILENO); /* Let's close an fd < 2, to make it more interesting */
195 assert_se(rearrange_stdio(-1, -1, -1) >= 0);
197 assert_se(fd_get_path(STDIN_FILENO, &path) >= 0);
198 assert_se(path_equal(path, "/dev/null"));
201 assert_se(fd_get_path(STDOUT_FILENO, &path) >= 0);
202 assert_se(path_equal(path, "/dev/null"));
205 assert_se(fd_get_path(STDOUT_FILENO, &path) >= 0);
206 assert_se(path_equal(path, "/dev/null"));
209 safe_close(STDIN_FILENO);
210 safe_close(STDOUT_FILENO);
211 safe_close(STDERR_FILENO);
215 assert_se(pipe(pair) >= 0);
216 assert_se(pair[0] == 0);
217 assert_se(pair[1] == 1);
218 assert_se(fd_move_above_stdio(0) == 3);
220 assert_se(open("/dev/full", O_WRONLY|O_CLOEXEC) == 0);
221 assert_se(acquire_data_fd("foobar", 6, 0) == 2);
223 assert_se(rearrange_stdio(2, 0, 1) >= 0);
225 assert_se(write(1, "x", 1) < 0 && errno == ENOSPC);
226 assert_se(write(2, "z", 1) == 1);
227 assert_se(read(3, buffer, sizeof(buffer)) == 1);
228 assert_se(buffer[0] == 'z');
229 assert_se(read(0, buffer, sizeof(buffer)) == 6);
230 assert_se(memcmp(buffer, "foobar", 6) == 0);
232 assert_se(rearrange_stdio(-1, 1, 2) >= 0);
233 assert_se(write(1, "a", 1) < 0 && errno == ENOSPC);
234 assert_se(write(2, "y", 1) == 1);
235 assert_se(read(3, buffer, sizeof(buffer)) == 1);
236 assert_se(buffer[0] == 'y');
238 assert_se(fd_get_path(0, &path) >= 0);
239 assert_se(path_equal(path, "/dev/null"));
246 int main(int argc, char *argv[]) {
249 #if 0 /// UNNEEDED by elogind
252 test_open_serialization_fd();
253 test_acquire_data_fd();
254 test_fd_move_above_stdio();
255 test_rearrange_stdio();