--- test/gtest/common/test_helpers.cc.orig 2026-09-09 16:59:33 UTC +++ test/gtest/common/test_helpers.cc @@ -14,8 +14,18 @@ #include #include +#include +#include #include +#if defined(__FreeBSD__) +#include +#include +#include +#include +#include +#endif + extern "C" { // On some platforms users have to declare environ explicitly extern char** environ; @@ -504,7 +514,7 @@ std::vector read_dir(const std::string &p dir = opendir(path.c_str()); if (dir == NULL) { - goto out_close; + return result; } for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) { @@ -513,7 +523,6 @@ std::vector read_dir(const std::string &p } } -out_close: closedir(dir); return result; } @@ -521,6 +530,42 @@ std::set get_open_fds() std::set get_open_fds() { std::set fds; + +#if defined(__FreeBSD__) + struct procstat *procstat; + struct kinfo_proc *procs; + struct filestat_list *files; + struct filestat *fst; + unsigned int count; + + procstat = procstat_open_sysctl(); + if (procstat == NULL) { + ucs_fatal("procstat_open_sysctl() failed"); + } + + procs = procstat_getprocs(procstat, KERN_PROC_PID, getpid(), &count); + if ((procs == NULL) || (count == 0)) { + procstat_close(procstat); + ucs_fatal("procstat_getprocs() failed"); + } + + files = procstat_getfiles(procstat, &procs[0], 0); + if (files == NULL) { + procstat_freeprocs(procstat, procs); + procstat_close(procstat); + ucs_fatal("procstat_getfiles() failed"); + } + + STAILQ_FOREACH(fst, files, next) { + if (fst->fs_fd >= 0) { + fds.insert(fst->fs_fd); + } + } + + procstat_freefiles(procstat, files); + procstat_freeprocs(procstat, procs); + procstat_close(procstat); +#else DIR *dir = opendir("/proc/self/fd"); if (dir == NULL) { ucs_fatal("failed to open /proc/self/fd"); @@ -542,11 +587,54 @@ std::set get_open_fds() } } closedir(dir); +#endif + return fds; } std::string readlink_proc_fd(int fd) { +#if defined(__FreeBSD__) + struct procstat *procstat; + struct kinfo_proc *procs; + struct filestat_list *files; + struct filestat *fst; + unsigned int count; + std::string result(""); + + procstat = procstat_open_sysctl(); + if (procstat == NULL) { + return ""; + } + + procs = procstat_getprocs(procstat, KERN_PROC_PID, getpid(), &count); + if ((procs == NULL) || (count == 0)) { + procstat_close(procstat); + return ""; + } + + files = procstat_getfiles(procstat, &procs[0], 0); + if (files == NULL) { + procstat_freeprocs(procstat, procs); + procstat_close(procstat); + return ""; + } + + STAILQ_FOREACH(fst, files, next) { + if (fst->fs_fd == fd) { + if ((fst->fs_path != NULL) && (fst->fs_path[0] != '\0')) { + result = fst->fs_path; + } + break; + } + } + + procstat_freefiles(procstat, files); + procstat_freeprocs(procstat, procs); + procstat_close(procstat); + + return result; +#else char path[64], link[PATH_MAX]; const size_t max_len = sizeof(link) - 1; @@ -559,6 +647,7 @@ std::string readlink_proc_fd(int fd) link[len] = '\0'; return std::string(link); +#endif } static std::map get_all_rdmacm_net_devices()