chiark / gitweb /
Prep v228: Removed utmp bits. elogind does not support utmp-wtmp.
[elogind.git] / src / basic / memfd-util.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 <fcntl.h>
23 #ifdef HAVE_LINUX_MEMFD_H
24 #  include <linux/memfd.h>
25 #endif
26 #include <stdio.h>
27 #include <sys/mman.h>
28 #include <sys/prctl.h>
29
30 #include "alloc-util.h"
31 #include "fd-util.h"
32 #include "memfd-util.h"
33 #include "missing.h"
34 #include "string-util.h"
35 #include "utf8.h"
36 #include "util.h"
37
38 int memfd_new(const char *name) {
39         _cleanup_free_ char *g = NULL;
40         int fd;
41
42         if (!name) {
43                 char pr[17] = {};
44
45                 /* If no name is specified we generate one. We include
46                  * a hint indicating our library implementation, and
47                  * add the thread name to it */
48
49                 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
50
51                 if (isempty(pr))
52                         name = "sd";
53                 else {
54                         _cleanup_free_ char *e = NULL;
55
56                         e = utf8_escape_invalid(pr);
57                         if (!e)
58                                 return -ENOMEM;
59
60                         g = strappend("sd-", e);
61                         if (!g)
62                                 return -ENOMEM;
63
64                         name = g;
65                 }
66         }
67
68         fd = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
69         if (fd < 0)
70                 return -errno;
71
72         return fd;
73 }
74
75 /// UNNEEDED by elogind
76 #if 0
77 int memfd_map(int fd, uint64_t offset, size_t size, void **p) {
78         void *q;
79         int sealed;
80
81         assert(fd >= 0);
82         assert(size > 0);
83         assert(p);
84
85         sealed = memfd_get_sealed(fd);
86         if (sealed < 0)
87                 return sealed;
88
89         if (sealed)
90                 q = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, offset);
91         else
92                 q = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
93
94         if (q == MAP_FAILED)
95                 return -errno;
96
97         *p = q;
98         return 0;
99 }
100 #endif // 0
101
102 int memfd_set_sealed(int fd) {
103         int r;
104
105         assert(fd >= 0);
106
107         r = fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL);
108         if (r < 0)
109                 return -errno;
110
111         return 0;
112 }
113
114 /// UNNEEDED by elogind
115 #if 0
116 int memfd_get_sealed(int fd) {
117         int r;
118
119         assert(fd >= 0);
120
121         r = fcntl(fd, F_GET_SEALS);
122         if (r < 0)
123                 return -errno;
124
125         return r == (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL);
126 }
127
128 int memfd_get_size(int fd, uint64_t *sz) {
129         struct stat stat;
130         int r;
131
132         assert(fd >= 0);
133         assert(sz);
134
135         r = fstat(fd, &stat);
136         if (r < 0)
137                 return -errno;
138
139         *sz = stat.st_size;
140         return 0;
141 }
142 #endif // 0
143
144 int memfd_set_size(int fd, uint64_t sz) {
145         int r;
146
147         assert(fd >= 0);
148
149         r = ftruncate(fd, sz);
150         if (r < 0)
151                 return -errno;
152
153         return 0;
154 }
155
156 /// UNNEEDED by elogind
157 #if 0
158 int memfd_new_and_map(const char *name, size_t sz, void **p) {
159         _cleanup_close_ int fd = -1;
160         int r;
161
162         assert(sz > 0);
163         assert(p);
164
165         fd = memfd_new(name);
166         if (fd < 0)
167                 return fd;
168
169         r = memfd_set_size(fd, sz);
170         if (r < 0)
171                 return r;
172
173         r = memfd_map(fd, 0, sz, p);
174         if (r < 0)
175                 return r;
176
177         r = fd;
178         fd = -1;
179
180         return r;
181 }
182 #endif // 0