chiark / gitweb /
util-lib: add new path_is_temporary_fs() API
[elogind.git] / src / basic / memfd-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2013 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #ifdef HAVE_LINUX_MEMFD_H
25 #include <linux/memfd.h>
26 #endif
27 #include <stdio.h>
28 #include <sys/mman.h>
29 #include <sys/prctl.h>
30
31 #include "alloc-util.h"
32 #include "fd-util.h"
33 #include "macro.h"
34 #include "memfd-util.h"
35 #include "missing.h"
36 #include "string-util.h"
37 #include "utf8.h"
38
39 int memfd_new(const char *name) {
40         _cleanup_free_ char *g = NULL;
41         int fd;
42
43         if (!name) {
44                 char pr[17] = {};
45
46                 /* If no name is specified we generate one. We include
47                  * a hint indicating our library implementation, and
48                  * add the thread name to it */
49
50                 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
51
52                 if (isempty(pr))
53                         name = "sd";
54                 else {
55                         _cleanup_free_ char *e = NULL;
56
57                         e = utf8_escape_invalid(pr);
58                         if (!e)
59                                 return -ENOMEM;
60
61                         g = strappend("sd-", e);
62                         if (!g)
63                                 return -ENOMEM;
64
65                         name = g;
66                 }
67         }
68
69         fd = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
70         if (fd < 0)
71                 return -errno;
72
73         return fd;
74 }
75
76 #if 0 /// UNNEEDED by elogind
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 #if 0 /// UNNEEDED by elogind
115 int memfd_get_sealed(int fd) {
116         int r;
117
118         assert(fd >= 0);
119
120         r = fcntl(fd, F_GET_SEALS);
121         if (r < 0)
122                 return -errno;
123
124         return r == (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL);
125 }
126
127 int memfd_get_size(int fd, uint64_t *sz) {
128         struct stat stat;
129         int r;
130
131         assert(fd >= 0);
132         assert(sz);
133
134         r = fstat(fd, &stat);
135         if (r < 0)
136                 return -errno;
137
138         *sz = stat.st_size;
139         return 0;
140 }
141 #endif // 0
142
143 int memfd_set_size(int fd, uint64_t sz) {
144         int r;
145
146         assert(fd >= 0);
147
148         r = ftruncate(fd, sz);
149         if (r < 0)
150                 return -errno;
151
152         return 0;
153 }
154
155 #if 0 /// UNNEEDED by elogind
156 int memfd_new_and_map(const char *name, size_t sz, void **p) {
157         _cleanup_close_ int fd = -1;
158         int r;
159
160         assert(sz > 0);
161         assert(p);
162
163         fd = memfd_new(name);
164         if (fd < 0)
165                 return fd;
166
167         r = memfd_set_size(fd, sz);
168         if (r < 0)
169                 return r;
170
171         r = memfd_map(fd, 0, sz, p);
172         if (r < 0)
173                 return r;
174
175         r = fd;
176         fd = -1;
177
178         return r;
179 }
180 #endif // 0