diff --git a/go.mod b/go.mod index 0343279..08c3099 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/mitchellh/go-ps +module github.com/jgbooks/go-ps go 1.13 diff --git a/process.go b/process.go index 2b5e8ed..d6aed72 100644 --- a/process.go +++ b/process.go @@ -16,6 +16,13 @@ type Process interface { // PPid is the parent process ID for this process. PPid() int + // Pgrp is the process group ID of the process + Pgrp() int + + // Sid is the session ID of the process + Sid() int + // TtyNr is the TTYID of the process + TtyNr() uint64 // Executable name running this process. This is not a path to the // executable. Executable() string @@ -33,7 +40,7 @@ func Processes() ([]Process, error) { // FindProcess looks up a single process by pid. // -// Process will be nil and error will be nil if a matching process is +// Process will be nil and error will be os.ErrNotExist if a matching process is // not found. func FindProcess(pid int) (Process, error) { return findProcess(pid) diff --git a/process_darwin.go b/process_darwin.go index 5ee87fb..a10f874 100644 --- a/process_darwin.go +++ b/process_darwin.go @@ -12,6 +12,9 @@ import ( type DarwinProcess struct { pid int ppid int + pgrp int + sid int + ttyNr uint64 binary string } @@ -23,10 +26,23 @@ func (p *DarwinProcess) PPid() int { return p.ppid } +func (p *DarwinProcess) Pgrp() int { + return p.pgrp +} + +func (p *DarwinProcess) Sid() int { + return p.sid +} + func (p *DarwinProcess) Executable() string { return p.binary } + +func (p *DarwinProcess) TtyNr() uint64 { + return p.ttyNr +} + func findProcess(pid int) (Process, error) { ps, err := processes() if err != nil { @@ -63,9 +79,13 @@ func processes() ([]Process, error) { darwinProcs := make([]Process, len(procs)) for i, p := range procs { + pgid, _ := syscall.Getpgid(int(p.Pid)) + sid, _ := syscall.Getsid(int(p.Pid)) darwinProcs[i] = &DarwinProcess{ pid: int(p.Pid), ppid: int(p.PPid), + pgrp: pgid, + sid: sid, binary: darwinCstring(p.Comm), } } diff --git a/process_freebsd.go b/process_freebsd.go index 130acbe..56bc5a0 100644 --- a/process_freebsd.go +++ b/process_freebsd.go @@ -121,10 +121,21 @@ func (p *UnixProcess) PPid() int { return p.ppid } +func (p *UnixProcess) Pgrp() int { + return p.pgrp +} + +func (p *UnixProcess) Sid() int { + return p.sid +} + func (p *UnixProcess) Executable() string { return p.binary } +func (p *UnixProcess) TtyNr() uint64 { + return p.ttyNr +} // Refresh reloads all the data associated with this process. func (p *UnixProcess) Refresh() error { diff --git a/process_linux.go b/process_linux.go index c1558f7..9f16c2a 100644 --- a/process_linux.go +++ b/process_linux.go @@ -25,11 +25,12 @@ func (p *UnixProcess) Refresh() error { // Move past the image name and start parsing the rest data = data[binStart+binEnd+2:] _, err = fmt.Sscanf(data, - "%c %d %d %d", + "%c %d %d %d %d", &p.state, &p.ppid, &p.pgrp, - &p.sid) + &p.sid, + &p.ttyNr) return err } diff --git a/process_solaris.go b/process_solaris.go index 014c416..425f70c 100644 --- a/process_solaris.go +++ b/process_solaris.go @@ -80,7 +80,7 @@ func (p *UnixProcess) Refresh() error { if err != nil { return err } - + p.ttyNr=uint64(psinfo.Pr_ttydev) p.ppid = int(psinfo.Pr_ppid) p.binary = toString(psinfo.Pr_fname[:], 16) return nil diff --git a/process_test.go b/process_test.go index 1bcbc32..92d3ef7 100644 --- a/process_test.go +++ b/process_test.go @@ -1,8 +1,10 @@ package ps import ( + "log" "os" "testing" + "time" ) func TestFindProcess(t *testing.T) { @@ -17,6 +19,9 @@ func TestFindProcess(t *testing.T) { if p.Pid() != os.Getpid() { t.Fatalf("bad: %#v", p.Pid()) } + time.Sleep(20*time.Second) + log.Println(p.Sid()) + log.Println(p.TtyNr()) } func TestProcesses(t *testing.T) { diff --git a/process_unix.go b/process_unix.go index cd217a8..f801bf1 100644 --- a/process_unix.go +++ b/process_unix.go @@ -17,7 +17,7 @@ type UnixProcess struct { state rune pgrp int sid int - + ttyNr uint64 binary string } @@ -29,6 +29,18 @@ func (p *UnixProcess) PPid() int { return p.ppid } +func (p *UnixProcess) Pgrp() int { + return p.pgrp +} + +func (p *UnixProcess) Sid() int { + return p.sid +} + +func (p *UnixProcess) TtyNr() uint64 { + return p.ttyNr +} + func (p *UnixProcess) Executable() string { return p.binary } @@ -37,10 +49,9 @@ func findProcess(pid int) (Process, error) { dir := fmt.Sprintf("/proc/%d", pid) _, err := os.Stat(dir) if err != nil { - if os.IsNotExist(err) { - return nil, nil - } - + // if os.IsNotExist(err) { + // return nil, nil + // } return nil, err } diff --git a/process_windows.go b/process_windows.go index f151974..75bfa65 100644 --- a/process_windows.go +++ b/process_windows.go @@ -42,6 +42,8 @@ type PROCESSENTRY32 struct { type WindowsProcess struct { pid int ppid int + pgrp int + sid int exe string } @@ -53,10 +55,21 @@ func (p *WindowsProcess) PPid() int { return p.ppid } +func (p *WindowsProcess) Pgrp() int { + return p.pgrp +} + +func (p *WindowsProcess) Sid() { + return p.sid +} + func (p *WindowsProcess) Executable() string { return p.exe } +func (p *WindowsProcess) TtyNr() uint64 { + return p.ttyNr +} func newWindowsProcess(e *PROCESSENTRY32) *WindowsProcess { // Find when the string ends for decoding end := 0