]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/fd-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/resource.h>
24 #include <sys/socket.h>
28 #include "dirent-util.h"
33 #include "parse-util.h"
34 #include "path-util.h"
35 #include "process-util.h"
36 #include "socket-util.h"
37 #include "stdio-util.h"
40 int close_nointr(int fd
) {
47 * Just ignore EINTR; a retry loop is the wrong thing to do on
50 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
51 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
52 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
53 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
61 int safe_close(int fd
) {
64 * Like close_nointr() but cannot fail. Guarantees errno is
65 * unchanged. Is a NOP with negative fds passed, and returns
66 * -1, so that it can be used in this syntax:
68 * fd = safe_close(fd);
74 /* The kernel might return pretty much any error code
75 * via close(), but the fd will be closed anyway. The
76 * only condition we want to check for here is whether
77 * the fd was invalid at all... */
79 assert_se(close_nointr(fd
) != -EBADF
);
85 void safe_close_pair(int p
[]) {
89 /* Special case pairs which use the same fd in both
91 p
[0] = p
[1] = safe_close(p
[0]);
95 p
[0] = safe_close(p
[0]);
96 p
[1] = safe_close(p
[1]);
99 void close_many(const int fds
[], unsigned n_fd
) {
102 assert(fds
|| n_fd
<= 0);
104 for (i
= 0; i
< n_fd
; i
++)
108 int fclose_nointr(FILE *f
) {
111 /* Same as close_nointr(), but for fclose() */
122 FILE* safe_fclose(FILE *f
) {
124 /* Same as safe_close(), but for fclose() */
129 assert_se(fclose_nointr(f
) != EBADF
);
135 DIR* safe_closedir(DIR *d
) {
140 assert_se(closedir(d
) >= 0 || errno
!= EBADF
);
146 int fd_nonblock(int fd
, bool nonblock
) {
151 flags
= fcntl(fd
, F_GETFL
, 0);
156 nflags
= flags
| O_NONBLOCK
;
158 nflags
= flags
& ~O_NONBLOCK
;
163 if (fcntl(fd
, F_SETFL
, nflags
) < 0)
169 int fd_cloexec(int fd
, bool cloexec
) {
174 flags
= fcntl(fd
, F_GETFD
, 0);
179 nflags
= flags
| FD_CLOEXEC
;
181 nflags
= flags
& ~FD_CLOEXEC
;
186 if (fcntl(fd
, F_SETFD
, nflags
) < 0)
192 void stdio_unset_cloexec(void) {
193 fd_cloexec(STDIN_FILENO
, false);
194 fd_cloexec(STDOUT_FILENO
, false);
195 fd_cloexec(STDERR_FILENO
, false);
198 _pure_
static bool fd_in_set(int fd
, const int fdset
[], unsigned n_fdset
) {
201 assert(n_fdset
== 0 || fdset
);
203 for (i
= 0; i
< n_fdset
; i
++)
210 int close_all_fds(const int except
[], unsigned n_except
) {
211 _cleanup_closedir_
DIR *d
= NULL
;
215 assert(n_except
== 0 || except
);
217 d
= opendir("/proc/self/fd");
222 /* When /proc isn't available (for example in chroots)
223 * the fallback is brute forcing through the fd
226 assert_se(getrlimit(RLIMIT_NOFILE
, &rl
) >= 0);
227 for (fd
= 3; fd
< (int) rl
.rlim_max
; fd
++) {
229 if (fd_in_set(fd
, except
, n_except
))
232 if (close_nointr(fd
) < 0)
233 if (errno
!= EBADF
&& r
== 0)
240 FOREACH_DIRENT(de
, d
, return -errno
) {
243 if (safe_atoi(de
->d_name
, &fd
) < 0)
244 /* Let's better ignore this, just in case */
253 if (fd_in_set(fd
, except
, n_except
))
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)
266 int same_fd(int a
, int b
) {
267 struct stat sta
, stb
;
274 /* Compares two file descriptors. Note that semantics are
275 * quite different depending on whether we have kcmp() or we
276 * don't. If we have kcmp() this will only return true for
277 * dup()ed file descriptors, but not otherwise. If we don't
278 * have kcmp() this will also return true for two fds of the same
279 * file, created by separate open() calls. Since we use this
280 * call mostly for filtering out duplicates in the fd store
281 * this difference hopefully doesn't matter too much. */
286 /* Try to use kcmp() if we have it. */
287 pid
= getpid_cached();
288 r
= kcmp(pid
, pid
, KCMP_FILE
, a
, b
);
296 /* We don't have kcmp(), use fstat() instead. */
297 if (fstat(a
, &sta
) < 0)
300 if (fstat(b
, &stb
) < 0)
303 if ((sta
.st_mode
& S_IFMT
) != (stb
.st_mode
& S_IFMT
))
306 /* We consider all device fds different, since two device fds
307 * might refer to quite different device contexts even though
308 * they share the same inode and backing dev_t. */
310 if (S_ISCHR(sta
.st_mode
) || S_ISBLK(sta
.st_mode
))
313 if (sta
.st_dev
!= stb
.st_dev
|| sta
.st_ino
!= stb
.st_ino
)
316 /* The fds refer to the same inode on disk, let's also check
317 * if they have the same fd flags. This is useful to
318 * distinguish the read and write side of a pipe created with
320 fa
= fcntl(a
, F_GETFL
);
324 fb
= fcntl(b
, F_GETFL
);
331 void cmsg_close_all(struct msghdr
*mh
) {
332 struct cmsghdr
*cmsg
;
336 CMSG_FOREACH(cmsg
, mh
)
337 if (cmsg
->cmsg_level
== SOL_SOCKET
&& cmsg
->cmsg_type
== SCM_RIGHTS
)
338 close_many((int*) CMSG_DATA(cmsg
), (cmsg
->cmsg_len
- CMSG_LEN(0)) / sizeof(int));
341 bool fdname_is_valid(const char *s
) {
344 /* Validates a name for $LISTEN_FDNAMES. We basically allow
345 * everything ASCII that's not a control character. Also, as
346 * special exception the ":" character is not allowed, as we
347 * use that as field separator in $LISTEN_FDNAMES.
349 * Note that the empty string is explicitly allowed
350 * here. However, we limit the length of the names to 255
356 for (p
= s
; *p
; p
++) {
368 int fd_get_path(int fd
, char **ret
) {
369 char procfs_path
[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
372 xsprintf(procfs_path
, "/proc/self/fd/%i", fd
);
374 r
= readlink_malloc(procfs_path
, ret
);
376 if (r
== -ENOENT
) /* If the file doesn't exist the fd is invalid */