mirror of
https://github.com/shirou/gopsutil.git
synced 2025-05-14 19:29:16 +08:00
Merge pull request #684 from Lomanic/issue670
[process][darwin] Fix #670 remove call to common.Pipeline (prone to race condition)
This commit is contained in:
commit
3e23fdab39
@ -332,49 +332,6 @@ func HostRun(combineWith ...string) string {
|
|||||||
return GetEnv("HOST_RUN", "/run", combineWith...)
|
return GetEnv("HOST_RUN", "/run", combineWith...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gist.github.com/kylelemons/1525278
|
|
||||||
func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) {
|
|
||||||
// Require at least one command
|
|
||||||
if len(cmds) < 1 {
|
|
||||||
return nil, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect the output from the command(s)
|
|
||||||
var output bytes.Buffer
|
|
||||||
var stderr bytes.Buffer
|
|
||||||
|
|
||||||
last := len(cmds) - 1
|
|
||||||
for i, cmd := range cmds[:last] {
|
|
||||||
var err error
|
|
||||||
// Connect each command's stdin to the previous command's stdout
|
|
||||||
if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
// Connect each command's stderr to a buffer
|
|
||||||
cmd.Stderr = &stderr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect the output and error for the last command
|
|
||||||
cmds[last].Stdout, cmds[last].Stderr = &output, &stderr
|
|
||||||
|
|
||||||
// Start each command
|
|
||||||
for _, cmd := range cmds {
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return output.Bytes(), stderr.Bytes(), err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for each command to complete
|
|
||||||
for _, cmd := range cmds {
|
|
||||||
if err := cmd.Wait(); err != nil {
|
|
||||||
return output.Bytes(), stderr.Bytes(), err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the pipeline output and the collected standard error
|
|
||||||
return output.Bytes(), stderr.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running
|
// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running
|
||||||
// sysctl commands (see DoSysctrl).
|
// sysctl commands (see DoSysctrl).
|
||||||
func getSysctrlEnv(env []string) []string {
|
func getSysctrlEnv(env []string) []string {
|
||||||
|
@ -23,7 +23,7 @@ func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ..
|
|||||||
}
|
}
|
||||||
out, err := invoke.CommandWithContext(ctx, lsof, cmd...)
|
out, err := invoke.CommandWithContext(ctx, lsof, cmd...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// if no pid found, lsof returnes code 1.
|
// if no pid found, lsof returns code 1.
|
||||||
if err.Error() == "exit status 1" && len(out) == 0 {
|
if err.Error() == "exit status 1" && len(out) == 0 {
|
||||||
return []string{}, nil
|
return []string{}, nil
|
||||||
}
|
}
|
||||||
|
@ -108,30 +108,21 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
out, err := invoke.CommandWithContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn")
|
||||||
awk_bin, err := exec.LookPath("awk")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("bad call to lsof: %s", err)
|
||||||
}
|
}
|
||||||
|
txtFound := 0
|
||||||
sed_bin, err := exec.LookPath("sed")
|
lines := strings.Split(string(out), "\n")
|
||||||
if err != nil {
|
for i := 1; i < len(lines); i += 2 {
|
||||||
return "", err
|
if lines[i] == "ftxt" {
|
||||||
|
txtFound++
|
||||||
|
if txtFound == 2 {
|
||||||
|
return lines[i-1][1:], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return "", fmt.Errorf("missing txt data returned by lsof")
|
||||||
lsof := exec.CommandContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn")
|
|
||||||
awk := exec.CommandContext(ctx, awk_bin, "NR==5{print}")
|
|
||||||
sed := exec.CommandContext(ctx, sed_bin, "s/n\\//\\//")
|
|
||||||
|
|
||||||
output, _, err := common.Pipeline(lsof, awk, sed)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := strings.TrimSpace(string(output))
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cmdline returns the command line arguments of the process as a string with
|
// Cmdline returns the command line arguments of the process as a string with
|
||||||
|
Loading…
x
Reference in New Issue
Block a user