2 * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
3 * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
5 #include "cmogstored.h"
6 bool mog_cloexec_atomic
;
9 * The presence of O_CLOEXEC in headers doesn't mean the kernel supports it
11 #if defined(O_CLOEXEC) && (O_CLOEXEC != 0) && \
12 defined(SOCK_CLOEXEC) && \
14 __attribute__((constructor
)) static void cloexec_detect(void)
17 int fd
= open("/dev/null", O_RDONLY
|O_CLOEXEC
);
20 if (errno
== EINVAL
) goto out
;
21 die_errno("open(/dev/null) failed");
24 flags
= fcntl(fd
, F_GETFD
);
26 mog_cloexec_atomic
= ((flags
& FD_CLOEXEC
) == FD_CLOEXEC
);
29 if (! mog_cloexec_atomic
) goto out
;
31 /* try to ensure sockets are sane, too */
32 fd
= socket(AF_INET
, SOCK_STREAM
|SOCK_CLOEXEC
, 0);
34 if (errno
== EINVAL
) goto out
;
35 die_errno("socket(AF_INET, ...) failed");
37 flags
= fcntl(fd
, F_GETFD
);
39 mog_cloexec_atomic
= ((flags
& FD_CLOEXEC
) == FD_CLOEXEC
);
43 if (mog_cloexec_atomic
)
46 warn("close-on-exec is NOT atomic");
48 #endif /* no O_CLOEXEC at all */