]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/fd-util.c
2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
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.
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.
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/>.
22 #include <sys/resource.h>
23 #include <sys/socket.h>
27 #include "dirent-util.h"
32 #include "parse-util.h"
33 #include "path-util.h"
34 #include "socket-util.h"
35 #include "stdio-util.h"
38 int close_nointr(int fd
) {
45 * Just ignore EINTR; a retry loop is the wrong thing to do on
48 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
49 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
50 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
51 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
59 int safe_close(int fd
) {
62 * Like close_nointr() but cannot fail. Guarantees errno is
63 * unchanged. Is a NOP with negative fds passed, and returns
64 * -1, so that it can be used in this syntax:
66 * fd = safe_close(fd);
72 /* The kernel might return pretty much any error code
73 * via close(), but the fd will be closed anyway. The
74 * only condition we want to check for here is whether
75 * the fd was invalid at all... */
77 assert_se(close_nointr(fd
) != -EBADF
);
83 void safe_close_pair(int p
[]) {
87 /* Special case pairs which use the same fd in both
89 p
[0] = p
[1] = safe_close(p
[0]);
93 p
[0] = safe_close(p
[0]);
94 p
[1] = safe_close(p
[1]);
97 void close_many(const int fds
[], unsigned n_fd
) {
100 assert(fds
|| n_fd
<= 0);
102 for (i
= 0; i
< n_fd
; i
++)
106 int fclose_nointr(FILE *f
) {
109 /* Same as close_nointr(), but for fclose() */
120 FILE* safe_fclose(FILE *f
) {
122 /* Same as safe_close(), but for fclose() */
127 assert_se(fclose_nointr(f
) != EBADF
);
133 DIR* safe_closedir(DIR *d
) {
138 assert_se(closedir(d
) >= 0 || errno
!= EBADF
);
144 int fd_nonblock(int fd
, bool nonblock
) {
149 flags
= fcntl(fd
, F_GETFL
, 0);
154 nflags
= flags
| O_NONBLOCK
;
156 nflags
= flags
& ~O_NONBLOCK
;
161 if (fcntl(fd
, F_SETFL
, nflags
) < 0)
167 int fd_cloexec(int fd
, bool cloexec
) {
172 flags
= fcntl(fd
, F_GETFD
, 0);
177 nflags
= flags
| FD_CLOEXEC
;
179 nflags
= flags
& ~FD_CLOEXEC
;
184 if (fcntl(fd
, F_SETFD
, nflags
) < 0)
190 void stdio_unset_cloexec(void) {
191 fd_cloexec(STDIN_FILENO
, false);
192 fd_cloexec(STDOUT_FILENO
, false);
193 fd_cloexec(STDERR_FILENO
, false);
196 _pure_
static bool fd_in_set(int fd
, const int fdset
[], unsigned n_fdset
) {
199 assert(n_fdset
== 0 || fdset
);
201 for (i
= 0; i
< n_fdset
; i
++)
208 int close_all_fds(const int except
[], unsigned n_except
) {
209 _cleanup_closedir_
DIR *d
= NULL
;
213 assert(n_except
== 0 || except
);
215 d
= opendir("/proc/self/fd");
220 /* When /proc isn't available (for example in chroots)
221 * the fallback is brute forcing through the fd
224 assert_se(getrlimit(RLIMIT_NOFILE
, &rl
) >= 0);
225 for (fd
= 3; fd
< (int) rl
.rlim_max
; fd
++) {
227 if (fd_in_set(fd
, except
, n_except
))
230 if (close_nointr(fd
) < 0)
231 if (errno
!= EBADF
&& r
== 0)
238 FOREACH_DIRENT(de
, d
, return -errno
) {
241 if (safe_atoi(de
->d_name
, &fd
) < 0)
242 /* Let's better ignore this, just in case */
251 if (fd_in_set(fd
, except
, n_except
))
254 if (close_nointr(fd
) < 0) {
255 /* Valgrind has its own FD and doesn't want to have it closed */
256 if (errno
!= EBADF
&& r
== 0)
264 int same_fd(int a
, int b
) {
265 struct stat sta
, stb
;
272 /* Compares two file descriptors. Note that semantics are
273 * quite different depending on whether we have kcmp() or we
274 * don't. If we have kcmp() this will only return true for
275 * dup()ed file descriptors, but not otherwise. If we don't
276 * have kcmp() this will also return true for two fds of the same
277 * file, created by separate open() calls. Since we use this
278 * call mostly for filtering out duplicates in the fd store
279 * this difference hopefully doesn't matter too much. */
284 /* Try to use kcmp() if we have it. */
286 r
= kcmp(pid
, pid
, KCMP_FILE
, a
, b
);
294 /* We don't have kcmp(), use fstat() instead. */
295 if (fstat(a
, &sta
) < 0)
298 if (fstat(b
, &stb
) < 0)
301 if ((sta
.st_mode
& S_IFMT
) != (stb
.st_mode
& S_IFMT
))
304 /* We consider all device fds different, since two device fds
305 * might refer to quite different device contexts even though
306 * they share the same inode and backing dev_t. */
308 if (S_ISCHR(sta
.st_mode
) || S_ISBLK(sta
.st_mode
))
311 if (sta
.st_dev
!= stb
.st_dev
|| sta
.st_ino
!= stb
.st_ino
)
314 /* The fds refer to the same inode on disk, let's also check
315 * if they have the same fd flags. This is useful to
316 * distinguish the read and write side of a pipe created with
318 fa
= fcntl(a
, F_GETFL
);
322 fb
= fcntl(b
, F_GETFL
);
329 void cmsg_close_all(struct msghdr
*mh
) {
330 struct cmsghdr
*cmsg
;
334 CMSG_FOREACH(cmsg
, mh
)
335 if (cmsg
->cmsg_level
== SOL_SOCKET
&& cmsg
->cmsg_type
== SCM_RIGHTS
)
336 close_many((int*) CMSG_DATA(cmsg
), (cmsg
->cmsg_len
- CMSG_LEN(0)) / sizeof(int));
339 bool fdname_is_valid(const char *s
) {
342 /* Validates a name for $LISTEN_FDNAMES. We basically allow
343 * everything ASCII that's not a control character. Also, as
344 * special exception the ":" character is not allowed, as we
345 * use that as field separator in $LISTEN_FDNAMES.
347 * Note that the empty string is explicitly allowed
348 * here. However, we limit the length of the names to 255
354 for (p
= s
; *p
; p
++) {
366 int fd_get_path(int fd
, char **ret
) {
367 char procfs_path
[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
370 xsprintf(procfs_path
, "/proc/self/fd/%i", fd
);
372 r
= readlink_malloc(procfs_path
, ret
);
374 if (r
== -ENOENT
) /* If the file doesn't exist the fd is invalid */