File indexing completed on 2025-01-18 09:50:11
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PROCESS_V2_IMPL_PID_IPP
0007 #define BOOST_PROCESS_V2_IMPL_PID_IPP
0008
0009 #include <boost/process/v2/detail/config.hpp>
0010 #include <boost/process/v2/detail/last_error.hpp>
0011 #include <boost/process/v2/detail/throw_error.hpp>
0012 #include <boost/process/v2/pid.hpp>
0013
0014 #if defined(BOOST_PROCESS_V2_WINDOWS)
0015 #include <windows.h>
0016 #include <tlhelp32.h>
0017 #else
0018 #include <unistd.h>
0019 #endif
0020
0021 #if (defined(__APPLE__) && defined(__MACH__))
0022 #include <sys/proc_info.h>
0023 #include <libproc.h>
0024 #endif
0025
0026 #if (defined(__linux__) || defined(__ANDROID__))
0027 #include <dirent.h>
0028 #endif
0029
0030 #if defined(__FreeBSD__)
0031 #include <sys/types.h>
0032 #include <sys/user.h>
0033 #include <libutil.h>
0034 #include <cstdlib>
0035 #endif
0036
0037 #if (defined(__DragonFly__) || defined(__OpenBSD__))
0038 #include <sys/types.h>
0039 #include <sys/param.h>
0040 #include <sys/sysctl.h>
0041 #include <sys/user.h>
0042 #include <kvm.h>
0043 #endif
0044
0045 #if defined(__NetBSD__)
0046 #include <sys/types.h>
0047 #include <kvm.h>
0048 #include <sys/param.h>
0049 #include <sys/sysctl.h>
0050 #endif
0051
0052 #if defined(__sun)
0053 #include <sys/types.h>
0054 #include <kvm.h>
0055 #include <sys/param.h>
0056 #include <sys/time.h>
0057 #include <sys/proc.h>
0058 #endif
0059
0060 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0061
0062 #if defined(BOOST_PROCESS_V2_WINDOWS)
0063 pid_type current_pid() {return ::GetCurrentProcessId();}
0064 #else
0065 pid_type current_pid() {return ::getpid();}
0066 #endif
0067
0068 #if defined(BOOST_PROCESS_V2_WINDOWS)
0069
0070 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0071 {
0072 std::vector<pid_type> vec;
0073 HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
0074 if (!hp)
0075 {
0076 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0077 return vec;
0078 }
0079 PROCESSENTRY32 pe;
0080 pe.dwSize = sizeof(PROCESSENTRY32);
0081 if (Process32First(hp, &pe))
0082 {
0083 do
0084 {
0085 vec.push_back(pe.th32ProcessID);
0086 } while (Process32Next(hp, &pe));
0087 }
0088 CloseHandle(hp);
0089 return vec;
0090 }
0091
0092 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0093 {
0094 pid_type ppid = static_cast<pid_type>(-1);
0095 HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
0096 if (!hp)
0097 {
0098 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0099 return ppid;
0100 }
0101 PROCESSENTRY32 pe;
0102 pe.dwSize = sizeof(PROCESSENTRY32);
0103 if (Process32First(hp, &pe))
0104 {
0105 do
0106 {
0107 if (pe.th32ProcessID == pid)
0108 {
0109 ppid = pe.th32ParentProcessID;
0110 break;
0111 }
0112 }
0113 while (Process32Next(hp, &pe));
0114 }
0115 CloseHandle(hp);
0116 return ppid;
0117 }
0118
0119 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0120 {
0121 std::vector<pid_type> vec;
0122 HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
0123 if (!hp)
0124 {
0125 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0126 return vec;
0127 }
0128 PROCESSENTRY32 pe;
0129 pe.dwSize = sizeof(PROCESSENTRY32);
0130 if (Process32First(hp, &pe))
0131 {
0132 do
0133 {
0134 if (pe.th32ParentProcessID == pid)
0135 {
0136 vec.push_back(pe.th32ProcessID);
0137 }
0138 }
0139 while (Process32Next(hp, &pe));
0140 }
0141 CloseHandle(hp);
0142 return vec;
0143 }
0144
0145 #elif (defined(__APPLE__) && defined(__MACH__))
0146
0147 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0148 {
0149 std::vector<pid_type> vec;
0150 vec.resize(proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0) / sizeof(pid_type));
0151 const auto sz = proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(pid_type) * vec.size());
0152 if (sz < 0)
0153 {
0154 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0155 return {};
0156 }
0157 vec.resize(sz);
0158 return vec;
0159 }
0160
0161 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0162 {
0163 pid_type ppid = static_cast<pid_type>(-1);
0164 proc_bsdinfo proc_info;
0165 if (proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc_info, sizeof(proc_info)) <= 0)
0166 {
0167 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0168 return ppid;
0169 }
0170 else
0171 ppid = proc_info.pbi_ppid;
0172 return ppid;
0173 }
0174
0175 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0176 {
0177 std::vector<pid_type> vec;
0178 vec.resize(proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, nullptr, 0) / sizeof(pid_type));
0179 const auto sz = proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, &vec[0], sizeof(pid_type) * vec.size());
0180 if (sz < 0)
0181 {
0182 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0183 return {};
0184 }
0185 vec.resize(sz);
0186 return vec;
0187 }
0188
0189 #elif (defined(__linux__) || defined(__ANDROID__))
0190
0191 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0192 {
0193 std::vector<pid_type> vec;
0194 DIR *proc = opendir("/proc");
0195 if (!proc)
0196 {
0197 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0198 return vec;
0199 }
0200 struct dirent *ent = nullptr;
0201 while ((ent = readdir(proc)))
0202 {
0203 if (!isdigit(*ent->d_name))
0204 continue;
0205 vec.push_back(atoi(ent->d_name));
0206 }
0207 closedir(proc);
0208 return vec;
0209 }
0210
0211 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0212 {
0213 pid_type ppid = static_cast<pid_type>(-1);
0214 char buffer[BUFSIZ];
0215 sprintf(buffer, "/proc/%d/stat", pid);
0216 FILE *stat = fopen(buffer, "r");
0217 if (!stat)
0218 {
0219 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0220 return ppid;
0221 }
0222 else
0223 {
0224 std::size_t size = fread(buffer, sizeof(char), sizeof(buffer), stat);
0225 if (size > 0)
0226 {
0227 char *token = nullptr;
0228 if ((token = strtok(buffer, " ")))
0229 {
0230 if ((token = strtok(nullptr, " ")))
0231 {
0232 if ((token = strtok(nullptr, " ")))
0233 {
0234 if ((token = strtok(nullptr, " ")))
0235 {
0236 ppid = (pid_type)strtoul(token, nullptr, 10);
0237 }
0238 }
0239 }
0240 }
0241 if (!token)
0242 {
0243 fclose(stat);
0244 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0245 return ppid;
0246 }
0247 }
0248 fclose(stat);
0249 }
0250 return ppid;
0251 }
0252
0253 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0254 {
0255 std::vector<pid_type> vec;
0256 std::vector<pid_type> pids = all_pids(ec);
0257 if (!pids.empty())
0258 vec.reserve(pids.size());
0259 for (std::size_t i = 0; i < pids.size(); i++)
0260 {
0261 pid_type ppid = parent_pid(pids[i], ec);
0262 if (ppid != -1 && ppid == pid)
0263 {
0264 vec.push_back(pids[i]);
0265 }
0266 }
0267 return vec;
0268 }
0269
0270 #elif defined(__FreeBSD__)
0271
0272 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0273 {
0274 std::vector<pid_type> vec;
0275 int cntp = 0;
0276 kinfo_proc *proc_info = kinfo_getallproc(&cntp);
0277 if (proc_info)
0278 {
0279 vec.reserve(cntp);
0280 for (int i = 0; i < cntp; i++)
0281 vec.push_back(proc_info[i].ki_pid);
0282 free(proc_info);
0283 }
0284 else
0285 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0286 return vec;
0287 }
0288
0289 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0290 {
0291 pid_type ppid = static_cast<pid_type>(-1);
0292 kinfo_proc *proc_info = kinfo_getproc(pid);
0293 if (proc_info)
0294 {
0295 ppid = proc_info->ki_ppid;
0296 free(proc_info);
0297 }
0298 else
0299 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0300 return ppid;
0301 }
0302
0303 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0304 {
0305 std::vector<pid_type> vec;
0306 int cntp = 0;
0307 kinfo_proc *proc_info = kinfo_getallproc(&cntp);
0308 if (proc_info)
0309 {
0310 vec.reserve(cntp);
0311 for (int i = 0; i < cntp; i++)
0312 {
0313 if (proc_info[i].ki_ppid == pid)
0314 {
0315 vec.push_back(proc_info[i].ki_pid);
0316 }
0317 }
0318 free(proc_info);
0319 }
0320 else
0321 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0322 return vec;
0323 }
0324
0325 #elif defined(__DragonFly__)
0326
0327 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0328 {
0329 std::vector<pid_type> vec;
0330 int cntp = 0;
0331 kinfo_proc *proc_info = nullptr;
0332 const char *nlistf, *memf;
0333 nlistf = memf = "/dev/null";
0334 struct closer
0335 {
0336 void operator()(kvm_t * kd)
0337 {
0338 kvm_close(kd);
0339 }
0340 };
0341
0342 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
0343 if (!kd)
0344 {
0345 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0346 return vec;
0347 }
0348 if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
0349 {
0350 vec.reserve(cntp);
0351 for (int i = 0; i < cntp; i++)
0352 if (proc_info[i].kp_pid >= 0)
0353 vec.push_back(proc_info[i].kp_pid);
0354 }
0355 else
0356 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0357 return vec;
0358 }
0359
0360 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0361 {
0362 pid_type ppid = static_cast<pid_type>(-1);
0363 int cntp = 0;
0364 kinfo_proc *proc_info = nullptr;
0365 const char *nlistf, *memf;
0366 nlistf = memf = "/dev/null";
0367 struct closer
0368 {
0369 void operator()(kvm_t * kd)
0370 {
0371 kvm_close(kd);
0372 }
0373 };
0374
0375 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
0376 if (!kd)
0377 {
0378 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0379 return ppid;
0380 }
0381 if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp)))
0382 {
0383 if (proc_info->kp_ppid >= 0)
0384 {
0385 ppid = proc_info->kp_ppid;
0386 }
0387 }
0388 else
0389 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0390 return ppid;
0391 }
0392
0393 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0394 {
0395 std::vector<pid_type> vec;
0396 int cntp = 0;
0397 kinfo_proc *proc_info = nullptr;
0398 const char *nlistf, *memf;
0399 nlistf = memf = "/dev/null";
0400 struct closer
0401 {
0402 void operator()(kvm_t * kd)
0403 {
0404 kvm_close(kd);
0405 }
0406 };
0407
0408 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
0409 if (!kd)
0410 {
0411 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0412 return vec;
0413 }
0414 if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
0415 {
0416 vec.reserve(cntp);
0417 for (int i = 0; i < cntp; i++)
0418 {
0419 if (proc_info[i].kp_pid >= 0 && proc_info[i].kp_ppid >= 0 && proc_info[i].kp_ppid == pid)
0420 {
0421 vec.push_back(proc_info[i].kp_pid);
0422 }
0423 }
0424 }
0425 else
0426 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0427 return vec;
0428 }
0429
0430 #elif defined(__NetBSD__)
0431
0432 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0433 {
0434 std::vector<pid_type> vec;
0435 int cntp = 0;
0436 kinfo_proc2 *proc_info = nullptr;
0437 struct closer
0438 {
0439 void operator()(kvm_t * kd)
0440 {
0441 kvm_close(kd);
0442 }
0443 };
0444
0445 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
0446 if (!kd)
0447 {
0448 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0449 return vec;
0450 }
0451 if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cntp)))
0452 {
0453 vec.reserve(cntp);
0454 for (int i = cntp - 1; i >= 0; i--)
0455 {
0456 vec.push_back(proc_info[i].p_pid);
0457 }
0458 }
0459 else
0460 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0461 return vec;
0462 }
0463
0464 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0465 {
0466 pid_type ppid = static_cast<pid_type>(-1);
0467 int cntp = 0;
0468 kinfo_proc2 *proc_info = nullptr;
0469 struct closer
0470 {
0471 void operator()(kvm_t * kd)
0472 {
0473 kvm_close(kd);
0474 }
0475 };
0476
0477 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
0478 if (!kd)
0479 {
0480 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0481 return ppid;
0482 }
0483 if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp)))
0484 {
0485 ppid = proc_info->p_ppid;
0486 }
0487 else
0488 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0489 return ppid;
0490 }
0491
0492 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0493 {
0494 std::vector<pid_type> vec;
0495 int cntp = 0;
0496 kinfo_proc2 *proc_info = nullptr;
0497 struct closer
0498 {
0499 void operator()(kvm_t * kd)
0500 {
0501 kvm_close(kd);
0502 }
0503 };
0504
0505 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
0506 if (!kd)
0507 {
0508 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0509 return vec;
0510 }
0511 if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cntp)))
0512 {
0513 vec.reserve(cntp);
0514 for (int i = cntp - 1; i >= 0; i--)
0515 {
0516 if (proc_info[i].p_ppid == pid)
0517 {
0518 vec.push_back(proc_info[i].p_pid);
0519 }
0520 }
0521 }
0522 else
0523 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0524 return vec;
0525 }
0526
0527 #elif defined(__OpenBSD__)
0528
0529 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0530 {
0531 std::vector<pid_type> vec;
0532 int cntp = 0;
0533 kinfo_proc *proc_info = nullptr;
0534 struct closer
0535 {
0536 void operator()(kvm_t * kd)
0537 {
0538 kvm_close(kd);
0539 }
0540 };
0541
0542 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
0543 if (!kd)
0544 {
0545 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0546 return vec;
0547 }
0548 if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cntp)))
0549 {
0550 vec.reserve(cntp);
0551 for (int i = cntp - 1; i >= 0; i--)
0552 {
0553 if (proc_info[i].kp_pid >= 0)
0554 {
0555 vec.push_back(proc_info[i].kp_pid);
0556 }
0557 }
0558 }
0559 else
0560 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0561 return vec;
0562 }
0563
0564 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0565 {
0566 pid_type ppid = static_cast<pid_type>(-1);
0567 int cntp = 0;
0568 kinfo_proc *proc_info = nullptr;
0569 struct closer
0570 {
0571 void operator()(kvm_t * kd)
0572 {
0573 kvm_close(kd);
0574 }
0575 };
0576
0577 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
0578 if (!kd)
0579 {
0580 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0581 return ppid;
0582 }
0583 if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp)))
0584 {
0585 ppid = proc_info->p_ppid;
0586 }
0587 else
0588 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0589 return ppid;
0590 }
0591
0592 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0593 {
0594 std::vector<pid_type> vec;
0595 int cntp = 0;
0596 kinfo_proc *proc_info = nullptr;
0597 struct closer
0598 {
0599 void operator()(kvm_t * kd)
0600 {
0601 kvm_close(kd);
0602 }
0603 };
0604
0605 std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
0606 if (!kd)
0607 {
0608 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0609 return vec;
0610 }
0611 if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cntp)))
0612 {
0613 vec.reserve(cntp);
0614 for (int i = cntp - 1; i >= 0; i--)
0615 {
0616 if (proc_info[i].p_ppid == pid)
0617 {
0618 vec.push_back(proc_info[i].p_pid);
0619 }
0620 }
0621 }
0622 else
0623 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0624 return vec;
0625 }
0626
0627
0628 #elif defined(__sun)
0629
0630 std::vector<pid_type> all_pids(boost::system::error_code & ec)
0631 {
0632 std::vector<pid_type> vec;
0633 struct pid cur_pid;
0634 proc *proc_info = nullptr;
0635 struct closer
0636 {
0637 void operator()(kvm_t * kd)
0638 {
0639 kvm_close(kd);
0640 }
0641 };
0642
0643 std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)};
0644 if (!kd)
0645 {
0646 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0647 return vec;
0648 }
0649 while ((proc_info = kvm_nextproc(kd)))
0650 {
0651 if (kvm_kread(kd, (std::uintptr_t)proc_info->p_pidp, &cur_pid, sizeof(cur_pid)) != -1)
0652 {
0653 vec.insert(vec.begin(), cur_pid.pid_id);
0654 }
0655 else
0656 {
0657 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0658 break;
0659 }
0660 }
0661 return vec;
0662 }
0663
0664 pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
0665 {
0666 pid_type ppid = static_cast<pid_type>(-1);
0667 proc *proc_info = nullptr;
0668 struct closer
0669 {
0670 void operator()(kvm_t * kd)
0671 {
0672 kvm_close(kd);
0673 }
0674 };
0675
0676 std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)};
0677 if (!kd)
0678 {
0679 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0680 return ppid;
0681 }
0682 if ((proc_info = kvm_getproc(kd, pid)))
0683 {
0684 ppid = proc_info->p_ppid;
0685 }
0686 else
0687 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0688 return ppid;
0689 }
0690
0691 std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
0692 {
0693 std::vector<pid_type> vec;
0694 struct pid cur_pid;
0695 proc *proc_info = nullptr;
0696 struct closer
0697 {
0698 void operator()(kvm_t * kd)
0699 {
0700 kvm_close(kd);
0701 }
0702 };
0703
0704 std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr);
0705 if (!kd)
0706 {
0707 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0708 return vec;
0709 }
0710 while ((proc_info = kvm_nextproc(kd)))
0711 {
0712 if (proc_info->p_ppid == pid)
0713 {
0714 if (kvm_kread(kd, (std::uintptr_t)proc_info->p_pidp, &cur_pid, sizeof(cur_pid)) != -1)
0715 {
0716 vec.insert(vec.begin(), cur_pid.pid_id);
0717 }
0718 else
0719 {
0720 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0721 break;
0722 }
0723 }
0724 }
0725 return vec;
0726 }
0727
0728 #else
0729 #error "Platform not supported"
0730 #endif
0731
0732 std::vector<pid_type> all_pids()
0733 {
0734 boost::system::error_code ec;
0735 auto res = all_pids(ec);
0736 if (ec)
0737 detail::throw_error(ec, "all_pids");
0738 return res;
0739 }
0740
0741 pid_type parent_pid(pid_type pid)
0742 {
0743 boost::system::error_code ec;
0744 auto res = parent_pid(pid, ec);
0745 if (ec)
0746 detail::throw_error(ec, "parent_pid");
0747 return res;
0748 }
0749
0750 std::vector<pid_type> child_pids(pid_type pid)
0751 {
0752 boost::system::error_code ec;
0753 auto res = child_pids(pid, ec);
0754 if (ec)
0755 detail::throw_error(ec, "child_pids");
0756 return res;
0757 }
0758
0759 BOOST_PROCESS_V2_END_NAMESPACE
0760
0761 #endif
0762