00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023
00024 #if !defined HAVE_CLOSEFROM && !defined __WIN32__
00025
00026 #include "closefrom.h"
00027
00028 #include "safeerrno.h"
00029 #include "safefcntl.h"
00030 #include "safeunistd.h"
00031
00032 #if defined __linux__ || defined __APPLE__
00033 # include "safedirent.h"
00034 # include <cstdlib>
00035
00036 using namespace std;
00037 #endif
00038
00039 void
00040 Xapian::Internal::closefrom(int fd)
00041 {
00042 #ifdef F_CLOSEM
00043
00044 if (fcntl(fd, F_CLOSEM, 0) >= 0)
00045 return;
00046 #elif defined __linux__ || defined __APPLE__
00047
00048
00049
00050
00051 #if !defined HAVE_DIRFD && !defined dirfd
00052
00053
00054
00055 while (close(fd) < 0 && errno == EINTR) { }
00056 ++fd;
00057 #endif
00058 #if 0
00059
00060
00061
00062 string path = "/proc/";
00063 path += str(getpid());
00064 path += "/fd";
00065 DIR * dir = opendir(path.c_str());
00066 #elif defined __linux__
00067 DIR * dir = opendir("/proc/self/fd");
00068 #elif defined __APPLE__ // Mac OS X
00069 DIR * dir = opendir("/dev/fd");
00070 #endif
00071 if (dir) {
00072 while (true) {
00073 errno = 0;
00074 struct dirent *entry = readdir(dir);
00075 if (entry == NULL) {
00076 closedir(dir);
00077
00078 if (errno) break;
00079 return;
00080 }
00081 char ch;
00082 ch = entry->d_name[0];
00083 if (ch < '0' || ch > '9')
00084 continue;
00085 int n = atoi(entry->d_name);
00086 if (n >= fd) {
00087 #if defined HAVE_DIRFD || defined dirfd
00088 if (n == dirfd(dir)) continue;
00089 #endif
00090
00091 while (close(n) < 0 && errno == EINTR) { }
00092 }
00093 }
00094 }
00095 #endif
00096 int maxfd = -1;
00097 #ifdef F_MAXFD
00098 maxfd = fcntl(0, F_MAXFD);
00099 #endif
00100 if (maxfd < 0)
00101 maxfd = static_cast<int>(sysconf(_SC_OPEN_MAX));
00102 while (fd < maxfd) {
00103
00104
00105 while (close(fd) < 0 && errno == EINTR) { }
00106 ++fd;
00107 }
00108 }
00109
00110 #endif