diff options
author | Volker Lendecke <vl@samba.org> | 2014-07-29 20:35:10 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-08-01 22:11:46 +0200 |
commit | 2dd8b6b25c76bd426ea0ed9fa9cce6cc09297503 (patch) | |
tree | 6922f1a61da9044838957c4c7a618213a9e6239d /lib | |
parent | 9b24abe2f7961c6c54ddc9cd90ff09bf429dd3c0 (diff) | |
download | samba-2dd8b6b25c76bd426ea0ed9fa9cce6cc09297503.tar.gz |
lib: Add close_low_fd
This factors out the essential code from close_low_fds for one file
descriptor: Redirect a fd to /dev/null
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/util/become_daemon.c | 43 | ||||
-rw-r--r-- | lib/util/samba_util.h | 5 |
2 files changed, 48 insertions, 0 deletions
diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c index 0671a1ef8ed..eba0cae579e 100644 --- a/lib/util/become_daemon.c +++ b/lib/util/become_daemon.c @@ -32,6 +32,49 @@ Close the low 3 fd's and open dev/null in their place. ********************************************************************/ +_PUBLIC_ int close_low_fd(int fd) +{ +#ifndef VALGRIND + int ret, dev_null; + + dev_null = open("/dev/null", O_RDWR, 0); + + if ((dev_null == -1) && (errno = ENFILE)) { + /* + * Try to free up an fd + */ + ret = close(fd); + if (ret != 0) { + return errno; + } + } + + dev_null = open("/dev/null", O_RDWR, 0); + if (dev_null == -1) { + dev_null = open("/dev/null", O_WRONLY, 0); + } + if (dev_null == -1) { + return errno; + } + + if (dev_null == fd) { + /* + * This can happen in the ENFILE case above + */ + return 0; + } + + ret = dup2(dev_null, fd); + if (ret == -1) { + int err = errno; + close(dev_null); + return err; + } + close(dev_null); +#endif + return 0; +} + _PUBLIC_ void close_low_fds(bool stdin_too, bool stdout_too, bool stderr_too) { #ifndef VALGRIND diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index 2ffe028959b..b31ee1f8f0a 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -839,6 +839,11 @@ _PUBLIC_ int idr_remove(struct idr_context *idp, int id); /* The following definitions come from lib/util/become_daemon.c */ /** + Close a fd and open dev/null in its place +**/ +_PUBLIC_ int close_low_fd(int fd); + +/** Close the low 3 fd's and open dev/null in their place **/ _PUBLIC_ void close_low_fds(bool stdin_too, bool stdout_too, bool stderr_too); |