]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/fd-util.c
socket-util: move CMSG_FOREACH() from macro.h to socket-util.h
[thirdparty/systemd.git] / src / basic / fd-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 2010 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 "dirent-util.h"
23 #include "fd-util.h"
24 #include "parse-util.h"
25 #include "socket-util.h"
26 #include "util.h"
27
28 int close_nointr(int fd) {
29 assert(fd >= 0);
30
31 if (close(fd) >= 0)
32 return 0;
33
34 /*
35 * Just ignore EINTR; a retry loop is the wrong thing to do on
36 * Linux.
37 *
38 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
39 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
40 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
41 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
42 */
43 if (errno == EINTR)
44 return 0;
45
46 return -errno;
47 }
48
49 int safe_close(int fd) {
50
51 /*
52 * Like close_nointr() but cannot fail. Guarantees errno is
53 * unchanged. Is a NOP with negative fds passed, and returns
54 * -1, so that it can be used in this syntax:
55 *
56 * fd = safe_close(fd);
57 */
58
59 if (fd >= 0) {
60 PROTECT_ERRNO;
61
62 /* The kernel might return pretty much any error code
63 * via close(), but the fd will be closed anyway. The
64 * only condition we want to check for here is whether
65 * the fd was invalid at all... */
66
67 assert_se(close_nointr(fd) != -EBADF);
68 }
69
70 return -1;
71 }
72
73 void safe_close_pair(int p[]) {
74 assert(p);
75
76 if (p[0] == p[1]) {
77 /* Special case pairs which use the same fd in both
78 * directions... */
79 p[0] = p[1] = safe_close(p[0]);
80 return;
81 }
82
83 p[0] = safe_close(p[0]);
84 p[1] = safe_close(p[1]);
85 }
86
87 void close_many(const int fds[], unsigned n_fd) {
88 unsigned i;
89
90 assert(fds || n_fd <= 0);
91
92 for (i = 0; i < n_fd; i++)
93 safe_close(fds[i]);
94 }
95
96 int fclose_nointr(FILE *f) {
97 assert(f);
98
99 /* Same as close_nointr(), but for fclose() */
100
101 if (fclose(f) == 0)
102 return 0;
103
104 if (errno == EINTR)
105 return 0;
106
107 return -errno;
108 }
109
110 FILE* safe_fclose(FILE *f) {
111
112 /* Same as safe_close(), but for fclose() */
113
114 if (f) {
115 PROTECT_ERRNO;
116
117 assert_se(fclose_nointr(f) != EBADF);
118 }
119
120 return NULL;
121 }
122
123 DIR* safe_closedir(DIR *d) {
124
125 if (d) {
126 PROTECT_ERRNO;
127
128 assert_se(closedir(d) >= 0 || errno != EBADF);
129 }
130
131 return NULL;
132 }
133
134 int fd_nonblock(int fd, bool nonblock) {
135 int flags, nflags;
136
137 assert(fd >= 0);
138
139 flags = fcntl(fd, F_GETFL, 0);
140 if (flags < 0)
141 return -errno;
142
143 if (nonblock)
144 nflags = flags | O_NONBLOCK;
145 else
146 nflags = flags & ~O_NONBLOCK;
147
148 if (nflags == flags)
149 return 0;
150
151 if (fcntl(fd, F_SETFL, nflags) < 0)
152 return -errno;
153
154 return 0;
155 }
156
157 int fd_cloexec(int fd, bool cloexec) {
158 int flags, nflags;
159
160 assert(fd >= 0);
161
162 flags = fcntl(fd, F_GETFD, 0);
163 if (flags < 0)
164 return -errno;
165
166 if (cloexec)
167 nflags = flags | FD_CLOEXEC;
168 else
169 nflags = flags & ~FD_CLOEXEC;
170
171 if (nflags == flags)
172 return 0;
173
174 if (fcntl(fd, F_SETFD, nflags) < 0)
175 return -errno;
176
177 return 0;
178 }
179
180 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
181 unsigned i;
182
183 assert(n_fdset == 0 || fdset);
184
185 for (i = 0; i < n_fdset; i++)
186 if (fdset[i] == fd)
187 return true;
188
189 return false;
190 }
191
192 int close_all_fds(const int except[], unsigned n_except) {
193 _cleanup_closedir_ DIR *d = NULL;
194 struct dirent *de;
195 int r = 0;
196
197 assert(n_except == 0 || except);
198
199 d = opendir("/proc/self/fd");
200 if (!d) {
201 int fd;
202 struct rlimit rl;
203
204 /* When /proc isn't available (for example in chroots)
205 * the fallback is brute forcing through the fd
206 * table */
207
208 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
209 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
210
211 if (fd_in_set(fd, except, n_except))
212 continue;
213
214 if (close_nointr(fd) < 0)
215 if (errno != EBADF && r == 0)
216 r = -errno;
217 }
218
219 return r;
220 }
221
222 while ((de = readdir(d))) {
223 int fd = -1;
224
225 if (hidden_file(de->d_name))
226 continue;
227
228 if (safe_atoi(de->d_name, &fd) < 0)
229 /* Let's better ignore this, just in case */
230 continue;
231
232 if (fd < 3)
233 continue;
234
235 if (fd == dirfd(d))
236 continue;
237
238 if (fd_in_set(fd, except, n_except))
239 continue;
240
241 if (close_nointr(fd) < 0) {
242 /* Valgrind has its own FD and doesn't want to have it closed */
243 if (errno != EBADF && r == 0)
244 r = -errno;
245 }
246 }
247
248 return r;
249 }
250
251 int same_fd(int a, int b) {
252 struct stat sta, stb;
253 pid_t pid;
254 int r, fa, fb;
255
256 assert(a >= 0);
257 assert(b >= 0);
258
259 /* Compares two file descriptors. Note that semantics are
260 * quite different depending on whether we have kcmp() or we
261 * don't. If we have kcmp() this will only return true for
262 * dup()ed file descriptors, but not otherwise. If we don't
263 * have kcmp() this will also return true for two fds of the same
264 * file, created by separate open() calls. Since we use this
265 * call mostly for filtering out duplicates in the fd store
266 * this difference hopefully doesn't matter too much. */
267
268 if (a == b)
269 return true;
270
271 /* Try to use kcmp() if we have it. */
272 pid = getpid();
273 r = kcmp(pid, pid, KCMP_FILE, a, b);
274 if (r == 0)
275 return true;
276 if (r > 0)
277 return false;
278 if (errno != ENOSYS)
279 return -errno;
280
281 /* We don't have kcmp(), use fstat() instead. */
282 if (fstat(a, &sta) < 0)
283 return -errno;
284
285 if (fstat(b, &stb) < 0)
286 return -errno;
287
288 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
289 return false;
290
291 /* We consider all device fds different, since two device fds
292 * might refer to quite different device contexts even though
293 * they share the same inode and backing dev_t. */
294
295 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
296 return false;
297
298 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
299 return false;
300
301 /* The fds refer to the same inode on disk, let's also check
302 * if they have the same fd flags. This is useful to
303 * distinguish the read and write side of a pipe created with
304 * pipe(). */
305 fa = fcntl(a, F_GETFL);
306 if (fa < 0)
307 return -errno;
308
309 fb = fcntl(b, F_GETFL);
310 if (fb < 0)
311 return -errno;
312
313 return fa == fb;
314 }
315
316 void cmsg_close_all(struct msghdr *mh) {
317 struct cmsghdr *cmsg;
318
319 assert(mh);
320
321 CMSG_FOREACH(cmsg, mh)
322 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
323 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
324 }