chiark / gitweb /
api: in constructor function calls, always put the returned object pointer first...
[elogind.git] / src / libsystemd / sd-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, *name;
34         uint64_t sz;
35         int r, fd;
36         FILE *f = NULL;
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, NULL);
44         if (r == -ENOENT)
45                 return EXIT_TEST_SKIP;
46
47         assert_se(r >= 0);
48
49         assert_se(sd_memfd_get_name(m, &name) >= 0);
50         log_info("name: %s", name);
51         free(name);
52
53         r = sd_memfd_map(m, 0, 12, (void**) &s);
54         assert_se(r >= 0);
55
56         strcpy(s, "----- world");
57
58         r = sd_memfd_set_sealed(m, 1);
59         assert_se(r == -ETXTBSY);
60
61         assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2);
62         assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3);
63         assert_se(streq(s, "heXXX world"));
64
65         /* fix "hello" */
66         assert_se(lseek(sd_memfd_get_fd(m), 2, SEEK_SET) == 2);
67         assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2);
68
69         assert_se(sd_memfd_get_file(m, &f) >= 0);
70         fputc('o', f);
71         fflush(f);
72
73         /* check content  */
74         assert_se(streq(s, "hello world"));
75
76         assert_se(munmap(s, 12) == 0);
77
78         r = sd_memfd_get_sealed(m);
79         assert_se(r == 0);
80
81         r = sd_memfd_get_size(m, &sz);
82         assert_se(r >= 0);
83         assert_se(sz = page_size());
84
85         /* truncate it */
86         r = sd_memfd_set_size(m, 6);
87         assert_se(r >= 0);
88
89         /* get back new value */
90         r = sd_memfd_get_size(m, &sz);
91         assert_se(r >= 0);
92         assert_se(sz == 6);
93
94         r = sd_memfd_set_sealed(m, 1);
95         assert_se(r >= 0);
96
97         r = sd_memfd_get_sealed(m);
98         assert_se(r == 1);
99
100         fd = sd_memfd_dup_fd(m);
101         assert_se(fd >= 0);
102
103         sd_memfd_free(m);
104
105         /* new sd_memfd, same underlying memfd */
106         r = sd_memfd_new_from_fd(&m, fd);
107         assert_se(r >= 0);
108
109         /* we did truncate it to 6 */
110         r = sd_memfd_get_size(m, &sz);
111         assert_se(r >= 0 && sz == 6);
112
113         /* map it, check content */
114         r = sd_memfd_map(m, 0, 12, (void **)&s);
115         assert_se(r >= 0);
116
117         /* we only see the truncated size */
118         assert_se(streq(s, "hello "));
119
120         /* it was already sealed */
121         r = sd_memfd_set_sealed(m, 1);
122         assert_se(r == -EALREADY);
123
124         /* we cannot break the seal, it is mapped */
125         r = sd_memfd_set_sealed(m, 0);
126         assert_se(r == -ETXTBSY);
127
128         /* unmap it; become the single owner */
129         assert_se(munmap(s, 12) == 0);
130
131         /* now we can do flip the sealing */
132         r = sd_memfd_set_sealed(m, 0);
133         assert_se(r == 0);
134         r = sd_memfd_get_sealed(m);
135         assert_se(r == 0);
136
137         r = sd_memfd_set_sealed(m, 1);
138         assert_se(r == 0);
139         r = sd_memfd_get_sealed(m);
140         assert_se(r == 1);
141
142         r = sd_memfd_set_sealed(m, 0);
143         assert_se(r == 0);
144         r = sd_memfd_get_sealed(m);
145         assert_se(r == 0);
146
147         /* seek at 2, read() 2 bytes */
148         assert_se(lseek(fd, 2, SEEK_SET) == 2);
149         assert_se(read(fd, buf, 2) == 2);
150
151         /* check content */
152         assert_se(memcmp(buf, "ll", 2) == 0);
153
154         /* writev it out*/
155         iov[0].iov_base = (char *)"ABC";
156         iov[0].iov_len = 3;
157         iov[1].iov_base = (char *)"DEF";
158         iov[1].iov_len = 3;
159         iov[2].iov_base = (char *)"GHI";
160         iov[2].iov_len = 3;
161         assert_se(pwritev(fd, iov, 3, 0) == 9);
162
163         /* readv it back */
164         iov[0].iov_base = bufv[0];
165         iov[0].iov_len = 3;
166         iov[1].iov_base = bufv[1];
167         iov[1].iov_len = 3;
168         iov[2].iov_base = bufv[2];
169         iov[2].iov_len = 3;
170         assert_se(preadv(fd, iov, 3, 0) == 9);
171
172         /* check content */
173         assert_se(memcmp(bufv[0], "ABC", 3) == 0);
174         assert_se(memcmp(bufv[1], "DEF", 3) == 0);
175         assert_se(memcmp(bufv[2], "GHI", 3) == 0);
176
177         sd_memfd_free(m);
178
179         return 0;
180 }