| 917 | } |
| 918 | |
| 919 | void Utility::CloseAllFDs(const std::vector<int>& except, std::function<void(int)> onClose) |
| 920 | { |
| 921 | #if defined(__linux__) || defined(__APPLE__) |
| 922 | namespace fs = boost::filesystem; |
| 923 | |
| 924 | std::set<int> fds; |
| 925 | |
| 926 | #ifdef __linux__ |
| 927 | const char *dir = "/proc/self/fd"; |
| 928 | #endif /* __linux__ */ |
| 929 | #ifdef __APPLE__ |
| 930 | const char *dir = "/dev/fd"; |
| 931 | #endif /* __APPLE__ */ |
| 932 | |
| 933 | for (fs::directory_iterator current {fs::path(dir)}, end; current != end; ++current) { |
| 934 | auto entry (current->path().filename()); |
| 935 | int fd; |
| 936 | |
| 937 | try { |
| 938 | fd = boost::lexical_cast<int>(entry.c_str()); |
| 939 | } catch (...) { |
| 940 | continue; |
| 941 | } |
| 942 | |
| 943 | fds.emplace(fd); |
| 944 | } |
| 945 | |
| 946 | for (auto fd : except) { |
| 947 | fds.erase(fd); |
| 948 | } |
| 949 | |
| 950 | for (auto fd : fds) { |
| 951 | if (close(fd) >= 0 && onClose) { |
| 952 | onClose(fd); |
| 953 | } |
| 954 | } |
| 955 | #else /* __linux__ || __APPLE__ */ |
| 956 | rlimit rl; |
| 957 | |
| 958 | if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) { |
| 959 | rlim_t maxfds = rl.rlim_max; |
| 960 | |
| 961 | if (maxfds == RLIM_INFINITY) { |
| 962 | maxfds = 65536; |
| 963 | } |
| 964 | |
| 965 | for (int fd = 0; fd < maxfds; ++fd) { |
| 966 | if (std::find(except.begin(), except.end(), fd) == except.end() && close(fd) >= 0 && onClose) { |
| 967 | onClose(fd); |
| 968 | } |
| 969 | } |
| 970 | } |
| 971 | #endif /* __linux__ || __APPLE__ */ |
| 972 | } |
| 973 | #endif /* _WIN32 */ |
| 974 | |
| 975 | void Utility::SetNonBlockingSocket(SOCKET s, bool nb) |