Merge pull request #167 from cgilling/cmdline_slice
process: add CmdlineSlice function for linux + freebsd
This commit is contained in:
commit
1ab11f7afd
|
@ -81,6 +81,9 @@ func (p *Process) Name() (string, error) {
|
|||
func (p *Process) Exe() (string, error) {
|
||||
return "", common.NotImplementedError
|
||||
}
|
||||
|
||||
// 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) {
|
||||
r, err := callPs("command", p.Pid, false)
|
||||
if err != nil {
|
||||
|
@ -88,6 +91,19 @@ func (p *Process) Cmdline() (string, error) {
|
|||
}
|
||||
return strings.Join(r[0], " "), err
|
||||
}
|
||||
|
||||
// CmdlineSlice returns the command line arguments of the process as a slice with each
|
||||
// element being an argument. Because of current deficiencies in the way that the command
|
||||
// line arguments are found, single arguments that have spaces in the will actually be
|
||||
// reported as two separate items. In order to do something better CGO would be needed
|
||||
// to use the native darwin functions.
|
||||
func (p *Process) CmdlineSlice() ([]string, error) {
|
||||
r, err := callPs("command", p.Pid, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r[0], err
|
||||
}
|
||||
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,27 @@ 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 len(buf) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
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"
|
||||
|
@ -91,9 +92,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 {
|
||||
|
@ -410,6 +421,28 @@ 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 len(cmdline) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
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()
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ package process
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
@ -145,6 +146,17 @@ func (p *Process) Cmdline() (string, error) {
|
|||
return *dst[0].CommandLine, nil
|
||||
}
|
||||
|
||||
// CmdlineSlice returns the command line arguments of the process as a slice with each
|
||||
// element being an argument. This merely returns the CommandLine informations passed
|
||||
// to the process split on the 0x20 ASCII character.
|
||||
func (p *Process) CmdlineSlice() ([]string, error) {
|
||||
cmdline, err := p.Cmdline()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return strings.Split(cmdline, " "), nil
|
||||
}
|
||||
|
||||
func (p *Process) CreateTime() (int64, error) {
|
||||
dst, err := GetWin32Proc(p.Pid)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue