aboutsummaryrefslogtreecommitdiff
path: root/nscd/nscd.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-01-15 19:52:59 +0000
committerUlrich Drepper <drepper@redhat.com>2003-01-15 19:52:59 +0000
commitd439762939d51c4a35b3b44d77a57aa545452af7 (patch)
tree2c3e99073dfcd3054b8dee7bc8ebd5e50f6218be /nscd/nscd.c
parent9caf4f1c67e137804f4bca9eb65bd0132424022a (diff)
downloadglibc-d439762939d51c4a35b3b44d77a57aa545452af7.tar
glibc-d439762939d51c4a35b3b44d77a57aa545452af7.tar.gz
glibc-d439762939d51c4a35b3b44d77a57aa545452af7.tar.bz2
glibc-d439762939d51c4a35b3b44d77a57aa545452af7.zip
Update.
* nscd/nscd.c (main): Make code to close all file descriptors faster and more robust.
Diffstat (limited to 'nscd/nscd.c')
-rw-r--r--nscd/nscd.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/nscd/nscd.c b/nscd/nscd.c
index 5520e1a475..af4b181c7d 100644
--- a/nscd/nscd.c
+++ b/nscd/nscd.c
@@ -21,10 +21,13 @@
#include <argp.h>
#include <assert.h>
+#include <dirent.h>
#include <errno.h>
#include <error.h>
+#include <fcntl.h>
#include <libintl.h>
#include <locale.h>
+#include <paths.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
@@ -33,10 +36,12 @@
#include <syslog.h>
#include <unistd.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/un.h>
#include "dbg_log.h"
#include "nscd.h"
+#include <device-nrs.h>
/* Get libc version number. */
#include <version.h>
@@ -133,8 +138,54 @@ main (int argc, char **argv)
if (fork ())
exit (0);
- for (i = 0; i < getdtablesize (); i++)
- close (i);
+ int nullfd = open (_PATH_DEVNULL, O_RDWR);
+ if (nullfd != -1)
+ {
+ struct stat64 st;
+
+ if (fstat64 (nullfd, &st) == 0 && S_ISCHR (st.st_mode) != 0
+#if defined DEV_NULL_MAJOR && defined DEV_NULL_MINOR
+ && st.st_rdev == makedev (DEV_NULL_MAJOR, DEV_NULL_MINOR)
+#endif
+ )
+ {
+ /* It is the /dev/null special device alright. */
+ (void) dup2 (nullfd, STDIN_FILENO);
+ (void) dup2 (nullfd, STDOUT_FILENO);
+ (void) dup2 (nullfd, STDERR_FILENO);
+
+ if (nullfd > 2)
+ close (nullfd);
+ }
+ else
+ {
+ /* Ugh, somebody is trying to play a trick on us. */
+ close (nullfd);
+ nullfd = -1;
+ }
+ }
+ int min_close_fd = nullfd == -1 ? 0 : STDERR_FILENO + 1;
+
+ DIR *d = opendir ("/proc/self/fd");
+ if (d != NULL)
+ {
+ struct dirent64 *dirent;
+ int dfdn = dirfd (d);
+
+ while ((dirent = readdir64 (d)) != NULL)
+ {
+ char *endp;
+ unsigned long int fdn = strtoul (dirent->d_name, &endp, 10);
+
+ if (*endp == '\0' && fdn != dfdn && fdn >= min_close_fd)
+ close ((int) fdn);
+ }
+
+ closedir (d);
+ }
+ else
+ for (i = min_close_fd; i < getdtablesize (); i++)
+ close (i);
if (fork ())
exit (0);