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