Last active
March 15, 2022 22:01
-
-
Save SCP002/b0b8ceca7f6bf2f52ae04c93fede3904 to your computer and use it in GitHub Desktop.
Golang: Get all descendants of the specified process.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Used in https://github.com/SCP002/terminator. | |
package main | |
import ( | |
"fmt" | |
"github.com/shirou/gopsutil/process" | |
) | |
func main() { | |
fmt.Print("The PID to build a process tree from: ") | |
var pid int | |
fmt.Scanln(&pid) | |
// Get a process tree. | |
tree := []process.Process{} | |
err := GetTree(pid, &tree, true) | |
if err != nil { | |
panic(err) | |
} | |
// Print collected info. | |
for _, proc := range tree { | |
cmdLine, err := proc.Cmdline() | |
if err != nil { | |
panic(err) | |
} | |
fmt.Printf("%v\t| %v\r\n", proc.Pid, cmdLine) | |
} | |
fmt.Println("Press <Enter> to exit...") | |
fmt.Scanln() | |
} | |
// GetTree populates the "tree" argument with gopsutil Process instances of all descendants of the specified process. | |
// | |
// The first element in the tree is deepest descendant. The last one is a progenitor or closest child. | |
// | |
// If the "withRoot" argument is set to "true", include the root process. | |
func GetTree(pid int, tree *[]process.Process, withRoot bool) error { | |
proc, err := process.NewProcess(int32(pid)) | |
if err != nil { | |
return err | |
} | |
children, err := proc.Children() | |
if err == process.ErrorNoChildren { | |
return nil | |
} | |
if err != nil { | |
return err | |
} | |
// Iterate for each child process in reverse order. | |
for i := len(children) - 1; i >= 0; i-- { | |
child := children[i] | |
// Call self to collect descendants. | |
err := GetTree(int(child.Pid), tree, false) | |
if err != nil { | |
return err | |
} | |
// Add the child after it's descendants. | |
*tree = append(*tree, *child) | |
} | |
// Add the root process to the end. | |
if withRoot { | |
*tree = append(*tree, *proc) | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment