File: | build-scan/../src/libsystemd/sd-login/sd-login.c |
Warning: | line 715, column 49 Potential leak of memory pointed to by 'b' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | ||||
2 | /*** | ||||
3 | ***/ | ||||
4 | |||||
5 | #include <errno(*__errno_location ()).h> | ||||
6 | #include <poll.h> | ||||
7 | #include <string.h> | ||||
8 | #include <sys/inotify.h> | ||||
9 | #include <unistd.h> | ||||
10 | |||||
11 | #include "sd-login.h" | ||||
12 | |||||
13 | #include "alloc-util.h" | ||||
14 | #include "cgroup-util.h" | ||||
15 | #include "dirent-util.h" | ||||
16 | #include "escape.h" | ||||
17 | #include "fd-util.h" | ||||
18 | #include "fileio.h" | ||||
19 | #include "format-util.h" | ||||
20 | #include "fs-util.h" | ||||
21 | #include "hostname-util.h" | ||||
22 | #include "io-util.h" | ||||
23 | #include "login-util.h" | ||||
24 | #include "macro.h" | ||||
25 | #include "parse-util.h" | ||||
26 | #include "path-util.h" | ||||
27 | #include "socket-util.h" | ||||
28 | #include "string-util.h" | ||||
29 | #include "strv.h" | ||||
30 | #include "user-util.h" | ||||
31 | #include "util.h" | ||||
32 | |||||
33 | /* Error codes: | ||||
34 | * | ||||
35 | * invalid input parameters → -EINVAL | ||||
36 | * invalid fd → -EBADF | ||||
37 | * process does not exist → -ESRCH | ||||
38 | * cgroup does not exist → -ENOENT | ||||
39 | * machine, session does not exist → -ENXIO | ||||
40 | * requested metadata on object is missing → -ENODATA | ||||
41 | */ | ||||
42 | |||||
43 | _public___attribute__ ((visibility("default"))) int sd_pid_get_session(pid_t pid, char **session) { | ||||
44 | int r; | ||||
45 | |||||
46 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 46, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
47 | assert_return(session, -EINVAL)do { if (!(((__builtin_expect(!!(session),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("session"), "../src/libsystemd/sd-login/sd-login.c" , 47, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
48 | |||||
49 | r = cg_pid_get_session(pid, session); | ||||
50 | return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case -6: case -123: _found = 1; break; default: break; } _found; } ) ? -ENODATA61 : r; | ||||
51 | } | ||||
52 | |||||
53 | _public___attribute__ ((visibility("default"))) int sd_pid_get_unit(pid_t pid, char **unit) { | ||||
54 | int r; | ||||
55 | |||||
56 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 56, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
57 | assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("unit"), "../src/libsystemd/sd-login/sd-login.c" , 57, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
58 | |||||
59 | r = cg_pid_get_unit(pid, unit); | ||||
60 | return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case -6: case -123: _found = 1; break; default: break; } _found; } ) ? -ENODATA61 : r; | ||||
61 | } | ||||
62 | |||||
63 | _public___attribute__ ((visibility("default"))) int sd_pid_get_user_unit(pid_t pid, char **unit) { | ||||
64 | int r; | ||||
65 | |||||
66 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 66, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
67 | assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("unit"), "../src/libsystemd/sd-login/sd-login.c" , 67, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
68 | |||||
69 | r = cg_pid_get_user_unit(pid, unit); | ||||
70 | return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case -6: case -123: _found = 1; break; default: break; } _found; } ) ? -ENODATA61 : r; | ||||
71 | } | ||||
72 | |||||
73 | _public___attribute__ ((visibility("default"))) int sd_pid_get_machine_name(pid_t pid, char **name) { | ||||
74 | int r; | ||||
75 | |||||
76 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 76, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
77 | assert_return(name, -EINVAL)do { if (!(((__builtin_expect(!!(name),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("name"), "../src/libsystemd/sd-login/sd-login.c" , 77, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
78 | |||||
79 | r = cg_pid_get_machine_name(pid, name); | ||||
80 | return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case -6: case -123: _found = 1; break; default: break; } _found; } ) ? -ENODATA61 : r; | ||||
81 | } | ||||
82 | |||||
83 | _public___attribute__ ((visibility("default"))) int sd_pid_get_slice(pid_t pid, char **slice) { | ||||
84 | int r; | ||||
85 | |||||
86 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 86, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
87 | assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("slice"), "../src/libsystemd/sd-login/sd-login.c" , 87, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
88 | |||||
89 | r = cg_pid_get_slice(pid, slice); | ||||
90 | return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case -6: case -123: _found = 1; break; default: break; } _found; } ) ? -ENODATA61 : r; | ||||
91 | } | ||||
92 | |||||
93 | _public___attribute__ ((visibility("default"))) int sd_pid_get_user_slice(pid_t pid, char **slice) { | ||||
94 | int r; | ||||
95 | |||||
96 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 96, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
97 | assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("slice"), "../src/libsystemd/sd-login/sd-login.c" , 97, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
98 | |||||
99 | r = cg_pid_get_user_slice(pid, slice); | ||||
100 | return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case -6: case -123: _found = 1; break; default: break; } _found; } ) ? -ENODATA61 : r; | ||||
101 | } | ||||
102 | |||||
103 | _public___attribute__ ((visibility("default"))) int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { | ||||
104 | int r; | ||||
105 | |||||
106 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 106, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
107 | assert_return(uid, -EINVAL)do { if (!(((__builtin_expect(!!(uid),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("uid"), "../src/libsystemd/sd-login/sd-login.c" , 107, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
108 | |||||
109 | r = cg_pid_get_owner_uid(pid, uid); | ||||
110 | return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case -6: case -123: _found = 1; break; default: break; } _found; } ) ? -ENODATA61 : r; | ||||
111 | } | ||||
112 | |||||
113 | _public___attribute__ ((visibility("default"))) int sd_pid_get_cgroup(pid_t pid, char **cgroup) { | ||||
114 | char *c; | ||||
115 | int r; | ||||
116 | |||||
117 | assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 117, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
118 | assert_return(cgroup, -EINVAL)do { if (!(((__builtin_expect(!!(cgroup),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("cgroup"), "../src/libsystemd/sd-login/sd-login.c" , 118, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
119 | |||||
120 | r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER"_systemd", pid, &c); | ||||
121 | if (r < 0) | ||||
122 | return r; | ||||
123 | |||||
124 | /* The internal APIs return the empty string for the root | ||||
125 | * cgroup, let's return the "/" in the public APIs instead, as | ||||
126 | * that's easier and less ambiguous for people to grok. */ | ||||
127 | if (isempty(c)) { | ||||
128 | free(c); | ||||
129 | c = strdup("/"); | ||||
130 | if (!c) | ||||
131 | return -ENOMEM12; | ||||
132 | |||||
133 | } | ||||
134 | |||||
135 | *cgroup = c; | ||||
136 | return 0; | ||||
137 | } | ||||
138 | |||||
139 | _public___attribute__ ((visibility("default"))) int sd_peer_get_session(int fd, char **session) { | ||||
140 | struct ucred ucred = {}; | ||||
141 | int r; | ||||
142 | |||||
143 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 143, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
144 | assert_return(session, -EINVAL)do { if (!(((__builtin_expect(!!(session),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("session"), "../src/libsystemd/sd-login/sd-login.c" , 144, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
145 | |||||
146 | r = getpeercred(fd, &ucred); | ||||
147 | if (r < 0) | ||||
148 | return r; | ||||
149 | |||||
150 | return cg_pid_get_session(ucred.pid, session); | ||||
151 | } | ||||
152 | |||||
153 | _public___attribute__ ((visibility("default"))) int sd_peer_get_owner_uid(int fd, uid_t *uid) { | ||||
154 | struct ucred ucred; | ||||
155 | int r; | ||||
156 | |||||
157 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 157, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
158 | assert_return(uid, -EINVAL)do { if (!(((__builtin_expect(!!(uid),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("uid"), "../src/libsystemd/sd-login/sd-login.c" , 158, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
159 | |||||
160 | r = getpeercred(fd, &ucred); | ||||
161 | if (r < 0) | ||||
162 | return r; | ||||
163 | |||||
164 | return cg_pid_get_owner_uid(ucred.pid, uid); | ||||
165 | } | ||||
166 | |||||
167 | _public___attribute__ ((visibility("default"))) int sd_peer_get_unit(int fd, char **unit) { | ||||
168 | struct ucred ucred; | ||||
169 | int r; | ||||
170 | |||||
171 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 171, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
172 | assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("unit"), "../src/libsystemd/sd-login/sd-login.c" , 172, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
173 | |||||
174 | r = getpeercred(fd, &ucred); | ||||
175 | if (r < 0) | ||||
176 | return r; | ||||
177 | |||||
178 | return cg_pid_get_unit(ucred.pid, unit); | ||||
179 | } | ||||
180 | |||||
181 | _public___attribute__ ((visibility("default"))) int sd_peer_get_user_unit(int fd, char **unit) { | ||||
182 | struct ucred ucred; | ||||
183 | int r; | ||||
184 | |||||
185 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 185, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
186 | assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("unit"), "../src/libsystemd/sd-login/sd-login.c" , 186, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
187 | |||||
188 | r = getpeercred(fd, &ucred); | ||||
189 | if (r < 0) | ||||
190 | return r; | ||||
191 | |||||
192 | return cg_pid_get_user_unit(ucred.pid, unit); | ||||
193 | } | ||||
194 | |||||
195 | _public___attribute__ ((visibility("default"))) int sd_peer_get_machine_name(int fd, char **machine) { | ||||
196 | struct ucred ucred; | ||||
197 | int r; | ||||
198 | |||||
199 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 199, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
200 | assert_return(machine, -EINVAL)do { if (!(((__builtin_expect(!!(machine),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("machine"), "../src/libsystemd/sd-login/sd-login.c" , 200, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
201 | |||||
202 | r = getpeercred(fd, &ucred); | ||||
203 | if (r < 0) | ||||
204 | return r; | ||||
205 | |||||
206 | return cg_pid_get_machine_name(ucred.pid, machine); | ||||
207 | } | ||||
208 | |||||
209 | _public___attribute__ ((visibility("default"))) int sd_peer_get_slice(int fd, char **slice) { | ||||
210 | struct ucred ucred; | ||||
211 | int r; | ||||
212 | |||||
213 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 213, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
214 | assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("slice"), "../src/libsystemd/sd-login/sd-login.c" , 214, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
215 | |||||
216 | r = getpeercred(fd, &ucred); | ||||
217 | if (r < 0) | ||||
218 | return r; | ||||
219 | |||||
220 | return cg_pid_get_slice(ucred.pid, slice); | ||||
221 | } | ||||
222 | |||||
223 | _public___attribute__ ((visibility("default"))) int sd_peer_get_user_slice(int fd, char **slice) { | ||||
224 | struct ucred ucred; | ||||
225 | int r; | ||||
226 | |||||
227 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 227, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
228 | assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("slice"), "../src/libsystemd/sd-login/sd-login.c" , 228, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
229 | |||||
230 | r = getpeercred(fd, &ucred); | ||||
231 | if (r < 0) | ||||
232 | return r; | ||||
233 | |||||
234 | return cg_pid_get_user_slice(ucred.pid, slice); | ||||
235 | } | ||||
236 | |||||
237 | _public___attribute__ ((visibility("default"))) int sd_peer_get_cgroup(int fd, char **cgroup) { | ||||
238 | struct ucred ucred; | ||||
239 | int r; | ||||
240 | |||||
241 | assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c" , 241, __PRETTY_FUNCTION__), 0))) return (-9); } while (0); | ||||
242 | assert_return(cgroup, -EINVAL)do { if (!(((__builtin_expect(!!(cgroup),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("cgroup"), "../src/libsystemd/sd-login/sd-login.c" , 242, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
243 | |||||
244 | r = getpeercred(fd, &ucred); | ||||
245 | if (r < 0) | ||||
246 | return r; | ||||
247 | |||||
248 | return sd_pid_get_cgroup(ucred.pid, cgroup); | ||||
249 | } | ||||
250 | |||||
251 | static int file_of_uid(uid_t uid, char **p) { | ||||
252 | |||||
253 | assert_return(uid_is_valid(uid), -EINVAL)do { if (!(((__builtin_expect(!!(uid_is_valid(uid)),1))) ? (1 ) : (log_assert_failed_return_realm(LOG_REALM_UDEV, ("uid_is_valid(uid)" ), "../src/libsystemd/sd-login/sd-login.c", 253, __PRETTY_FUNCTION__ ), 0))) return (-22); } while (0); | ||||
254 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("p"), "../src/libsystemd/sd-login/sd-login.c" , 254, __PRETTY_FUNCTION__); } while (0); | ||||
255 | |||||
256 | if (asprintf(p, "/run/systemd/users/" UID_FMT"%" "u", uid) < 0) | ||||
257 | return -ENOMEM12; | ||||
258 | |||||
259 | return 0; | ||||
260 | } | ||||
261 | |||||
262 | _public___attribute__ ((visibility("default"))) int sd_uid_get_state(uid_t uid, char**state) { | ||||
263 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0); | ||||
264 | char *s = NULL((void*)0); | ||||
265 | int r; | ||||
266 | |||||
267 | assert_return(state, -EINVAL)do { if (!(((__builtin_expect(!!(state),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("state"), "../src/libsystemd/sd-login/sd-login.c" , 267, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
268 | |||||
269 | r = file_of_uid(uid, &p); | ||||
270 | if (r < 0) | ||||
271 | return r; | ||||
272 | |||||
273 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "STATE", &s, NULL((void*)0)); | ||||
274 | if (r == -ENOENT2) { | ||||
275 | free(s); | ||||
276 | s = strdup("offline"); | ||||
277 | if (!s) | ||||
278 | return -ENOMEM12; | ||||
279 | |||||
280 | } | ||||
281 | else if (r < 0) { | ||||
282 | free(s); | ||||
283 | return r; | ||||
284 | } | ||||
285 | if (isempty(s)) { | ||||
286 | free(s); | ||||
287 | return -EIO5; | ||||
288 | } | ||||
289 | |||||
290 | *state = s; | ||||
291 | return 0; | ||||
292 | } | ||||
293 | |||||
294 | _public___attribute__ ((visibility("default"))) int sd_uid_get_display(uid_t uid, char **session) { | ||||
295 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
296 | int r; | ||||
297 | |||||
298 | assert_return(session, -EINVAL)do { if (!(((__builtin_expect(!!(session),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("session"), "../src/libsystemd/sd-login/sd-login.c" , 298, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
299 | |||||
300 | r = file_of_uid(uid, &p); | ||||
301 | if (r < 0) | ||||
302 | return r; | ||||
303 | |||||
304 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "DISPLAY", &s, NULL((void*)0)); | ||||
305 | if (r == -ENOENT2) | ||||
306 | return -ENODATA61; | ||||
307 | if (r < 0) | ||||
308 | return r; | ||||
309 | if (isempty(s)) | ||||
310 | return -ENODATA61; | ||||
311 | |||||
312 | *session = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; }); | ||||
313 | |||||
314 | return 0; | ||||
315 | } | ||||
316 | |||||
317 | static int file_of_seat(const char *seat, char **_p) { | ||||
318 | char *p; | ||||
319 | int r; | ||||
320 | |||||
321 | assert(_p)do { if ((__builtin_expect(!!(!(_p)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("_p"), "../src/libsystemd/sd-login/sd-login.c" , 321, __PRETTY_FUNCTION__); } while (0); | ||||
322 | |||||
323 | if (seat) { | ||||
324 | if (!filename_is_valid(seat)) | ||||
325 | return -EINVAL22; | ||||
326 | |||||
327 | p = strappend("/run/systemd/seats/", seat); | ||||
328 | } else { | ||||
329 | _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0); | ||||
330 | |||||
331 | r = sd_session_get_seat(NULL((void*)0), &buf); | ||||
332 | if (r < 0) | ||||
333 | return r; | ||||
334 | |||||
335 | p = strappend("/run/systemd/seats/", buf); | ||||
336 | } | ||||
337 | |||||
338 | if (!p) | ||||
339 | return -ENOMEM12; | ||||
340 | |||||
341 | *_p = TAKE_PTR(p)({ typeof(p) _ptr_ = (p); (p) = ((void*)0); _ptr_; }); | ||||
342 | return 0; | ||||
343 | } | ||||
344 | |||||
345 | _public___attribute__ ((visibility("default"))) int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) { | ||||
346 | _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0), *s = NULL((void*)0), *p = NULL((void*)0); | ||||
347 | size_t l; | ||||
348 | int r; | ||||
349 | const char *word, *variable, *state; | ||||
350 | |||||
351 | assert_return(uid_is_valid(uid), -EINVAL)do { if (!(((__builtin_expect(!!(uid_is_valid(uid)),1))) ? (1 ) : (log_assert_failed_return_realm(LOG_REALM_UDEV, ("uid_is_valid(uid)" ), "../src/libsystemd/sd-login/sd-login.c", 351, __PRETTY_FUNCTION__ ), 0))) return (-22); } while (0); | ||||
352 | |||||
353 | r = file_of_seat(seat, &p); | ||||
354 | if (r < 0) | ||||
355 | return r; | ||||
356 | |||||
357 | variable = require_active ? "ACTIVE_UID" : "UIDS"; | ||||
358 | |||||
359 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", variable, &s, NULL((void*)0)); | ||||
360 | if (r == -ENOENT2) | ||||
361 | return 0; | ||||
362 | if (r < 0) | ||||
363 | return r; | ||||
364 | if (isempty(s)) | ||||
365 | return 0; | ||||
366 | |||||
367 | if (asprintf(&t, UID_FMT"%" "u", uid) < 0) | ||||
368 | return -ENOMEM12; | ||||
369 | |||||
370 | FOREACH_WORD(word, l, s, state)for ((state) = (s), (word) = split(&(state), &(l), (" \t\n\r" ), (0)); (word); (word) = split(&(state), &(l), (" \t\n\r" ), (0))) | ||||
371 | if (strneq(t, word, l)(strncmp((t), (word), (l)) == 0)) | ||||
372 | return 1; | ||||
373 | |||||
374 | return 0; | ||||
375 | } | ||||
376 | |||||
377 | static int uid_get_array(uid_t uid, const char *variable, char ***array) { | ||||
378 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
379 | char **a; | ||||
380 | int r; | ||||
381 | |||||
382 | assert(variable)do { if ((__builtin_expect(!!(!(variable)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("variable"), "../src/libsystemd/sd-login/sd-login.c" , 382, __PRETTY_FUNCTION__); } while (0); | ||||
383 | |||||
384 | r = file_of_uid(uid, &p); | ||||
385 | if (r < 0) | ||||
386 | return r; | ||||
387 | |||||
388 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", variable, &s, NULL((void*)0)); | ||||
389 | if (r == -ENOENT2 || (r >= 0 && isempty(s))) { | ||||
390 | if (array) | ||||
391 | *array = NULL((void*)0); | ||||
392 | return 0; | ||||
393 | } | ||||
394 | if (r < 0) | ||||
395 | return r; | ||||
396 | |||||
397 | a = strv_split(s, " "); | ||||
398 | if (!a) | ||||
399 | return -ENOMEM12; | ||||
400 | |||||
401 | strv_uniq(a); | ||||
402 | r = (int) strv_length(a); | ||||
403 | |||||
404 | if (array) | ||||
405 | *array = a; | ||||
406 | else | ||||
407 | strv_free(a); | ||||
408 | |||||
409 | return r; | ||||
410 | } | ||||
411 | |||||
412 | _public___attribute__ ((visibility("default"))) int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions) { | ||||
413 | return uid_get_array( | ||||
414 | uid, | ||||
415 | require_active == 0 ? "ONLINE_SESSIONS" : | ||||
416 | require_active > 0 ? "ACTIVE_SESSIONS" : | ||||
417 | "SESSIONS", | ||||
418 | sessions); | ||||
419 | } | ||||
420 | |||||
421 | _public___attribute__ ((visibility("default"))) int sd_uid_get_seats(uid_t uid, int require_active, char ***seats) { | ||||
422 | return uid_get_array( | ||||
423 | uid, | ||||
424 | require_active == 0 ? "ONLINE_SEATS" : | ||||
425 | require_active > 0 ? "ACTIVE_SEATS" : | ||||
426 | "SEATS", | ||||
427 | seats); | ||||
428 | } | ||||
429 | |||||
430 | static int file_of_session(const char *session, char **_p) { | ||||
431 | char *p; | ||||
432 | int r; | ||||
433 | |||||
434 | assert(_p)do { if ((__builtin_expect(!!(!(_p)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("_p"), "../src/libsystemd/sd-login/sd-login.c" , 434, __PRETTY_FUNCTION__); } while (0); | ||||
435 | |||||
436 | if (session) { | ||||
437 | if (!session_id_valid(session)) | ||||
438 | return -EINVAL22; | ||||
439 | |||||
440 | p = strappend("/run/systemd/sessions/", session); | ||||
441 | } else { | ||||
442 | _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0); | ||||
443 | |||||
444 | r = sd_pid_get_session(0, &buf); | ||||
445 | if (r < 0) | ||||
446 | return r; | ||||
447 | |||||
448 | p = strappend("/run/systemd/sessions/", buf); | ||||
449 | } | ||||
450 | |||||
451 | if (!p) | ||||
452 | return -ENOMEM12; | ||||
453 | |||||
454 | *_p = p; | ||||
455 | return 0; | ||||
456 | } | ||||
457 | |||||
458 | _public___attribute__ ((visibility("default"))) int sd_session_is_active(const char *session) { | ||||
459 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
460 | int r; | ||||
461 | |||||
462 | r = file_of_session(session, &p); | ||||
463 | if (r < 0) | ||||
464 | return r; | ||||
465 | |||||
466 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "ACTIVE", &s, NULL((void*)0)); | ||||
467 | if (r == -ENOENT2) | ||||
468 | return -ENXIO6; | ||||
469 | if (r < 0) | ||||
470 | return r; | ||||
471 | if (isempty(s)) | ||||
472 | return -EIO5; | ||||
473 | |||||
474 | return parse_boolean(s); | ||||
475 | } | ||||
476 | |||||
477 | _public___attribute__ ((visibility("default"))) int sd_session_is_remote(const char *session) { | ||||
478 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
479 | int r; | ||||
480 | |||||
481 | r = file_of_session(session, &p); | ||||
482 | if (r < 0) | ||||
483 | return r; | ||||
484 | |||||
485 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "REMOTE", &s, NULL((void*)0)); | ||||
486 | if (r == -ENOENT2) | ||||
487 | return -ENXIO6; | ||||
488 | if (r < 0) | ||||
489 | return r; | ||||
490 | if (isempty(s)) | ||||
491 | return -ENODATA61; | ||||
492 | |||||
493 | return parse_boolean(s); | ||||
494 | } | ||||
495 | |||||
496 | _public___attribute__ ((visibility("default"))) int sd_session_get_state(const char *session, char **state) { | ||||
497 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
498 | int r; | ||||
499 | |||||
500 | assert_return(state, -EINVAL)do { if (!(((__builtin_expect(!!(state),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("state"), "../src/libsystemd/sd-login/sd-login.c" , 500, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
501 | |||||
502 | r = file_of_session(session, &p); | ||||
503 | if (r < 0) | ||||
504 | return r; | ||||
505 | |||||
506 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "STATE", &s, NULL((void*)0)); | ||||
507 | if (r == -ENOENT2) | ||||
508 | return -ENXIO6; | ||||
509 | if (r < 0) | ||||
510 | return r; | ||||
511 | if (isempty(s)) | ||||
512 | return -EIO5; | ||||
513 | |||||
514 | *state = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; }); | ||||
515 | |||||
516 | return 0; | ||||
517 | } | ||||
518 | |||||
519 | _public___attribute__ ((visibility("default"))) int sd_session_get_uid(const char *session, uid_t *uid) { | ||||
520 | int r; | ||||
521 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
522 | |||||
523 | assert_return(uid, -EINVAL)do { if (!(((__builtin_expect(!!(uid),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("uid"), "../src/libsystemd/sd-login/sd-login.c" , 523, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
524 | |||||
525 | r = file_of_session(session, &p); | ||||
526 | if (r < 0) | ||||
527 | return r; | ||||
528 | |||||
529 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "UID", &s, NULL((void*)0)); | ||||
530 | if (r == -ENOENT2) | ||||
531 | return -ENXIO6; | ||||
532 | if (r < 0) | ||||
533 | return r; | ||||
534 | if (isempty(s)) | ||||
535 | return -EIO5; | ||||
536 | |||||
537 | return parse_uid(s, uid); | ||||
538 | } | ||||
539 | |||||
540 | static int session_get_string(const char *session, const char *field, char **value) { | ||||
541 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
542 | int r; | ||||
543 | |||||
544 | assert_return(value, -EINVAL)do { if (!(((__builtin_expect(!!(value),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("value"), "../src/libsystemd/sd-login/sd-login.c" , 544, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
545 | assert(field)do { if ((__builtin_expect(!!(!(field)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("field"), "../src/libsystemd/sd-login/sd-login.c" , 545, __PRETTY_FUNCTION__); } while (0); | ||||
546 | |||||
547 | r = file_of_session(session, &p); | ||||
548 | if (r < 0) | ||||
549 | return r; | ||||
550 | |||||
551 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", field, &s, NULL((void*)0)); | ||||
552 | if (r == -ENOENT2) | ||||
553 | return -ENXIO6; | ||||
554 | if (r < 0) | ||||
555 | return r; | ||||
556 | if (isempty(s)) | ||||
557 | return -ENODATA61; | ||||
558 | |||||
559 | *value = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; }); | ||||
560 | return 0; | ||||
561 | } | ||||
562 | |||||
563 | _public___attribute__ ((visibility("default"))) int sd_session_get_seat(const char *session, char **seat) { | ||||
564 | return session_get_string(session, "SEAT", seat); | ||||
565 | } | ||||
566 | |||||
567 | _public___attribute__ ((visibility("default"))) int sd_session_get_tty(const char *session, char **tty) { | ||||
568 | return session_get_string(session, "TTY", tty); | ||||
569 | } | ||||
570 | |||||
571 | _public___attribute__ ((visibility("default"))) int sd_session_get_vt(const char *session, unsigned *vtnr) { | ||||
572 | _cleanup_free___attribute__((cleanup(freep))) char *vtnr_string = NULL((void*)0); | ||||
573 | unsigned u; | ||||
574 | int r; | ||||
575 | |||||
576 | assert_return(vtnr, -EINVAL)do { if (!(((__builtin_expect(!!(vtnr),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("vtnr"), "../src/libsystemd/sd-login/sd-login.c" , 576, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
577 | |||||
578 | r = session_get_string(session, "VTNR", &vtnr_string); | ||||
579 | if (r < 0) | ||||
580 | return r; | ||||
581 | |||||
582 | r = safe_atou(vtnr_string, &u); | ||||
583 | if (r < 0) | ||||
584 | return r; | ||||
585 | |||||
586 | *vtnr = u; | ||||
587 | return 0; | ||||
588 | } | ||||
589 | |||||
590 | _public___attribute__ ((visibility("default"))) int sd_session_get_service(const char *session, char **service) { | ||||
591 | return session_get_string(session, "SERVICE", service); | ||||
592 | } | ||||
593 | |||||
594 | _public___attribute__ ((visibility("default"))) int sd_session_get_type(const char *session, char **type) { | ||||
595 | return session_get_string(session, "TYPE", type); | ||||
596 | } | ||||
597 | |||||
598 | _public___attribute__ ((visibility("default"))) int sd_session_get_class(const char *session, char **class) { | ||||
599 | return session_get_string(session, "CLASS", class); | ||||
600 | } | ||||
601 | |||||
602 | _public___attribute__ ((visibility("default"))) int sd_session_get_desktop(const char *session, char **desktop) { | ||||
603 | _cleanup_free___attribute__((cleanup(freep))) char *escaped = NULL((void*)0); | ||||
604 | char *t; | ||||
605 | int r; | ||||
606 | |||||
607 | assert_return(desktop, -EINVAL)do { if (!(((__builtin_expect(!!(desktop),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("desktop"), "../src/libsystemd/sd-login/sd-login.c" , 607, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
608 | |||||
609 | r = session_get_string(session, "DESKTOP", &escaped); | ||||
610 | if (r < 0) | ||||
611 | return r; | ||||
612 | |||||
613 | r = cunescape(escaped, 0, &t); | ||||
614 | if (r < 0) | ||||
615 | return r; | ||||
616 | |||||
617 | *desktop = t; | ||||
618 | return 0; | ||||
619 | } | ||||
620 | |||||
621 | _public___attribute__ ((visibility("default"))) int sd_session_get_display(const char *session, char **display) { | ||||
622 | return session_get_string(session, "DISPLAY", display); | ||||
623 | } | ||||
624 | |||||
625 | _public___attribute__ ((visibility("default"))) int sd_session_get_remote_user(const char *session, char **remote_user) { | ||||
626 | return session_get_string(session, "REMOTE_USER", remote_user); | ||||
627 | } | ||||
628 | |||||
629 | _public___attribute__ ((visibility("default"))) int sd_session_get_remote_host(const char *session, char **remote_host) { | ||||
630 | return session_get_string(session, "REMOTE_HOST", remote_host); | ||||
631 | } | ||||
632 | |||||
633 | _public___attribute__ ((visibility("default"))) int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { | ||||
634 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0), *t = NULL((void*)0); | ||||
635 | int r; | ||||
636 | |||||
637 | assert_return(session || uid, -EINVAL)do { if (!(((__builtin_expect(!!(session || uid),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_UDEV, ("session || uid" ), "../src/libsystemd/sd-login/sd-login.c", 637, __PRETTY_FUNCTION__ ), 0))) return (-22); } while (0); | ||||
638 | |||||
639 | r = file_of_seat(seat, &p); | ||||
640 | if (r < 0) | ||||
641 | return r; | ||||
642 | |||||
643 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", | ||||
644 | "ACTIVE", &s, | ||||
645 | "ACTIVE_UID", &t, | ||||
646 | NULL((void*)0)); | ||||
647 | if (r == -ENOENT2) | ||||
648 | return -ENXIO6; | ||||
649 | if (r < 0) | ||||
650 | return r; | ||||
651 | |||||
652 | if (session && !s) | ||||
653 | return -ENODATA61; | ||||
654 | |||||
655 | if (uid && !t) | ||||
656 | return -ENODATA61; | ||||
657 | |||||
658 | if (uid && t) { | ||||
659 | r = parse_uid(t, uid); | ||||
660 | if (r < 0) | ||||
661 | return r; | ||||
662 | } | ||||
663 | |||||
664 | if (session && s) | ||||
665 | *session = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; }); | ||||
666 | |||||
667 | return 0; | ||||
668 | } | ||||
669 | |||||
670 | _public___attribute__ ((visibility("default"))) int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) { | ||||
671 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0), *t = NULL((void*)0); | ||||
672 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0); | ||||
673 | _cleanup_free___attribute__((cleanup(freep))) uid_t *b = NULL((void*)0); | ||||
674 | unsigned n = 0; | ||||
675 | int r; | ||||
676 | |||||
677 | r = file_of_seat(seat, &p); | ||||
678 | if (r
| ||||
| |||||
679 | return r; | ||||
680 | |||||
681 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", | ||||
682 | "SESSIONS", &s, | ||||
683 | "UIDS", &t, | ||||
684 | NULL((void*)0)); | ||||
685 | if (r == -ENOENT2) | ||||
686 | return -ENXIO6; | ||||
687 | if (r < 0) | ||||
688 | return r; | ||||
689 | |||||
690 | if (s) { | ||||
691 | a = strv_split(s, " "); | ||||
692 | if (!a) | ||||
693 | return -ENOMEM12; | ||||
694 | } | ||||
695 | |||||
696 | if (uids && t) { | ||||
697 | const char *word, *state; | ||||
698 | size_t l; | ||||
699 | |||||
700 | FOREACH_WORD(word, l, t, state)for ((state) = (t), (word) = split(&(state), &(l), (" \t\n\r" ), (0)); (word); (word) = split(&(state), &(l), (" \t\n\r" ), (0))) | ||||
701 | n++; | ||||
702 | |||||
703 | if (n
| ||||
704 | unsigned i = 0; | ||||
705 | |||||
706 | b = new(uid_t, n)((uid_t*) malloc_multiply(sizeof(uid_t), (n))); | ||||
707 | if (!b) | ||||
708 | return -ENOMEM12; | ||||
709 | |||||
710 | FOREACH_WORD(word, l, t, state)for ((state) = (t), (word) = split(&(state), &(l), (" \t\n\r" ), (0)); (word); (word) = split(&(state), &(l), (" \t\n\r" ), (0))) { | ||||
711 | _cleanup_free___attribute__((cleanup(freep))) char *k = NULL((void*)0); | ||||
712 | |||||
713 | k = strndup(word, l); | ||||
714 | if (!k) | ||||
715 | return -ENOMEM12; | ||||
| |||||
716 | |||||
717 | r = parse_uid(k, b + i); | ||||
718 | if (r < 0) | ||||
719 | return r; | ||||
720 | |||||
721 | i++; | ||||
722 | } | ||||
723 | } | ||||
724 | } | ||||
725 | |||||
726 | r = (int) strv_length(a); | ||||
727 | |||||
728 | if (sessions) | ||||
729 | *sessions = TAKE_PTR(a)({ typeof(a) _ptr_ = (a); (a) = ((void*)0); _ptr_; }); | ||||
730 | |||||
731 | if (uids) | ||||
732 | *uids = TAKE_PTR(b)({ typeof(b) _ptr_ = (b); (b) = ((void*)0); _ptr_; }); | ||||
733 | |||||
734 | if (n_uids) | ||||
735 | *n_uids = n; | ||||
736 | |||||
737 | return r; | ||||
738 | } | ||||
739 | |||||
740 | static int seat_get_can(const char *seat, const char *variable) { | ||||
741 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0); | ||||
742 | int r; | ||||
743 | |||||
744 | assert(variable)do { if ((__builtin_expect(!!(!(variable)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("variable"), "../src/libsystemd/sd-login/sd-login.c" , 744, __PRETTY_FUNCTION__); } while (0); | ||||
745 | |||||
746 | r = file_of_seat(seat, &p); | ||||
747 | if (r < 0) | ||||
748 | return r; | ||||
749 | |||||
750 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", | ||||
751 | variable, &s, | ||||
752 | NULL((void*)0)); | ||||
753 | if (r == -ENOENT2) | ||||
754 | return -ENXIO6; | ||||
755 | if (r < 0) | ||||
756 | return r; | ||||
757 | if (isempty(s)) | ||||
758 | return -ENODATA61; | ||||
759 | |||||
760 | return parse_boolean(s); | ||||
761 | } | ||||
762 | |||||
763 | _public___attribute__ ((visibility("default"))) int sd_seat_can_multi_session(const char *seat) { | ||||
764 | return seat_get_can(seat, "CAN_MULTI_SESSION"); | ||||
765 | } | ||||
766 | |||||
767 | _public___attribute__ ((visibility("default"))) int sd_seat_can_tty(const char *seat) { | ||||
768 | return seat_get_can(seat, "CAN_TTY"); | ||||
769 | } | ||||
770 | |||||
771 | _public___attribute__ ((visibility("default"))) int sd_seat_can_graphical(const char *seat) { | ||||
772 | return seat_get_can(seat, "CAN_GRAPHICAL"); | ||||
773 | } | ||||
774 | |||||
775 | _public___attribute__ ((visibility("default"))) int sd_get_seats(char ***seats) { | ||||
776 | int r; | ||||
777 | |||||
778 | r = get_files_in_directory("/run/systemd/seats/", seats); | ||||
779 | if (r == -ENOENT2) { | ||||
780 | if (seats) | ||||
781 | *seats = NULL((void*)0); | ||||
782 | return 0; | ||||
783 | } | ||||
784 | return r; | ||||
785 | } | ||||
786 | |||||
787 | _public___attribute__ ((visibility("default"))) int sd_get_sessions(char ***sessions) { | ||||
788 | int r; | ||||
789 | |||||
790 | r = get_files_in_directory("/run/systemd/sessions/", sessions); | ||||
791 | if (r == -ENOENT2) { | ||||
792 | if (sessions) | ||||
793 | *sessions = NULL((void*)0); | ||||
794 | return 0; | ||||
795 | } | ||||
796 | return r; | ||||
797 | } | ||||
798 | |||||
799 | _public___attribute__ ((visibility("default"))) int sd_get_uids(uid_t **users) { | ||||
800 | _cleanup_closedir___attribute__((cleanup(closedirp))) DIR *d; | ||||
801 | struct dirent *de; | ||||
802 | int r = 0; | ||||
803 | unsigned n = 0; | ||||
804 | _cleanup_free___attribute__((cleanup(freep))) uid_t *l = NULL((void*)0); | ||||
805 | |||||
806 | d = opendir("/run/systemd/users/"); | ||||
807 | if (!d) { | ||||
808 | if (errno(*__errno_location ()) == ENOENT2) { | ||||
809 | if (users) | ||||
810 | *users = NULL((void*)0); | ||||
811 | return 0; | ||||
812 | } | ||||
813 | return -errno(*__errno_location ()); | ||||
814 | } | ||||
815 | |||||
816 | FOREACH_DIRENT_ALL(de, d, return -errno)for ((*__errno_location ()) = 0, de = readdir(d);; (*__errno_location ()) = 0, de = readdir(d)) if (!de) { if ((*__errno_location ( )) > 0) { return -(*__errno_location ()); } break; } else { | ||||
817 | int k; | ||||
818 | uid_t uid; | ||||
819 | |||||
820 | dirent_ensure_type(d, de); | ||||
821 | |||||
822 | if (!dirent_is_file(de)) | ||||
823 | continue; | ||||
824 | |||||
825 | k = parse_uid(de->d_name, &uid); | ||||
826 | if (k < 0) | ||||
827 | continue; | ||||
828 | |||||
829 | if (users) { | ||||
830 | if ((unsigned) r >= n) { | ||||
831 | uid_t *t; | ||||
832 | |||||
833 | n = MAX(16, 2*r)__extension__ ({ const typeof((16)) __unique_prefix_A12 = ((16 )); const typeof((2*r)) __unique_prefix_B13 = ((2*r)); __unique_prefix_A12 > __unique_prefix_B13 ? __unique_prefix_A12 : __unique_prefix_B13 ; }); | ||||
834 | t = realloc(l, sizeof(uid_t) * n); | ||||
835 | if (!t) | ||||
836 | return -ENOMEM12; | ||||
837 | |||||
838 | l = t; | ||||
839 | } | ||||
840 | |||||
841 | assert((unsigned) r < n)do { if ((__builtin_expect(!!(!((unsigned) r < n)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("(unsigned) r < n"), "../src/libsystemd/sd-login/sd-login.c" , 841, __PRETTY_FUNCTION__); } while (0); | ||||
842 | l[r++] = uid; | ||||
843 | } else | ||||
844 | r++; | ||||
845 | } | ||||
846 | |||||
847 | if (users) | ||||
848 | *users = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; }); | ||||
849 | |||||
850 | return r; | ||||
851 | } | ||||
852 | |||||
853 | _public___attribute__ ((visibility("default"))) int sd_get_machine_names(char ***machines) { | ||||
854 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0); | ||||
855 | char **a, **b; | ||||
856 | int r; | ||||
857 | |||||
858 | r = get_files_in_directory("/run/systemd/machines/", &l); | ||||
859 | if (r == -ENOENT2) { | ||||
860 | if (machines) | ||||
861 | *machines = NULL((void*)0); | ||||
862 | return 0; | ||||
863 | } | ||||
864 | if (r < 0) | ||||
865 | return r; | ||||
866 | |||||
867 | if (l) { | ||||
868 | r = 0; | ||||
869 | |||||
870 | /* Filter out the unit: symlinks */ | ||||
871 | for (a = b = l; *a; a++) { | ||||
872 | if (startswith(*a, "unit:") || !machine_name_is_valid(*a)hostname_is_valid(*a, 0)) | ||||
873 | free(*a); | ||||
874 | else { | ||||
875 | *b = *a; | ||||
876 | b++; | ||||
877 | r++; | ||||
878 | } | ||||
879 | } | ||||
880 | |||||
881 | *b = NULL((void*)0); | ||||
882 | } | ||||
883 | |||||
884 | if (machines) | ||||
885 | *machines = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; }); | ||||
886 | |||||
887 | return r; | ||||
888 | } | ||||
889 | |||||
890 | _public___attribute__ ((visibility("default"))) int sd_machine_get_class(const char *machine, char **class) { | ||||
891 | _cleanup_free___attribute__((cleanup(freep))) char *c = NULL((void*)0); | ||||
892 | const char *p; | ||||
893 | int r; | ||||
894 | |||||
895 | assert_return(class, -EINVAL)do { if (!(((__builtin_expect(!!(class),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("class"), "../src/libsystemd/sd-login/sd-login.c" , 895, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
896 | |||||
897 | if (streq(machine, ".host")(strcmp((machine),(".host")) == 0)) { | ||||
898 | c = strdup("host"); | ||||
899 | if (!c) | ||||
900 | return -ENOMEM12; | ||||
901 | } else { | ||||
902 | if (!machine_name_is_valid(machine)hostname_is_valid(machine, 0)) | ||||
903 | return -EINVAL22; | ||||
904 | |||||
905 | p = strjoina("/run/systemd/machines/", machine)({ const char *_appendees_[] = { "/run/systemd/machines/", machine }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | ||||
906 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "CLASS", &c, NULL((void*)0)); | ||||
907 | if (r == -ENOENT2) | ||||
908 | return -ENXIO6; | ||||
909 | if (r < 0) | ||||
910 | return r; | ||||
911 | if (!c) | ||||
912 | return -EIO5; | ||||
913 | } | ||||
914 | |||||
915 | *class = TAKE_PTR(c)({ typeof(c) _ptr_ = (c); (c) = ((void*)0); _ptr_; }); | ||||
916 | return 0; | ||||
917 | } | ||||
918 | |||||
919 | _public___attribute__ ((visibility("default"))) int sd_machine_get_ifindices(const char *machine, int **ifindices) { | ||||
920 | _cleanup_free___attribute__((cleanup(freep))) char *netif = NULL((void*)0); | ||||
921 | size_t l, allocated = 0, nr = 0; | ||||
922 | int *ni = NULL((void*)0); | ||||
923 | const char *p, *word, *state; | ||||
924 | int r; | ||||
925 | |||||
926 | assert_return(machine_name_is_valid(machine), -EINVAL)do { if (!(((__builtin_expect(!!(hostname_is_valid(machine, 0 )),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_UDEV , ("machine_name_is_valid(machine)"), "../src/libsystemd/sd-login/sd-login.c" , 926, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
927 | assert_return(ifindices, -EINVAL)do { if (!(((__builtin_expect(!!(ifindices),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("ifindices"), "../src/libsystemd/sd-login/sd-login.c" , 927, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
928 | |||||
929 | p = strjoina("/run/systemd/machines/", machine)({ const char *_appendees_[] = { "/run/systemd/machines/", machine }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | ||||
930 | r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "NETIF", &netif, NULL((void*)0)); | ||||
931 | if (r == -ENOENT2) | ||||
932 | return -ENXIO6; | ||||
933 | if (r < 0) | ||||
934 | return r; | ||||
935 | if (!netif) { | ||||
936 | *ifindices = NULL((void*)0); | ||||
937 | return 0; | ||||
938 | } | ||||
939 | |||||
940 | FOREACH_WORD(word, l, netif, state)for ((state) = (netif), (word) = split(&(state), &(l) , (" \t\n\r"), (0)); (word); (word) = split(&(state), & (l), (" \t\n\r"), (0))) { | ||||
941 | char buf[l+1]; | ||||
942 | int ifi; | ||||
943 | |||||
944 | *(char*) (mempcpy(buf, word, l)) = 0; | ||||
945 | |||||
946 | if (parse_ifindex(buf, &ifi) < 0) | ||||
947 | continue; | ||||
948 | |||||
949 | if (!GREEDY_REALLOC(ni, allocated, nr+1)greedy_realloc((void**) &(ni), &(allocated), (nr+1), sizeof ((ni)[0]))) { | ||||
950 | free(ni); | ||||
951 | return -ENOMEM12; | ||||
952 | } | ||||
953 | |||||
954 | ni[nr++] = ifi; | ||||
955 | } | ||||
956 | |||||
957 | *ifindices = ni; | ||||
958 | return nr; | ||||
959 | } | ||||
960 | |||||
961 | static inline int MONITOR_TO_FD(sd_login_monitor *m) { | ||||
962 | return (int) (unsigned long) m - 1; | ||||
963 | } | ||||
964 | |||||
965 | static inline sd_login_monitor* FD_TO_MONITOR(int fd) { | ||||
966 | return (sd_login_monitor*) (unsigned long) (fd + 1); | ||||
967 | } | ||||
968 | |||||
969 | _public___attribute__ ((visibility("default"))) int sd_login_monitor_new(const char *category, sd_login_monitor **m) { | ||||
970 | _cleanup_close___attribute__((cleanup(closep))) int fd = -1; | ||||
971 | bool_Bool good = false0; | ||||
972 | int k; | ||||
973 | |||||
974 | assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("m"), "../src/libsystemd/sd-login/sd-login.c" , 974, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
975 | |||||
976 | fd = inotify_init1(IN_NONBLOCKIN_NONBLOCK|IN_CLOEXECIN_CLOEXEC); | ||||
977 | if (fd < 0) | ||||
978 | return -errno(*__errno_location ()); | ||||
979 | |||||
980 | if (!category || streq(category, "seat")(strcmp((category),("seat")) == 0)) { | ||||
981 | k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200); | ||||
982 | if (k < 0) | ||||
983 | return -errno(*__errno_location ()); | ||||
984 | |||||
985 | good = true1; | ||||
986 | } | ||||
987 | |||||
988 | if (!category || streq(category, "session")(strcmp((category),("session")) == 0)) { | ||||
989 | k = inotify_add_watch(fd, "/run/systemd/sessions/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200); | ||||
990 | if (k < 0) | ||||
991 | return -errno(*__errno_location ()); | ||||
992 | |||||
993 | good = true1; | ||||
994 | } | ||||
995 | |||||
996 | if (!category || streq(category, "uid")(strcmp((category),("uid")) == 0)) { | ||||
997 | k = inotify_add_watch(fd, "/run/systemd/users/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200); | ||||
998 | if (k < 0) | ||||
999 | return -errno(*__errno_location ()); | ||||
1000 | |||||
1001 | good = true1; | ||||
1002 | } | ||||
1003 | |||||
1004 | if (!category || streq(category, "machine")(strcmp((category),("machine")) == 0)) { | ||||
1005 | k = inotify_add_watch(fd, "/run/systemd/machines/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200); | ||||
1006 | if (k < 0) | ||||
1007 | return -errno(*__errno_location ()); | ||||
1008 | |||||
1009 | good = true1; | ||||
1010 | } | ||||
1011 | |||||
1012 | if (!good) | ||||
1013 | return -EINVAL22; | ||||
1014 | |||||
1015 | *m = FD_TO_MONITOR(fd); | ||||
1016 | fd = -1; | ||||
1017 | |||||
1018 | return 0; | ||||
1019 | } | ||||
1020 | |||||
1021 | _public___attribute__ ((visibility("default"))) sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) { | ||||
1022 | int fd; | ||||
1023 | |||||
1024 | if (!m) | ||||
1025 | return NULL((void*)0); | ||||
1026 | |||||
1027 | fd = MONITOR_TO_FD(m); | ||||
1028 | close_nointr(fd); | ||||
1029 | |||||
1030 | return NULL((void*)0); | ||||
1031 | } | ||||
1032 | |||||
1033 | _public___attribute__ ((visibility("default"))) int sd_login_monitor_flush(sd_login_monitor *m) { | ||||
1034 | int r; | ||||
1035 | |||||
1036 | assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("m"), "../src/libsystemd/sd-login/sd-login.c" , 1036, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
1037 | |||||
1038 | r = flush_fd(MONITOR_TO_FD(m)); | ||||
1039 | if (r < 0) | ||||
1040 | return r; | ||||
1041 | |||||
1042 | return 0; | ||||
1043 | } | ||||
1044 | |||||
1045 | _public___attribute__ ((visibility("default"))) int sd_login_monitor_get_fd(sd_login_monitor *m) { | ||||
1046 | |||||
1047 | assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("m"), "../src/libsystemd/sd-login/sd-login.c" , 1047, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
1048 | |||||
1049 | return MONITOR_TO_FD(m); | ||||
1050 | } | ||||
1051 | |||||
1052 | _public___attribute__ ((visibility("default"))) int sd_login_monitor_get_events(sd_login_monitor *m) { | ||||
1053 | |||||
1054 | assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("m"), "../src/libsystemd/sd-login/sd-login.c" , 1054, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
1055 | |||||
1056 | /* For now we will only return POLLIN here, since we don't | ||||
1057 | * need anything else ever for inotify. However, let's have | ||||
1058 | * this API to keep our options open should we later on need | ||||
1059 | * it. */ | ||||
1060 | return POLLIN0x001; | ||||
1061 | } | ||||
1062 | |||||
1063 | _public___attribute__ ((visibility("default"))) int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec) { | ||||
1064 | |||||
1065 | assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_UDEV, ("m"), "../src/libsystemd/sd-login/sd-login.c" , 1065, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | ||||
1066 | assert_return(timeout_usec, -EINVAL)do { if (!(((__builtin_expect(!!(timeout_usec),1))) ? (1) : ( log_assert_failed_return_realm(LOG_REALM_UDEV, ("timeout_usec" ), "../src/libsystemd/sd-login/sd-login.c", 1066, __PRETTY_FUNCTION__ ), 0))) return (-22); } while (0); | ||||
1067 | |||||
1068 | /* For now we will only return (uint64_t) -1, since we don't | ||||
1069 | * need any timeout. However, let's have this API to keep our | ||||
1070 | * options open should we later on need it. */ | ||||
1071 | *timeout_usec = (uint64_t) -1; | ||||
1072 | return 0; | ||||
1073 | } |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | #pragma once |
3 | |
4 | #include <alloca.h> |
5 | #include <stddef.h> |
6 | #include <stdlib.h> |
7 | #include <string.h> |
8 | |
9 | #include "macro.h" |
10 | |
11 | #define new(t, n)((t*) malloc_multiply(sizeof(t), (n))) ((t*) malloc_multiply(sizeof(t), (n))) |
12 | |
13 | #define new0(t, n)((t*) calloc((n), sizeof(t))) ((t*) calloc((n), sizeof(t))) |
14 | |
15 | #define newa(t, n)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof (t), n))),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("!size_multiply_overflow(sizeof(t), n)" ), "../src/basic/alloc-util.h", 15, __PRETTY_FUNCTION__); } while (0); (t*) __builtin_alloca (sizeof(t)*(n)); }) \ |
16 | ({ \ |
17 | assert(!size_multiply_overflow(sizeof(t), n))do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof (t), n))),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("!size_multiply_overflow(sizeof(t), n)" ), "../src/basic/alloc-util.h", 17, __PRETTY_FUNCTION__); } while (0); \ |
18 | (t*) alloca(sizeof(t)*(n))__builtin_alloca (sizeof(t)*(n)); \ |
19 | }) |
20 | |
21 | #define newa0(t, n)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof (t), n))),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("!size_multiply_overflow(sizeof(t), n)" ), "../src/basic/alloc-util.h", 21, __PRETTY_FUNCTION__); } while (0); (t*) ({ char *_new_; size_t _len_ = sizeof(t)*(n); _new_ = __builtin_alloca (_len_); (void *) memset(_new_, 0, _len_) ; }); }) \ |
22 | ({ \ |
23 | assert(!size_multiply_overflow(sizeof(t), n))do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof (t), n))),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("!size_multiply_overflow(sizeof(t), n)" ), "../src/basic/alloc-util.h", 23, __PRETTY_FUNCTION__); } while (0); \ |
24 | (t*) alloca0(sizeof(t)*(n))({ char *_new_; size_t _len_ = sizeof(t)*(n); _new_ = __builtin_alloca (_len_); (void *) memset(_new_, 0, _len_); }); \ |
25 | }) |
26 | |
27 | #define newdup(t, p, n)((t*) memdup_multiply(p, sizeof(t), (n))) ((t*) memdup_multiply(p, sizeof(t), (n))) |
28 | |
29 | #define newdup_suffix0(t, p, n)((t*) memdup_suffix0_multiply(p, sizeof(t), (n))) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n))) |
30 | |
31 | #define malloc0(n)(calloc(1, (n))) (calloc(1, (n))) |
32 | |
33 | static inline void *mfree(void *memory) { |
34 | free(memory); |
35 | return NULL((void*)0); |
36 | } |
37 | |
38 | #define free_and_replace(a, b)({ free(a); (a) = (b); (b) = ((void*)0); 0; }) \ |
39 | ({ \ |
40 | free(a); \ |
41 | (a) = (b); \ |
42 | (b) = NULL((void*)0); \ |
43 | 0; \ |
44 | }) |
45 | |
46 | void* memdup(const void *p, size_t l) _alloc_(2); |
47 | void* memdup_suffix0(const void *p, size_t l) _alloc_(2); |
48 | |
49 | static inline void freep(void *p) { |
50 | free(*(void**) p); |
51 | } |
52 | |
53 | #define _cleanup_free___attribute__((cleanup(freep))) _cleanup_(freep)__attribute__((cleanup(freep))) |
54 | |
55 | static inline bool_Bool size_multiply_overflow(size_t size, size_t need) { |
56 | return _unlikely_(need != 0 && size > (SIZE_MAX / need))(__builtin_expect(!!(need != 0 && size > ((18446744073709551615UL ) / need)),0)); |
57 | } |
58 | |
59 | _malloc___attribute__ ((malloc)) _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) { |
60 | if (size_multiply_overflow(size, need)) |
61 | return NULL((void*)0); |
62 | |
63 | return malloc(size * need); |
64 | } |
65 | |
66 | #if !HAVE_REALLOCARRAY1 |
67 | _alloc_(2, 3) static inline void *reallocarray(void *p, size_t need, size_t size) { |
68 | if (size_multiply_overflow(size, need)) |
69 | return NULL((void*)0); |
70 | |
71 | return realloc(p, size * need); |
72 | } |
73 | #endif |
74 | |
75 | _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) { |
76 | if (size_multiply_overflow(size, need)) |
77 | return NULL((void*)0); |
78 | |
79 | return memdup(p, size * need); |
80 | } |
81 | |
82 | _alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) { |
83 | if (size_multiply_overflow(size, need)) |
84 | return NULL((void*)0); |
85 | |
86 | return memdup_suffix0(p, size * need); |
87 | } |
88 | |
89 | void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size); |
90 | void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size); |
91 | |
92 | #define GREEDY_REALLOC(array, allocated, need)greedy_realloc((void**) &(array), &(allocated), (need ), sizeof((array)[0])) \ |
93 | greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0])) |
94 | |
95 | #define GREEDY_REALLOC0(array, allocated, need)greedy_realloc0((void**) &(array), &(allocated), (need ), sizeof((array)[0])) \ |
96 | greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0])) |
97 | |
98 | #define alloca0(n)({ char *_new_; size_t _len_ = n; _new_ = __builtin_alloca (_len_ ); (void *) memset(_new_, 0, _len_); }) \ |
99 | ({ \ |
100 | char *_new_; \ |
101 | size_t _len_ = n; \ |
102 | _new_ = alloca(_len_)__builtin_alloca (_len_); \ |
103 | (void *) memset(_new_, 0, _len_); \ |
104 | }) |
105 | |
106 | /* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */ |
107 | #define alloca_align(size, align)({ void *_ptr_; size_t _mask_ = (align) - 1; _ptr_ = __builtin_alloca ((size) + _mask_); (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); }) \ |
108 | ({ \ |
109 | void *_ptr_; \ |
110 | size_t _mask_ = (align) - 1; \ |
111 | _ptr_ = alloca((size) + _mask_)__builtin_alloca ((size) + _mask_); \ |
112 | (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \ |
113 | }) |
114 | |
115 | #define alloca0_align(size, align)({ void *_new_; size_t _size_ = (size); _new_ = ({ void *_ptr_ ; size_t _mask_ = ((align)) - 1; _ptr_ = __builtin_alloca ((_size_ ) + _mask_); (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_ ); }); (void*)memset(_new_, 0, _size_); }) \ |
116 | ({ \ |
117 | void *_new_; \ |
118 | size_t _size_ = (size); \ |
119 | _new_ = alloca_align(_size_, (align))({ void *_ptr_; size_t _mask_ = ((align)) - 1; _ptr_ = __builtin_alloca ((_size_) + _mask_); (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); }); \ |
120 | (void*)memset(_new_, 0, _size_); \ |
121 | }) |
122 | |
123 | /* Takes inspiration from Rusts's Option::take() method: reads and returns a pointer, but at the same time resets it to |
124 | * NULL. See: https://doc.rust-lang.org/std/option/enum.Option.html#method.take */ |
125 | #define TAKE_PTR(ptr)({ typeof(ptr) _ptr_ = (ptr); (ptr) = ((void*)0); _ptr_; }) \ |
126 | ({ \ |
127 | typeof(ptr) _ptr_ = (ptr); \ |
128 | (ptr) = NULL((void*)0); \ |
129 | _ptr_; \ |
130 | }) |