chiark / gitweb /
db199d46dbd13138ed6a1a9ac828cf5acf8c5216
[elogind.git] / src / libsystemd-bus / test-bus-memfd.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <sys/mman.h>
23
24 #include "log.h"
25 #include "macro.h"
26 #include "util.h"
27
28 #include "sd-memfd.h"
29
30 int main(int argc, char *argv[]) {
31         sd_memfd *m;
32         char *s;
33         uint64_t sz;
34         int r, fd;
35         FILE *f;
36         char buf[3] = {};
37         struct iovec iov[3] = {};
38         char bufv[3][3] = {};
39
40         log_set_max_level(LOG_DEBUG);
41
42         r = sd_memfd_new(&m);
43         if (r == -ENOENT)
44                 return EXIT_TEST_SKIP;
45
46         r = sd_memfd_map(m, 0, 12, (void**) &s);
47         assert_se(r >= 0);
48
49         strcpy(s, "----- world");
50
51         r = sd_memfd_set_sealed(m, 1);
52         assert_se(r == -ETXTBSY);
53
54         assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2);
55         assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3);
56         assert_se(streq(s, "heXXX world"));
57
58         /* fix "hello" */
59         assert_se(lseek(sd_memfd_get_fd(m), 2, SEEK_SET) == 2);
60         assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2);
61
62         assert_se(sd_memfd_get_file(m, &f) >= 0);
63         fputc('o', f);
64         fflush(f);
65
66         /* check content  */
67         assert_se(streq(s, "hello world"));
68
69         assert_se(munmap(s, 12) == 0);
70
71         r = sd_memfd_get_sealed(m);
72         assert_se(r == 0);
73
74         r = sd_memfd_get_size(m, &sz);
75         assert_se(r >= 0);
76         assert_se(sz = page_size());
77
78         /* truncate it */
79         r = sd_memfd_set_size(m, 6);
80         assert_se(r >= 0);
81
82         /* get back new value */
83         r = sd_memfd_get_size(m, &sz);
84         assert_se(r >= 0);
85         assert_se(sz == 6);
86
87         r = sd_memfd_set_sealed(m, 1);
88         assert_se(r >= 0);
89
90         r = sd_memfd_get_sealed(m);
91         assert_se(r == 1);
92
93         fd = sd_memfd_dup_fd(m);
94         assert_se(fd >= 0);
95
96         sd_memfd_free(m);
97
98         /* new sd_memfd, same underlying memfd */
99         r = sd_memfd_make(fd, &m);
100         assert_se(r >= 0);
101
102         /* we did truncate it to 6 */
103         r = sd_memfd_get_size(m, &sz);
104         assert_se(sz == 6);
105
106         /* map it, check content */
107         r = sd_memfd_map(m, 0, 12, (void **)&s);
108         assert_se(r >= 0);
109
110         /* we only see the truncated size */
111         assert_se(streq(s, "hello "));
112
113         /* it was already sealed */
114         r = sd_memfd_set_sealed(m, 1);
115         assert_se(r == -EALREADY);
116
117         /* we cannot break the seal, it is mapped */
118         r = sd_memfd_set_sealed(m, 0);
119         assert_se(r == -ETXTBSY);
120
121         /* unmap it; become the single owner */
122         assert_se(munmap(s, 12) == 0);
123
124         /* now we can do flip the sealing */
125         r = sd_memfd_set_sealed(m, 0);
126         assert_se(r == 0);
127         r = sd_memfd_get_sealed(m);
128         assert_se(r == 0);
129
130         r = sd_memfd_set_sealed(m, 1);
131         assert_se(r == 0);
132         r = sd_memfd_get_sealed(m);
133         assert_se(r == 1);
134
135         r = sd_memfd_set_sealed(m, 0);
136         assert_se(r == 0);
137         r = sd_memfd_get_sealed(m);
138         assert_se(r == 0);
139
140         /* seek at 2, read() 2 bytes */
141         assert_se(lseek(fd, 2, SEEK_SET) == 2);
142         assert_se(read(fd, buf, 2) == 2);
143
144         /* check content */
145         assert_se(memcmp(buf, "ll", 2) == 0);
146
147         /* writev it out*/
148         iov[0].iov_base = (char *)"ABC";
149         iov[0].iov_len = 3;
150         iov[1].iov_base = (char *)"DEF";
151         iov[1].iov_len = 3;
152         iov[2].iov_base = (char *)"GHI";
153         iov[2].iov_len = 3;
154         assert_se(lseek(fd, 0, SEEK_SET) == 0);
155         assert_se(writev(fd, iov, 3) == 9);
156
157         /* readv it back */
158         iov[0].iov_base = bufv[0];
159         iov[0].iov_len = 3;
160         iov[1].iov_base = bufv[1];
161         iov[1].iov_len = 3;
162         iov[2].iov_base = bufv[2];
163         iov[2].iov_len = 3;
164         assert_se(lseek(fd, 0, SEEK_SET) == 0);
165         assert_se(readv(fd, iov, 3) == 9);
166
167         /* check content */
168         assert_se(memcmp(bufv[0], "ABC", 3) == 0);
169         assert_se(memcmp(bufv[1], "DEF", 3) == 0);
170         assert_se(memcmp(bufv[2], "GHI", 3) == 0);
171
172         sd_memfd_free(m);
173
174         return 0;
175 }