102 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build linux solaris
 | 
						|
 | 
						|
package ps
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"strconv"
 | 
						|
)
 | 
						|
 | 
						|
// UnixProcess is an implementation of Process that contains Unix-specific
 | 
						|
// fields and information.
 | 
						|
type UnixProcess struct {
 | 
						|
	pid   int
 | 
						|
	ppid  int
 | 
						|
	state rune
 | 
						|
	pgrp  int
 | 
						|
	sid   int
 | 
						|
 | 
						|
	binary string
 | 
						|
}
 | 
						|
 | 
						|
func (p *UnixProcess) Pid() int {
 | 
						|
	return p.pid
 | 
						|
}
 | 
						|
 | 
						|
func (p *UnixProcess) PPid() int {
 | 
						|
	return p.ppid
 | 
						|
}
 | 
						|
 | 
						|
func (p *UnixProcess) Executable() string {
 | 
						|
	return p.binary
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
		}
 | 
						|
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	return newUnixProcess(pid)
 | 
						|
}
 | 
						|
 | 
						|
func processes() ([]Process, error) {
 | 
						|
	d, err := os.Open("/proc")
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	defer d.Close()
 | 
						|
 | 
						|
	results := make([]Process, 0, 50)
 | 
						|
	for {
 | 
						|
		fis, err := d.Readdir(10)
 | 
						|
		if err == io.EOF {
 | 
						|
			break
 | 
						|
		}
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
 | 
						|
		for _, fi := range fis {
 | 
						|
			// We only care about directories, since all pids are dirs
 | 
						|
			if !fi.IsDir() {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			// We only care if the name starts with a numeric
 | 
						|
			name := fi.Name()
 | 
						|
			if name[0] < '0' || name[0] > '9' {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			// From this point forward, any errors we just ignore, because
 | 
						|
			// it might simply be that the process doesn't exist anymore.
 | 
						|
			pid, err := strconv.ParseInt(name, 10, 0)
 | 
						|
			if err != nil {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			p, err := newUnixProcess(int(pid))
 | 
						|
			if err != nil {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			results = append(results, p)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return results, nil
 | 
						|
}
 | 
						|
 | 
						|
func newUnixProcess(pid int) (*UnixProcess, error) {
 | 
						|
	p := &UnixProcess{pid: pid}
 | 
						|
	return p, p.Refresh()
 | 
						|
}
 |