]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: turn off O_NONBLOCK on stdio fds when rearranging fds
authorLennart Poettering <lennart@poettering.net>
Mon, 8 Jan 2024 21:25:22 +0000 (22:25 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 8 Jan 2024 22:23:42 +0000 (23:23 +0100)
We often create our fds O_NONBLOCK, but when we want to invoke some
program with them as stdin/stdout/stderr we really should turn it off
again.

src/basic/fd-util.c
src/basic/fd-util.h
src/basic/process-util.c

index 1a279690d245c678b6e11612adb697e52584b6b5..38866ebb78253b409e06d82385dce9df719b3612 100644 (file)
@@ -170,6 +170,19 @@ int fd_nonblock(int fd, bool nonblock) {
         return RET_NERRNO(fcntl(fd, F_SETFL, nflags));
 }
 
+int stdio_disable_nonblock(void) {
+        int ret = 0;
+
+        /* stdin/stdout/stderr really should have O_NONBLOCK, which would confuse apps if left on, as
+         * write()s might unexpectedly fail with EAGAIN. */
+
+        RET_GATHER(ret, fd_nonblock(STDIN_FILENO, false));
+        RET_GATHER(ret, fd_nonblock(STDOUT_FILENO, false));
+        RET_GATHER(ret, fd_nonblock(STDERR_FILENO, false));
+
+        return ret;
+}
+
 int fd_cloexec(int fd, bool cloexec) {
         int flags, nflags;
 
index 4bdd61fe54350dce2408cd1e004241811b5d58de..6a1143b4f301ee8bf0237fb99caa6f209edcb41c 100644 (file)
@@ -62,6 +62,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(DIR*, closedir, NULL);
 #define _cleanup_close_pair_ _cleanup_(close_pairp)
 
 int fd_nonblock(int fd, bool nonblock);
+int stdio_disable_nonblock(void);
+
 int fd_cloexec(int fd, bool cloexec);
 int fd_cloexec_many(const int fds[], size_t n_fds, bool cloexec);
 
index 4d5c01d2cffec0815a8553037f9157b110bf7977..0f6cace426d4626ce579cf7ed8f3b8bfff28fec1 100644 (file)
@@ -1667,6 +1667,9 @@ int safe_fork_full(
                                 log_full_errno(prio, r, "Failed to rearrange stdio fds: %m");
                                 _exit(EXIT_FAILURE);
                         }
+
+                        /* Turn off O_NONBLOCK on the fdio fds, in case it was left on */
+                        stdio_disable_nonblock();
                 } else {
                         r = make_null_stdio();
                         if (r < 0) {