| 384 | } |
| 385 | |
| 386 | int CountOpenFds(Env* env, const string& path_pattern) { |
| 387 | static const char* kProcSelfFd = |
| 388 | #if defined(__APPLE__) |
| 389 | "/dev/fd"; |
| 390 | #else |
| 391 | "/proc/self/fd"; |
| 392 | #endif // defined(__APPLE__) |
| 393 | faststring path_buf; |
| 394 | vector<string> children; |
| 395 | CHECK_OK(env->GetChildren(kProcSelfFd, &children)); |
| 396 | int num_fds = 0; |
| 397 | for (const auto& c : children) { |
| 398 | // Skip '.' and '..'. |
| 399 | if (c == "." || c == "..") { |
| 400 | continue; |
| 401 | } |
| 402 | int32_t fd; |
| 403 | CHECK(safe_strto32(c, &fd)) << "Unexpected file in fd list: " << c; |
| 404 | #ifdef __APPLE__ |
| 405 | path_buf.resize(MAXPATHLEN); |
| 406 | if (fcntl(fd, F_GETPATH, path_buf.data()) != 0) { |
| 407 | if (errno == EBADF) { |
| 408 | // The file was closed while we were looping. This is likely the |
| 409 | // actual file descriptor used for opening /proc/fd itself. |
| 410 | continue; |
| 411 | } |
| 412 | PLOG(FATAL) << "Unknown error in fcntl(F_GETPATH): " << fd; |
| 413 | } |
| 414 | char* buf_data = reinterpret_cast<char*>(path_buf.data()); |
| 415 | path_buf.resize(strlen(buf_data)); |
| 416 | #else |
| 417 | path_buf.resize(PATH_MAX); |
| 418 | char* buf_data = reinterpret_cast<char*>(path_buf.data()); |
| 419 | auto proc_file = JoinPathSegments(kProcSelfFd, c); |
| 420 | int path_len = readlink(proc_file.c_str(), buf_data, path_buf.size()); |
| 421 | if (path_len < 0) { |
| 422 | if (errno == ENOENT) { |
| 423 | // The file was closed while we were looping. This is likely the |
| 424 | // actual file descriptor used for opening /proc/fd itself. |
| 425 | continue; |
| 426 | } |
| 427 | PLOG(FATAL) << "Unknown error in readlink: " << proc_file; |
| 428 | } |
| 429 | path_buf.resize(path_len); |
| 430 | #endif |
| 431 | if (!MatchPattern(path_buf.ToString(), path_pattern)) { |
| 432 | continue; |
| 433 | } |
| 434 | num_fds++; |
| 435 | } |
| 436 | |
| 437 | return num_fds; |
| 438 | } |
| 439 | |
| 440 | namespace { |
| 441 | const vector<string> kWildcard = { "0.0.0.0" }; |
no test coverage detected