diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/utils/utils.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c index 9b516accd..55eab8e14 100644 --- a/src/libstrongswan/utils/utils.c +++ b/src/libstrongswan/utils/utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -16,15 +16,23 @@ #include "utils.h" +#include <sys/types.h> #include <unistd.h> #include <limits.h> +#include <ctype.h> #ifndef WIN32 # include <signal.h> #endif +#ifndef HAVE_CLOSEFROM +# include <dirent.h> +#endif + #include <library.h> #include <collections/enumerator.h> +#define FD_DIR "/proc/self/fd" + #ifdef WIN32 #include <threading/mutex.h> @@ -110,43 +118,47 @@ void wait_sigint() /** * Described in header. */ -void closefrom(int lowfd) +void closefrom(int low_fd) { - char fd_dir[PATH_MAX]; - int maxfd, fd, len; - - /* try to close only open file descriptors on Linux... */ - len = snprintf(fd_dir, sizeof(fd_dir), "/proc/%u/fd", getpid()); - if (len > 0 && len < sizeof(fd_dir) && access(fd_dir, F_OK) == 0) + DIR *dir; + struct dirent *entry; + int max_fd, dir_fd, fd; + + /* try to close only open file descriptors on Linux... This is potentially + * unsafe when called after fork() in multi-threaded applications. In + * particular opendir() will require an allocation. So it depends on how + * the malloc() implementation handles such situations */ + dir = opendir(FD_DIR); + if (dir) { - enumerator_t *enumerator = enumerator_create_directory(fd_dir); - if (enumerator) + dir_fd = dirfd(dir); + while ((entry = readdir(dir))) { - char *rel; - while (enumerator->enumerate(enumerator, &rel, NULL, NULL)) + if (!isdigit(entry->d_name[0])) + { + continue; + } + fd = atoi(entry->d_name); + if (fd != dir_fd && fd >= low_fd) { - fd = atoi(rel); - if (fd >= lowfd) - { - close(fd); - } + close(fd); } - enumerator->destroy(enumerator); - return; } + closedir(dir); + return; } /* ...fall back to closing all fds otherwise */ #ifdef WIN32 - maxfd = _getmaxstdio(); + max_fd = _getmaxstdio(); #else - maxfd = (int)sysconf(_SC_OPEN_MAX); + max_fd = (int)sysconf(_SC_OPEN_MAX); #endif - if (maxfd < 0) + if (max_fd < 0) { - maxfd = 256; + max_fd = 256; } - for (fd = lowfd; fd < maxfd; fd++) + for (fd = low_fd; fd < max_fd; fd++) { close(fd); } |