]>
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 "process-util.h"
35 #include "socket-util.h"
36 #include "stdio-util.h"
39 int close_nointr(int fd
) {
46 * Just ignore EINTR; a retry loop is the wrong thing to do on
49 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
50 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
51 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
52 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
60 int safe_close(int fd
) {
63 * Like close_nointr() but cannot fail. Guarantees errno is
64 * unchanged. Is a NOP with negative fds passed, and returns
65 * -1, so that it can be used in this syntax:
67 * fd = safe_close(fd);
73 /* The kernel might return pretty much any error code
74 * via close(), but the fd will be closed anyway. The
75 * only condition we want to check for here is whether
76 * the fd was invalid at all... */
78 assert_se(close_nointr(fd
) != -EBADF
);
84 void safe_close_pair(int p
[]) {
88 /* Special case pairs which use the same fd in both
90 p
[0] = p
[1] = safe_close(p
[0]);
94 p
[0] = safe_close(p
[0]);
95 p
[1] = safe_close(p
[1]);
98 void close_many(const int fds
[], unsigned n_fd
) {
101 assert(fds
|| n_fd
<= 0);
103 for (i
= 0; i
< n_fd
; i
++)
107 int fclose_nointr(FILE *f
) {
110 /* Same as close_nointr(), but for fclose() */
121 FILE* safe_fclose(FILE *f
) {
123 /* Same as safe_close(), but for fclose() */
128 assert_se(fclose_nointr(f
) != EBADF
);
134 DIR* safe_closedir(DIR *d
) {
139 assert_se(closedir(d
) >= 0 || errno
!= EBADF
);
145 int fd_nonblock(int fd
, bool nonblock
) {
150 flags
= fcntl(fd
, F_GETFL
, 0);
155 nflags
= flags
| O_NONBLOCK
;
157 nflags
= flags
& ~O_NONBLOCK
;
162 if (fcntl(fd
, F_SETFL
, nflags
) < 0)
168 int fd_cloexec(int fd
, bool cloexec
) {
173 flags
= fcntl(fd
, F_GETFD
, 0);
178 nflags
= flags
| FD_CLOEXEC
;
180 nflags
= flags
& ~FD_CLOEXEC
;
185 if (fcntl(fd
, F_SETFD
, nflags
) < 0)
191 void stdio_unset_cloexec(void) {
192 fd_cloexec(STDIN_FILENO
, false);
193 fd_cloexec(STDOUT_FILENO
, false);
194 fd_cloexec(STDERR_FILENO
, false);
197 _pure_
static bool fd_in_set(int fd
, const int fdset
[], unsigned n_fdset
) {
200 assert(n_fdset
== 0 || fdset
);
202 for (i
= 0; i
< n_fdset
; i
++)
209 int close_all_fds(const int except
[], unsigned n_except
) {
210 _cleanup_closedir_
DIR *d
= NULL
;
214 assert(n_except
== 0 || except
);
216 d
= opendir("/proc/self/fd");
221 /* When /proc isn't available (for example in chroots)
222 * the fallback is brute forcing through the fd
225 assert_se(getrlimit(RLIMIT_NOFILE
, &rl
) >= 0);
226 for (fd
= 3; fd
< (int) rl
.rlim_max
; fd
++) {
228 if (fd_in_set(fd
, except
, n_except
))
231 if (close_nointr(fd
) < 0)
232 if (errno
!= EBADF
&& r
== 0)
239 FOREACH_DIRENT(de
, d
, return -errno
) {
242 if (safe_atoi(de
->d_name
, &fd
) < 0)
243 /* Let's better ignore this, just in case */
252 if (fd_in_set(fd
, except
, n_except
))
255 if (close_nointr(fd
) < 0) {
256 /* Valgrind has its own FD and doesn't want to have it closed */
257 if (errno
!= EBADF
&& r
== 0)
265 int same_fd(int a
, int b
) {
266 struct stat sta
, stb
;
273 /* Compares two file descriptors. Note that semantics are
274 * quite different depending on whether we have kcmp() or we
275 * don't. If we have kcmp() this will only return true for
276 * dup()ed file descriptors, but not otherwise. If we don't
277 * have kcmp() this will also return true for two fds of the same
278 * file, created by separate open() calls. Since we use this
279 * call mostly for filtering out duplicates in the fd store
280 * this difference hopefully doesn't matter too much. */
285 /* Try to use kcmp() if we have it. */
286 pid
= getpid_cached();
287 r
= kcmp(pid
, pid
, KCMP_FILE
, a
, b
);
295 /* We don't have kcmp(), use fstat() instead. */
296 if (fstat(a
, &sta
) < 0)
299 if (fstat(b
, &stb
) < 0)
302 if ((sta
.st_mode
& S_IFMT
) != (stb
.st_mode
& S_IFMT
))
305 /* We consider all device fds different, since two device fds
306 * might refer to quite different device contexts even though
307 * they share the same inode and backing dev_t. */
309 if (S_ISCHR(sta
.st_mode
) || S_ISBLK(sta
.st_mode
))
312 if (sta
.st_dev
!= stb
.st_dev
|| sta
.st_ino
!= stb
.st_ino
)
315 /* The fds refer to the same inode on disk, let's also check
316 * if they have the same fd flags. This is useful to
317 * distinguish the read and write side of a pipe created with
319 fa
= fcntl(a
, F_GETFL
);
323 fb
= fcntl(b
, F_GETFL
);
330 void cmsg_close_all(struct msghdr
*mh
) {
331 struct cmsghdr
*cmsg
;
335 CMSG_FOREACH(cmsg
, mh
)
336 if (cmsg
->cmsg_level
== SOL_SOCKET
&& cmsg
->cmsg_type
== SCM_RIGHTS
)
337 close_many((int*) CMSG_DATA(cmsg
), (cmsg
->cmsg_len
- CMSG_LEN(0)) / sizeof(int));
340 bool fdname_is_valid(const char *s
) {
343 /* Validates a name for $LISTEN_FDNAMES. We basically allow
344 * everything ASCII that's not a control character. Also, as
345 * special exception the ":" character is not allowed, as we
346 * use that as field separator in $LISTEN_FDNAMES.
348 * Note that the empty string is explicitly allowed
349 * here. However, we limit the length of the names to 255
355 for (p
= s
; *p
; p
++) {
367 int fd_get_path(int fd
, char **ret
) {
368 char procfs_path
[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
371 xsprintf(procfs_path
, "/proc/self/fd/%i", fd
);
373 r
= readlink_malloc(procfs_path
, ret
);
375 if (r
== -ENOENT
) /* If the file doesn't exist the fd is invalid */