diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2018-03-15 02:33:20 +0100 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2018-03-16 10:55:12 +0100 |
commit | 330e5acbcec00d1bc43a9c1110c4325fa62ba9ad (patch) | |
tree | b7f853a1714dbb513593193f16033ffd38bee3a1 | |
parent | 12af7016e23e7b7f507dc99a1b73e64d0bb5ccf3 (diff) | |
download | rneovim-330e5acbcec00d1bc43a9c1110c4325fa62ba9ad.tar.gz rneovim-330e5acbcec00d1bc43a9c1110c4325fa62ba9ad.tar.bz2 rneovim-330e5acbcec00d1bc43a9c1110c4325fa62ba9ad.zip |
win: nvim_get_proc_children()
TODO: Raymond Chen explains[1] racy behavior of the
CreateToolhelp32Snapshot approach. Better approach:
> create a job object and put process P in it. Then call
> QueryInformationJobObject with JobObjectBasicProcessIdList to get the
> list of child processes.
[1] "Why is CreateToolhelp32Snapshot returning incorrect parent process IDs all of a sudden?"
https://blogs.msdn.microsoft.com/oldnewthing/20150403-00/?p=44313
-rw-r--r-- | src/nvim/os/process.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c index 80c2dad64d..09769925ac 100644 --- a/src/nvim/os/process.c +++ b/src/nvim/os/process.c @@ -43,7 +43,6 @@ static bool os_proc_tree_kill_rec(HANDLE process, int sig) if (!Process32First(h, &pe)) { goto theend; } - do { if (pe.th32ParentProcessID == pid) { HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS, false, pe.th32ProcessID); @@ -53,7 +52,6 @@ static bool os_proc_tree_kill_rec(HANDLE process, int sig) } } } while (Process32Next(h, &pe)); - CloseHandle(h); } } @@ -111,11 +109,40 @@ int os_proc_children(int ppid, int **proc_list, size_t *proc_count) // https://github.com/giampaolo/psutil/tree/master/psutil/arch // + if (ppid < 0) { + return 2; + } + int *temp = NULL; *proc_list = NULL; *proc_count = 0; -#if defined(__APPLE__) || defined(BSD) +#ifdef WIN32 + PROCESSENTRY32 pe; + + // Snapshot of all processes. + HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if(h == INVALID_HANDLE_VALUE) { + return 2; + } + + pe.dwSize = sizeof(PROCESSENTRY32); + // Get root process. + if(!Process32First(h, &pe)) { + CloseHandle(h); + return 2; + } + // Collect processes whose parent matches `ppid`. + do { + if (pe.th32ParentProcessID == (DWORD)ppid) { + temp = xrealloc(temp, (*proc_count + 1) * sizeof(*temp)); + temp[*proc_count] = (int)pe.th32ProcessID; + (*proc_count)++; + } + } while (Process32Next(h, &pe)); + CloseHandle(h); + +#elif defined(__APPLE__) || defined(BSD) # if defined(__APPLE__) # define KP_PID(o) o.kp_proc.p_pid # define KP_PPID(o) o.kp_eproc.e_ppid |