From: Timo Sirainen Date: Mon, 14 Nov 2016 13:48:20 +0000 (+0100) Subject: lib-master: Make sure stdin/stdout/stderr fds are open. X-Git-Tag: 2.2.27~175 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7071e573857ed73dfa9a63036aaedfeb23a8f130;p=thirdparty%2Fdovecot%2Fcore.git lib-master: Make sure stdin/stdout/stderr fds are open. We'll just open /dev/null for them if they don't already exist. --- diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index 2a00c35a4c..fb01df6332 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -20,6 +20,7 @@ #include "master-service-settings.h" #include +#include #include #include @@ -166,6 +167,28 @@ master_service_init(const char *name, enum master_service_flags flags, fd_debug_verify_leaks(MASTER_LISTEN_FD_FIRST + count, 1024); } #endif + /* Make sure stdin, stdout and stderr fds exist. We especially rely on + stderr being available and a lot of code doesn't like fd being 0. + We'll open /dev/null as write-only also for stdin, since if any + reads are attempted from it we'll want them to fail. */ + for (int fd = 0; fd <= 2; fd++) { + struct stat st; + + if (fstat(fd, &st) < 0 && errno == EBADF) { + int null_fd = open("/dev/null", O_WRONLY); + if (null_fd == -1) + i_fatal("Can't open /dev/null: %m"); + else if (null_fd != fd) { + /* we don't really expect this to happen. + POSIX guarantees that open() returns the + lowest numbered fd. So this would only mean + that fstat() returned EBADF for a fd that + actually existed. */ + if (close(null_fd) < 0) + i_error("close(/dev/null) failed: %m"); + } + } + } if ((flags & MASTER_SERVICE_FLAG_STANDALONE) == 0) { /* make sure we can dump core, at least until privileges are dropped. (i'm not really sure why this