]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/test-udev-spawn.c
Merge pull request #34549 from weblate/weblate-systemd-main
[thirdparty/systemd.git] / src / udev / test-udev-spawn.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "mountpoint-util.h"
4 #include "path-util.h"
5 #include "signal-util.h"
6 #include "strv.h"
7 #include "tests.h"
8 #include "udev-event.h"
9 #include "udev-spawn.h"
10
11 #define BUF_SIZE 1024
12
13 static void test_event_spawn_core(bool with_pidfd, const char *cmd, char *result_buf, size_t buf_size) {
14 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
15 _cleanup_(udev_event_freep) UdevEvent *event = NULL;
16
17 assert_se(setenv("SYSTEMD_PIDFD", yes_no(with_pidfd), 1) >= 0);
18
19 assert_se(sd_device_new_from_syspath(&dev, "/sys/class/net/lo") >= 0);
20 assert_se(event = udev_event_new(dev, NULL, EVENT_TEST_SPAWN));
21 assert_se(udev_event_spawn(event, false, cmd, result_buf, buf_size, NULL) == 0);
22
23 assert_se(unsetenv("SYSTEMD_PIDFD") >= 0);
24 }
25
26 static void test_event_spawn_cat(bool with_pidfd, size_t buf_size) {
27 _cleanup_strv_free_ char **lines = NULL;
28 _cleanup_free_ char *cmd = NULL;
29 char result_buf[BUF_SIZE];
30
31 log_debug("/* %s(%s) */", __func__, yes_no(with_pidfd));
32
33 assert_se(find_executable("cat", &cmd) >= 0);
34 assert_se(strextend_with_separator(&cmd, " ", "/sys/class/net/lo/uevent"));
35
36 test_event_spawn_core(with_pidfd, cmd, result_buf,
37 buf_size >= BUF_SIZE ? BUF_SIZE : buf_size);
38
39 assert_se(lines = strv_split_newlines(result_buf));
40 strv_print(lines);
41
42 if (buf_size >= BUF_SIZE) {
43 assert_se(strv_contains(lines, "INTERFACE=lo"));
44 assert_se(strv_contains(lines, "IFINDEX=1"));
45 }
46 }
47
48 static void test_event_spawn_self(const char *self, const char *arg, bool with_pidfd) {
49 _cleanup_strv_free_ char **lines = NULL;
50 _cleanup_free_ char *cmd = NULL;
51 char result_buf[BUF_SIZE];
52
53 log_debug("/* %s(%s, %s) */", __func__, arg, yes_no(with_pidfd));
54
55 /* 'self' may contain spaces, hence needs to be quoted. */
56 assert_se(cmd = strjoin("'", self, "' ", arg));
57
58 test_event_spawn_core(with_pidfd, cmd, result_buf, BUF_SIZE);
59
60 assert_se(lines = strv_split_newlines(result_buf));
61 strv_print(lines);
62
63 assert_se(strv_contains(lines, "aaa"));
64 assert_se(strv_contains(lines, "bbb"));
65 }
66
67 static void test1(void) {
68 fprintf(stdout, "aaa\nbbb");
69 fprintf(stderr, "ccc\nddd");
70 }
71
72 static void test2(void) {
73 char buf[16384];
74
75 fprintf(stdout, "aaa\nbbb");
76
77 memset(buf, 'a', sizeof(buf) - 1);
78 char_array_0(buf);
79 fputs(buf, stderr);
80 }
81
82 int main(int argc, char *argv[]) {
83 _cleanup_free_ char *self = NULL;
84
85 if (path_is_mount_point("/sys") <= 0)
86 return log_tests_skipped("/sys is not mounted");
87
88 if (argc > 1) {
89 if (streq(argv[1], "test1"))
90 test1();
91 else if (streq(argv[1], "test2"))
92 test2();
93 else
94 assert_not_reached();
95
96 return 0;
97 }
98
99 test_setup_logging(LOG_DEBUG);
100
101 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD) >= 0);
102
103 test_event_spawn_cat(true, SIZE_MAX);
104 test_event_spawn_cat(false, SIZE_MAX);
105 test_event_spawn_cat(true, 5);
106 test_event_spawn_cat(false, 5);
107
108 assert_se(path_make_absolute_cwd(argv[0], &self) >= 0);
109 path_simplify(self);
110
111 test_event_spawn_self(self, "test1", true);
112 test_event_spawn_self(self, "test1", false);
113
114 test_event_spawn_self(self, "test2", true);
115 test_event_spawn_self(self, "test2", false);
116
117 return 0;
118 }