chiark / gitweb /
libsystemd-bus: use assert_return
[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 #include <sys/uio.h>
24
25 #include "log.h"
26 #include "macro.h"
27 #include "util.h"
28
29 #include "sd-memfd.h"
30
31 int main(int argc, char *argv[]) {
32         sd_memfd *m;
33         char *s;
34         uint64_t sz;
35         int r, fd;
36         FILE *f;
37         char buf[3] = {};
38         struct iovec iov[3] = {};
39         char bufv[3][3] = {};
40
41         log_set_max_level(LOG_DEBUG);
42
43         r = sd_memfd_new(&m);
44         if (r == -ENOENT)
45                 return EXIT_TEST_SKIP;
46
47         r = sd_memfd_map(m, 0, 12, (void**) &s);
48         assert_se(r >= 0);
49
50         strcpy(s, "----- world");
51
52         r = sd_memfd_set_sealed(m, 1);
53         assert_se(r == -ETXTBSY);
54
55         assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2);
56         assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3);
57         assert_se(streq(s, "heXXX world"));
58
59         /* fix "hello" */
60         assert_se(lseek(sd_memfd_get_fd(m), 2, SEEK_SET) == 2);
61         assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2);
62
63         assert_se(sd_memfd_get_file(m, &f) >= 0);
64         fputc('o', f);
65         fflush(f);
66
67         /* check content  */
68         assert_se(streq(s, "hello world"));
69
70         assert_se(munmap(s, 12) == 0);
71
72         r = sd_memfd_get_sealed(m);
73         assert_se(r == 0);
74
75         r = sd_memfd_get_size(m, &sz);
76         assert_se(r >= 0);
77         assert_se(sz = page_size());
78
79         /* truncate it */
80         r = sd_memfd_set_size(m, 6);
81         assert_se(r >= 0);
82
83         /* get back new value */
84         r = sd_memfd_get_size(m, &sz);
85         assert_se(r >= 0);
86         assert_se(sz == 6);
87
88         r = sd_memfd_set_sealed(m, 1);
89         assert_se(r >= 0);
90
91         r = sd_memfd_get_sealed(m);
92         assert_se(r == 1);
93
94         fd = sd_memfd_dup_fd(m);
95         assert_se(fd >= 0);
96
97         sd_memfd_free(m);
98
99         /* new sd_memfd, same underlying memfd */
100         r = sd_memfd_make(fd, &m);
101         assert_se(r >= 0);
102
103         /* we did truncate it to 6 */
104         r = sd_memfd_get_size(m, &sz);
105         assert_se(r >= 0 && sz == 6);
106
107         /* map it, check content */
108         r = sd_memfd_map(m, 0, 12, (void **)&s);
109         assert_se(r >= 0);
110
111         /* we only see the truncated size */
112         assert_se(streq(s, "hello "));
113
114         /* it was already sealed */
115         r = sd_memfd_set_sealed(m, 1);
116         assert_se(r == -EALREADY);
117
118         /* we cannot break the seal, it is mapped */
119         r = sd_memfd_set_sealed(m, 0);
120         assert_se(r == -ETXTBSY);
121
122         /* unmap it; become the single owner */
123         assert_se(munmap(s, 12) == 0);
124
125         /* now we can do flip the sealing */
126         r = sd_memfd_set_sealed(m, 0);
127         assert_se(r == 0);
128         r = sd_memfd_get_sealed(m);
129         assert_se(r == 0);
130
131         r = sd_memfd_set_sealed(m, 1);
132         assert_se(r == 0);
133         r = sd_memfd_get_sealed(m);
134         assert_se(r == 1);
135
136         r = sd_memfd_set_sealed(m, 0);
137         assert_se(r == 0);
138         r = sd_memfd_get_sealed(m);
139         assert_se(r == 0);
140
141         /* seek at 2, read() 2 bytes */
142         assert_se(lseek(fd, 2, SEEK_SET) == 2);
143         assert_se(read(fd, buf, 2) == 2);
144
145         /* check content */
146         assert_se(memcmp(buf, "ll", 2) == 0);
147
148         /* writev it out*/
149         iov[0].iov_base = (char *)"ABC";
150         iov[0].iov_len = 3;
151         iov[1].iov_base = (char *)"DEF";
152         iov[1].iov_len = 3;
153         iov[2].iov_base = (char *)"GHI";
154         iov[2].iov_len = 3;
155         assert_se(pwritev(fd, iov, 3, 0) == 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(preadv(fd, iov, 3, 0) == 9);
165
166         /* check content */
167         assert_se(memcmp(bufv[0], "ABC", 3) == 0);
168         assert_se(memcmp(bufv[1], "DEF", 3) == 0);
169         assert_se(memcmp(bufv[2], "GHI", 3) == 0);
170
171         sd_memfd_free(m);
172
173         return 0;
174 }