提交 b8c40ac8 编写于 作者: C Chris Gilling

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.
上级 3618a777
......@@ -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
}
......
......@@ -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
}
......
......@@ -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
......
......@@ -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()
......
......@@ -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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册