From: Lennart Poettering Date: Thu, 28 Jul 2011 03:33:46 +0000 (+0200) Subject: sysdeps-unix: introduce dbus_close_all() and make use of it where appropriate X-Git-Tag: dbus-1.5.12~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1a4d710d67391c1d7be2d7db6313e6c118acc773;p=platform%2Fupstream%2Fdbus.git sysdeps-unix: introduce dbus_close_all() and make use of it where appropriate This is optimized on Linux and enumerates through /proc/self/fd with a fallback on brute-force closing of fds, in case /proc is not available. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=35230 Reviewed-by: Simon McVittie --- diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index da3f035..5770812 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -3124,7 +3124,6 @@ _read_subprocess_line_argv (const char *progpath, int ret; int status; int orig_len; - int i; dbus_bool_t retval; sigset_t new_set, old_set; @@ -3177,7 +3176,6 @@ _read_subprocess_line_argv (const char *progpath, if (pid == 0) { /* child process */ - int maxfds; int fd; fd = open ("/dev/null", O_RDWR); @@ -3201,15 +3199,7 @@ _read_subprocess_line_argv (const char *progpath, if (dup2 (errors_pipe[WRITE_END], 2) == -1) _exit (1); - maxfds = sysconf (_SC_OPEN_MAX); - /* Pick something reasonable if for some reason sysconf - * says unlimited. - */ - if (maxfds < 0) - maxfds = 1024; - /* close all inherited fds */ - for (i = 3; i < maxfds; i++) - close (i); + _dbus_close_all (); sigprocmask (SIG_SETMASK, &old_set, NULL); @@ -3920,4 +3910,69 @@ _dbus_replace_install_prefix (const char *configure_time_path) return configure_time_path; } +/** + * Closes all file descriptors except the first three (i.e. stdin, + * stdout, stderr). + */ +void +_dbus_close_all (void) +{ + int maxfds, i; + +#ifdef __linux__ + DIR *d; + + /* On Linux we can optimize this a bit if /proc is available. If it + isn't available, fall back to the brute force way. */ + + d = opendir ("/proc/self/fd"); + if (d) + { + for (;;) + { + struct dirent buf, *de; + int k, fd; + long l; + char *e = NULL; + + k = readdir_r (d, &buf, &de); + if (k != 0 || !de) + break; + + if (de->d_name[0] == '.') + continue; + + errno = 0; + l = strtol (de->d_name, &e, 10); + if (errno != 0 || e == NULL || *e != '\0') + continue; + + fd = (int) l; + if (fd < 3) + continue; + + if (fd == dirfd (d)) + continue; + + close (fd); + } + + closedir (d); + return; + } +#endif + + maxfds = sysconf (_SC_OPEN_MAX); + + /* Pick something reasonable if for some reason sysconf says + * unlimited. + */ + if (maxfds < 0) + maxfds = 1024; + + /* close all inherited fds */ + for (i = 3; i < maxfds; i++) + close (i); +} + /* tests in dbus-sysdeps-util.c */ diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h index 9f92dcd..fbe5259 100644 --- a/dbus/dbus-sysdeps-unix.h +++ b/dbus/dbus-sysdeps-unix.h @@ -132,6 +132,8 @@ dbus_uid_t _dbus_geteuid (void); dbus_bool_t _dbus_parse_uid (const DBusString *uid_str, dbus_uid_t *uid); +void _dbus_close_all (void); + /** @} */ DBUS_END_DECLS