chiark / gitweb /
17cafa4bb8b46b5f7cf952e2ed96f8b1dfa9954a
[elogind.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 #if 0 /// UNNEEDED by elogind
124 DIR* safe_closedir(DIR *d) {
125
126         if (d) {
127                 PROTECT_ERRNO;
128
129                 assert_se(closedir(d) >= 0 || errno != EBADF);
130         }
131
132         return NULL;
133 }
134 #endif // 0
135
136 int fd_nonblock(int fd, bool nonblock) {
137         int flags, nflags;
138
139         assert(fd >= 0);
140
141         flags = fcntl(fd, F_GETFL, 0);
142         if (flags < 0)
143                 return -errno;
144
145         if (nonblock)
146                 nflags = flags | O_NONBLOCK;
147         else
148                 nflags = flags & ~O_NONBLOCK;
149
150         if (nflags == flags)
151                 return 0;
152
153         if (fcntl(fd, F_SETFL, nflags) < 0)
154                 return -errno;
155
156         return 0;
157 }
158
159 int fd_cloexec(int fd, bool cloexec) {
160         int flags, nflags;
161
162         assert(fd >= 0);
163
164         flags = fcntl(fd, F_GETFD, 0);
165         if (flags < 0)
166                 return -errno;
167
168         if (cloexec)
169                 nflags = flags | FD_CLOEXEC;
170         else
171                 nflags = flags & ~FD_CLOEXEC;
172
173         if (nflags == flags)
174                 return 0;
175
176         if (fcntl(fd, F_SETFD, nflags) < 0)
177                 return -errno;
178
179         return 0;
180 }
181
182 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
183         unsigned i;
184
185         assert(n_fdset == 0 || fdset);
186
187         for (i = 0; i < n_fdset; i++)
188                 if (fdset[i] == fd)
189                         return true;
190
191         return false;
192 }
193
194 int close_all_fds(const int except[], unsigned n_except) {
195         _cleanup_closedir_ DIR *d = NULL;
196         struct dirent *de;
197         int r = 0;
198
199         assert(n_except == 0 || except);
200
201         d = opendir("/proc/self/fd");
202         if (!d) {
203                 int fd;
204                 struct rlimit rl;
205
206                 /* When /proc isn't available (for example in chroots)
207                  * the fallback is brute forcing through the fd
208                  * table */
209
210                 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
211                 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
212
213                         if (fd_in_set(fd, except, n_except))
214                                 continue;
215
216                         if (close_nointr(fd) < 0)
217                                 if (errno != EBADF && r == 0)
218                                         r = -errno;
219                 }
220
221                 return r;
222         }
223
224         while ((de = readdir(d))) {
225                 int fd = -1;
226
227                 if (hidden_file(de->d_name))
228                         continue;
229
230                 if (safe_atoi(de->d_name, &fd) < 0)
231                         /* Let's better ignore this, just in case */
232                         continue;
233
234                 if (fd < 3)
235                         continue;
236
237                 if (fd == dirfd(d))
238                         continue;
239
240                 if (fd_in_set(fd, except, n_except))
241                         continue;
242
243                 if (close_nointr(fd) < 0) {
244                         /* Valgrind has its own FD and doesn't want to have it closed */
245                         if (errno != EBADF && r == 0)
246                                 r = -errno;
247                 }
248         }
249
250         return r;
251 }
252
253 #if 0 /// UNNEEDED by elogind
254 int same_fd(int a, int b) {
255         struct stat sta, stb;
256         pid_t pid;
257         int r, fa, fb;
258
259         assert(a >= 0);
260         assert(b >= 0);
261
262         /* Compares two file descriptors. Note that semantics are
263          * quite different depending on whether we have kcmp() or we
264          * don't. If we have kcmp() this will only return true for
265          * dup()ed file descriptors, but not otherwise. If we don't
266          * have kcmp() this will also return true for two fds of the same
267          * file, created by separate open() calls. Since we use this
268          * call mostly for filtering out duplicates in the fd store
269          * this difference hopefully doesn't matter too much. */
270
271         if (a == b)
272                 return true;
273
274         /* Try to use kcmp() if we have it. */
275         pid = getpid();
276         r = kcmp(pid, pid, KCMP_FILE, a, b);
277         if (r == 0)
278                 return true;
279         if (r > 0)
280                 return false;
281         if (errno != ENOSYS)
282                 return -errno;
283
284         /* We don't have kcmp(), use fstat() instead. */
285         if (fstat(a, &sta) < 0)
286                 return -errno;
287
288         if (fstat(b, &stb) < 0)
289                 return -errno;
290
291         if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
292                 return false;
293
294         /* We consider all device fds different, since two device fds
295          * might refer to quite different device contexts even though
296          * they share the same inode and backing dev_t. */
297
298         if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
299                 return false;
300
301         if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
302                 return false;
303
304         /* The fds refer to the same inode on disk, let's also check
305          * if they have the same fd flags. This is useful to
306          * distinguish the read and write side of a pipe created with
307          * pipe(). */
308         fa = fcntl(a, F_GETFL);
309         if (fa < 0)
310                 return -errno;
311
312         fb = fcntl(b, F_GETFL);
313         if (fb < 0)
314                 return -errno;
315
316         return fa == fb;
317 }
318
319 void cmsg_close_all(struct msghdr *mh) {
320         struct cmsghdr *cmsg;
321
322         assert(mh);
323
324         CMSG_FOREACH(cmsg, mh)
325                 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
326                         close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
327 }
328
329 bool fdname_is_valid(const char *s) {
330         const char *p;
331
332         /* Validates a name for $LISTEN_FDNAMES. We basically allow
333          * everything ASCII that's not a control character. Also, as
334          * special exception the ":" character is not allowed, as we
335          * use that as field separator in $LISTEN_FDNAMES.
336          *
337          * Note that the empty string is explicitly allowed
338          * here. However, we limit the length of the names to 255
339          * characters. */
340
341         if (!s)
342                 return false;
343
344         for (p = s; *p; p++) {
345                 if (*p < ' ')
346                         return false;
347                 if (*p >= 127)
348                         return false;
349                 if (*p == ':')
350                         return false;
351         }
352
353         return p - s < 256;
354 }
355 #endif // 0