diff --git a/process/process_darwin.go b/process/process_darwin.go index 414ea98e5a8ef0b607c5d3c8abf1f85289f7f71a..f2bd0a828f52e0e4fc5a923b851c9955e67a59ff 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -88,6 +88,9 @@ func (p *Process) Cmdline() (string, error) { } return strings.Join(r[0], " "), err } +func (p *Process) CmdlineSlice() ([]string, error) { + return nil, common.NotImplementedError +} func (p *Process) CreateTime() (int64, error) { return 0, common.NotImplementedError } diff --git a/process/process_freebsd.go b/process/process_freebsd.go index 9835bc99e14a2a3b92dc8156a3c629ab5c9ef511..49898670e6b95e9a0261a8527d5efb2f5f35aff9 100644 --- a/process/process_freebsd.go +++ b/process/process_freebsd.go @@ -54,6 +54,7 @@ func (p *Process) Name() (string, error) { func (p *Process) Exe() (string, error) { return "", common.NotImplementedError } + func (p *Process) Cmdline() (string, error) { mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} buf, _, err := common.CallSyscall(mib) @@ -69,6 +70,24 @@ func (p *Process) Cmdline() (string, error) { return strings.Join(ret, " "), nil } + +func (p *Process) CmdlineSlice() ([]string, error) { + mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} + buf, _, err := common.CallSyscall(mib) + if err != nil { + return nil, err + } + if buf[len(buf)-1] == 0 { + buf = buf[:len(buf)-1] + } + parts := bytes.Split(buf, []byte{0}) + var strParts []string + for _, p := range parts { + strParts = append(strParts, string(p)) + } + + return strParts, nil +} func (p *Process) CreateTime() (int64, error) { return 0, common.NotImplementedError } diff --git a/process/process_linux.go b/process/process_linux.go index 1783d2f2245d49023a818c9e5e4283657f8284dd..7c6bb29a53a5796c023d7c08898ce0ac5ef0c809 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -3,6 +3,7 @@ package process import ( + "bytes" "encoding/json" "errors" "fmt" @@ -84,9 +85,19 @@ func (p *Process) Name() (string, error) { func (p *Process) Exe() (string, error) { return p.fillFromExe() } + +// Cmdline returns the command line arguments of the process as a string with +// each argument separated by 0x20 ascii character. func (p *Process) Cmdline() (string, error) { return p.fillFromCmdline() } + +// CmdlineSlice returns the command line arguments of the process as a slice with each +// element being an argument. +func (p *Process) CmdlineSlice() ([]string, error) { + return p.fillSliceFromCmdline() +} + func (p *Process) CreateTime() (int64, error) { _, _, _, createTime, _, err := p.fillFromStat() if err != nil { @@ -403,6 +414,25 @@ func (p *Process) fillFromCmdline() (string, error) { return strings.Join(ret, " "), nil } +func (p *Process) fillSliceFromCmdline() ([]string, error) { + pid := p.Pid + cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline") + cmdline, err := ioutil.ReadFile(cmdPath) + if err != nil { + return nil, err + } + if cmdline[len(cmdline)-1] == 0 { + cmdline = cmdline[:len(cmdline)-1] + } + parts := bytes.Split(cmdline, []byte{0}) + var strParts []string + for _, p := range parts { + strParts = append(strParts, string(p)) + } + + return strParts, nil +} + // Get IO status from /proc/(pid)/io func (p *Process) fillFromIO() (*IOCountersStat, error) { pid := p.Pid diff --git a/process/process_test.go b/process/process_test.go index 129204f98d55dca057382bbd76748f57e23e246f..c5aac11f6f56bca3482e4a7b68b317834fefb54d 100644 --- a/process/process_test.go +++ b/process/process_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/user" + "reflect" "runtime" "strings" "sync" @@ -120,6 +121,18 @@ func Test_Process_CmdLine(t *testing.T) { } } +func Test_Process_CmdLineSlice(t *testing.T) { + p := testGetProcess() + + v, err := p.CmdlineSlice() + if err != nil { + t.Fatalf("geting cmdline slice error %v", err) + } + if !reflect.DeepEqual(v, os.Args) { + t.Errorf("returned cmdline slice not as expected:\nexp: %v\ngot: %v", os.Args, v) + } +} + func Test_Process_Ppid(t *testing.T) { p := testGetProcess() diff --git a/process/process_windows.go b/process/process_windows.go index 51a0ee10dc2cbd17d2f82f0666053ea4c44190a4..6fd972ee71c351098b2cb7ac3cc0bb5f3ec00abd 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -144,7 +144,9 @@ func (p *Process) Cmdline() (string, error) { } return *dst[0].CommandLine, nil } - +func (p *Process) CmdlineSlice() ([]string, error) { + return nil, common.NotImplementedError +} func (p *Process) CreateTime() (int64, error) { dst, err := GetWin32Proc(p.Pid) if err != nil {