Blindly setting FD_CLOEXEC without a read-modify-write will
inadvertently clear any other intentionally-set bits, such as a
proposed new bit for designating a fd that must behave in 32-bit mode.
However, we cannot use our wrapper qemu_set_cloexec(), because that
wrapper intentionally abort()s on failure, whereas the probe here
intentionally tolerates failure to deal with incorrect socket
activation gracefully. Instead, fix the code to do the proper
read-modify-write.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <
20200420175309.75894-3-eblake@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
unsigned long nr_fds;
unsigned int i;
int fd;
+ int f;
int err;
s = getenv("LISTEN_PID");
/* So the file descriptors don't leak into child processes. */
for (i = 0; i < nr_fds; ++i) {
fd = FIRST_SOCKET_ACTIVATION_FD + i;
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
+ f = fcntl(fd, F_GETFD);
+ if (f == -1 || fcntl(fd, F_SETFD, f | FD_CLOEXEC) == -1) {
/* If we cannot set FD_CLOEXEC then it probably means the file
* descriptor is invalid, so socket activation has gone wrong
* and we should exit.