process: add CmdlineSlice function for linux + freebsd

This allows for getting more exact information about each argument
especially if there are arguments that have spaces in them.

This was not implemented for darwin or for windows because they
both currently have not way of properly parsing the cmdline string.
Darwin parses the output of 'ps' which is already whitespace
segmented, and windows just has the cmdline string.
pull/167/head
Chris Gilling 9 years ago
parent 3618a777a8
commit b8c40ac83c

@ -88,6 +88,9 @@ func (p *Process) Cmdline() (string, error) {
} }
return strings.Join(r[0], " "), err return strings.Join(r[0], " "), err
} }
func (p *Process) CmdlineSlice() ([]string, error) {
return nil, common.NotImplementedError
}
func (p *Process) CreateTime() (int64, error) { func (p *Process) CreateTime() (int64, error) {
return 0, common.NotImplementedError return 0, common.NotImplementedError
} }

@ -54,6 +54,7 @@ func (p *Process) Name() (string, error) {
func (p *Process) Exe() (string, error) { func (p *Process) Exe() (string, error) {
return "", common.NotImplementedError return "", common.NotImplementedError
} }
func (p *Process) Cmdline() (string, error) { func (p *Process) Cmdline() (string, error) {
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
buf, _, err := common.CallSyscall(mib) buf, _, err := common.CallSyscall(mib)
@ -69,6 +70,24 @@ func (p *Process) Cmdline() (string, error) {
return strings.Join(ret, " "), nil 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) { func (p *Process) CreateTime() (int64, error) {
return 0, common.NotImplementedError return 0, common.NotImplementedError
} }

@ -3,6 +3,7 @@
package process package process
import ( import (
"bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -84,9 +85,19 @@ func (p *Process) Name() (string, error) {
func (p *Process) Exe() (string, error) { func (p *Process) Exe() (string, error) {
return p.fillFromExe() 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) { func (p *Process) Cmdline() (string, error) {
return p.fillFromCmdline() 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) { func (p *Process) CreateTime() (int64, error) {
_, _, _, createTime, _, err := p.fillFromStat() _, _, _, createTime, _, err := p.fillFromStat()
if err != nil { if err != nil {
@ -403,6 +414,25 @@ func (p *Process) fillFromCmdline() (string, error) {
return strings.Join(ret, " "), nil 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 // Get IO status from /proc/(pid)/io
func (p *Process) fillFromIO() (*IOCountersStat, error) { func (p *Process) fillFromIO() (*IOCountersStat, error) {
pid := p.Pid pid := p.Pid

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/user" "os/user"
"reflect"
"runtime" "runtime"
"strings" "strings"
"sync" "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) { func Test_Process_Ppid(t *testing.T) {
p := testGetProcess() p := testGetProcess()

@ -144,7 +144,9 @@ func (p *Process) Cmdline() (string, error) {
} }
return *dst[0].CommandLine, nil return *dst[0].CommandLine, nil
} }
func (p *Process) CmdlineSlice() ([]string, error) {
return nil, common.NotImplementedError
}
func (p *Process) CreateTime() (int64, error) { func (p *Process) CreateTime() (int64, error) {
dst, err := GetWin32Proc(p.Pid) dst, err := GetWin32Proc(p.Pid)
if err != nil { if err != nil {

Loading…
Cancel
Save