Skip to content

Commit

Permalink
Merge pull request #605 from Lomanic/issue596
Browse files Browse the repository at this point in the history
Fix #596 Implement process.Background and process.Foreground functions
  • Loading branch information
Lomanic authored Dec 8, 2018
2 parents 3581593 + 8002bdd commit 21ddb4f
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 0 deletions.
13 changes: 13 additions & 0 deletions process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return false, err
}

// Background returns true if the process is in background, false otherwise.
func (p *Process) Background() (bool, error) {
return p.BackgroundWithContext(context.Background())
}

func (p *Process) BackgroundWithContext(ctx context.Context) (bool, error) {
fg, err := p.ForegroundWithContext(ctx)
if err != nil {
return false, err
}
return !fg, err
}

// If interval is 0, return difference from last call(non-blocking).
// If interval > 0, wait interval sec and return diffrence between start and end.
func (p *Process) Percent(interval time.Duration) (float64, error) {
Expand Down
19 changes: 19 additions & 0 deletions process/process_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,25 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {

return r[0][0], err
}

func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}

func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid
ps, err := exec.LookPath("ps")
if err != nil {
return false, err
}
out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid)))
if err != nil {
return false, err
}
return strings.IndexByte(string(out), '+') != -1, nil
}

func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
Expand Down
7 changes: 7 additions & 0 deletions process/process_fallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ func (p *Process) Status() (string, error) {
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}

func (p *Process) ForegroundWithContext() (bool, error) {
return false, common.ErrNotImplementedError
}
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
Expand Down
21 changes: 21 additions & 0 deletions process/process_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"bytes"
"context"
"encoding/binary"
"os/exec"
"strconv"
"strings"

cpu "github.com/shirou/gopsutil/cpu"
Expand Down Expand Up @@ -168,6 +170,25 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {

return s, nil
}

func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}

func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid
ps, err := exec.LookPath("ps")
if err != nil {
return false, err
}
out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid)))
if err != nil {
return false, err
}
return strings.IndexByte(string(out), '+') != -1, nil
}

func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
Expand Down
22 changes: 22 additions & 0 deletions process/process_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,28 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return p.status, nil
}

// Foreground returns true if the process is in foreground, false otherwise.
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}

func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid
statPath := common.HostProc(strconv.Itoa(int(pid)), "stat")
contents, err := ioutil.ReadFile(statPath)
if err != nil {
return false, err
}
fields := strings.Fields(string(contents))
if len(fields) < 8 {
return false, fmt.Errorf("insufficient data in %s", statPath)
}
pgid := fields[4]
tpgid := fields[7]
return pgid == tpgid, nil
}

// Uids returns user ids of the process as a slice of the int
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
Expand Down
17 changes: 17 additions & 0 deletions process/process_openbsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,23 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {

return s, nil
}
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}

func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid
ps, err := exec.LookPath("ps")
if err != nil {
return false, err
}
out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid)))
if err != nil {
return false, err
}
return strings.IndexByte(string(out), '+') != -1, nil
}
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
Expand Down
8 changes: 8 additions & 0 deletions process/process_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}

func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}

func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return false, common.ErrNotImplementedError
}

func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}
Expand Down

0 comments on commit 21ddb4f

Please sign in to comment.