chiark / gitweb /
tree-wide: remove Lennart's copyright lines
[elogind.git] / src / basic / memfd-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7 #if HAVE_LINUX_MEMFD_H
8 #include <linux/memfd.h>
9 #endif
10 #include <stdio.h>
11 #include <sys/mman.h>
12 #include <sys/prctl.h>
13
14 #include "alloc-util.h"
15 #include "fd-util.h"
16 #include "macro.h"
17 #include "memfd-util.h"
18 #include "missing.h"
19 #include "string-util.h"
20 #include "utf8.h"
21
22 int memfd_new(const char *name) {
23         _cleanup_free_ char *g = NULL;
24         int fd;
25
26         if (!name) {
27                 char pr[17] = {};
28
29                 /* If no name is specified we generate one. We include
30                  * a hint indicating our library implementation, and
31                  * add the thread name to it */
32
33                 assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
34
35                 if (isempty(pr))
36                         name = "sd";
37                 else {
38                         _cleanup_free_ char *e = NULL;
39
40                         e = utf8_escape_invalid(pr);
41                         if (!e)
42                                 return -ENOMEM;
43
44                         g = strappend("sd-", e);
45                         if (!g)
46                                 return -ENOMEM;
47
48                         name = g;
49                 }
50         }
51
52         fd = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
53         if (fd < 0)
54                 return -errno;
55
56         return fd;
57 }
58
59 #if 0 /// UNNEEDED by elogind
60 int memfd_map(int fd, uint64_t offset, size_t size, void **p) {
61         void *q;
62         int sealed;
63
64         assert(fd >= 0);
65         assert(size > 0);
66         assert(p);
67
68         sealed = memfd_get_sealed(fd);
69         if (sealed < 0)
70                 return sealed;
71
72         if (sealed)
73                 q = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, offset);
74         else
75                 q = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
76
77         if (q == MAP_FAILED)
78                 return -errno;
79
80         *p = q;
81         return 0;
82 }
83 #endif // 0
84
85 int memfd_set_sealed(int fd) {
86         int r;
87
88         assert(fd >= 0);
89
90         r = fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL);
91         if (r < 0)
92                 return -errno;
93
94         return 0;
95 }
96
97 #if 0 /// UNNEEDED by elogind
98 int memfd_get_sealed(int fd) {
99         int r;
100
101         assert(fd >= 0);
102
103         r = fcntl(fd, F_GET_SEALS);
104         if (r < 0)
105                 return -errno;
106
107         return r == (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL);
108 }
109 #endif // 0
110
111 int memfd_get_size(int fd, uint64_t *sz) {
112         struct stat stat;
113         int r;
114
115         assert(fd >= 0);
116         assert(sz);
117
118         r = fstat(fd, &stat);
119         if (r < 0)
120                 return -errno;
121
122         *sz = stat.st_size;
123         return 0;
124 }
125
126 int memfd_set_size(int fd, uint64_t sz) {
127         int r;
128
129         assert(fd >= 0);
130
131         r = ftruncate(fd, sz);
132         if (r < 0)
133                 return -errno;
134
135         return 0;
136 }
137
138 #if 0 /// UNNEEDED by elogind
139 int memfd_new_and_map(const char *name, size_t sz, void **p) {
140         _cleanup_close_ int fd = -1;
141         int r;
142
143         assert(sz > 0);
144         assert(p);
145
146         fd = memfd_new(name);
147         if (fd < 0)
148                 return fd;
149
150         r = memfd_set_size(fd, sz);
151         if (r < 0)
152                 return r;
153
154         r = memfd_map(fd, 0, sz, p);
155         if (r < 0)
156                 return r;
157
158         return TAKE_FD(fd);
159 }
160 #endif // 0