From: Timo Sirainen Date: Wed, 16 Nov 2016 09:40:35 +0000 (+0200) Subject: lib: Add fd_close_maybe_stdio() X-Git-Tag: 2.2.27~151 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=58bd9504a72311e5b8b6cd6c4ff1b20ef2ee6b9f;p=thirdparty%2Fdovecot%2Fcore.git lib: Add fd_close_maybe_stdio() The idea is that this should be used whenever closing fds that may be 0 or 1. If they are closed normally, the following code may end up using 0/1 fd for other purposes, which could cause problems. --- diff --git a/src/lib/lib.c b/src/lib/lib.c index c1605cad8c..0b40fb1643 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -34,6 +34,25 @@ int close_keep_errno(int *fd) return ret; } +void fd_close_maybe_stdio(int *fd_in, int *fd_out) +{ + int *fdp[2] = { fd_in, fd_out }; + + if (*fd_in == *fd_out) + *fd_in = -1; + + for (unsigned int i = 0; i < N_ELEMENTS(fdp); i++) { + if (*fdp[i] == -1) + ; + else if (*fdp[i] > 1) + i_close_fd(fdp[i]); + else if (dup2(dev_null_fd, *fdp[i]) == *fdp[i]) + *fdp[i] = -1; + else + i_fatal("dup2(/dev/null, %d) failed: %m", *fdp[i]); + } +} + #undef i_unlink int i_unlink(const char *path, const char *source_fname, unsigned int source_linenum) diff --git a/src/lib/lib.h b/src/lib/lib.h index 1581924759..fa386892ae 100644 --- a/src/lib/lib.h +++ b/src/lib/lib.h @@ -54,6 +54,10 @@ typedef void lib_atexit_callback_t(void); extern int dev_null_fd; int close_keep_errno(int *fd); +/* Close fd_in and fd_out, unless they're already -1. They can point to the + same fd, in which case they're closed only once. If they point to stdin + or stdout, they're replaced with /dev/null. */ +void fd_close_maybe_stdio(int *fd_in, int *fd_out); /* Call unlink(). If it fails, log an error including the source filename and line number. */ int i_unlink(const char *path, const char *source_fname,