"MESSAGE_ID=" SD_MESSAGE_CORE_FD_SET_FAILED_STR);
}
- (void) fdset_cloexec(*ret_fds, true);
-
/* The serialization fd should have O_CLOEXEC turned on already, let's verify that we didn't pick it up here */
assert_se(!arg_serialization || !fdset_contains(*ret_fds, fileno(arg_serialization)));
r = fdset_new_fill(/* filter_cloexec= */ 0, &passed);
if (r < 0)
return log_error_errno(r, "Failed to take possession of passed file descriptors: %m");
-
- r = fdset_cloexec(passed, true);
- if (r < 0)
- return log_error_errno(r, "Failed to enable O_CLOEXEC for passed file descriptors: %m");
}
if (fdnr < 3) {
int fdset_new_fill(
int filter_cloexec, /* if < 0 takes all fds, otherwise only those with O_CLOEXEC set (1) or unset (0) */
FDSet **ret) {
+
_cleanup_(fdset_shallow_freep) FDSet *s = NULL;
_cleanup_closedir_ DIR *d = NULL;
int r;
assert(ret);
- /* Creates an fdset and fills in all currently open file descriptors. */
+ /* Creates an fdset and fills in all currently open file descriptors. Also set all collected fds
+ * to CLOEXEC. */
d = opendir("/proc/self/fd");
if (!d) {
/* If user asked for that filter by O_CLOEXEC. This is useful so that fds that have
* been passed in can be collected and fds which have been created locally can be
* ignored, under the assumption that only the latter have O_CLOEXEC set. */
+
fl = fcntl(fd, F_GETFD);
if (fl < 0)
return -errno;
continue;
}
+ /* We need to set CLOEXEC manually only if we're collecting non-CLOEXEC fds. */
+ if (filter_cloexec <= 0) {
+ r = fd_cloexec(fd, true);
+ if (r < 0)
+ return r;
+ }
+
r = fdset_put(s, fd);
if (r < 0)
return r;
#include "tmpfile-util.h"
TEST(fdset_new_fill) {
- int fd = -EBADF;
_cleanup_fdset_free_ FDSet *fdset = NULL;
+ int fd = -EBADF, flags;
log_close();
log_set_open_when_needed(true);
assert_se(fdset_new_fill(/* filter_cloexec= */ 0, &fdset) >= 0);
assert_se(fdset_contains(fdset, fd));
+ flags = fcntl(fd, F_GETFD);
+ assert_se(flags >= 0);
+ assert_se(FLAGS_SET(flags, FD_CLOEXEC));
fdset = fdset_free(fdset);
assert_se(fcntl(fd, F_GETFD) < 0);
assert_se(errno == EBADF);