summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-07-29 20:35:10 +0200
committerJeremy Allison <jra@samba.org>2014-08-01 22:11:46 +0200
commit2dd8b6b25c76bd426ea0ed9fa9cce6cc09297503 (patch)
tree6922f1a61da9044838957c4c7a618213a9e6239d /lib
parent9b24abe2f7961c6c54ddc9cd90ff09bf429dd3c0 (diff)
downloadsamba-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.c43
-rw-r--r--lib/util/samba_util.h5
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);