github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/toolkit/internal/common/common_unix.go (about)

     1  //go:build linux || freebsd || darwin || openbsd
     2  // +build linux freebsd darwin openbsd
     3  
     4  package common
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"os/exec"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ...string) ([]string, error) {
    15  	var cmd []string
    16  	if pid == 0 { // will get from all processes.
    17  		cmd = []string{"-a", "-n", "-P"}
    18  	} else {
    19  		cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))}
    20  	}
    21  	cmd = append(cmd, args...)
    22  	out, err := invoke.CommandWithContext(ctx, "lsof", cmd...)
    23  	if err != nil {
    24  		if errors.Is(err, exec.ErrNotFound) {
    25  			return []string{}, err
    26  		}
    27  		// if no pid found, lsof returns code 1.
    28  		if err.Error() == "exit status 1" && len(out) == 0 {
    29  			return []string{}, nil
    30  		}
    31  	}
    32  	lines := strings.Split(string(out), "\n")
    33  
    34  	var ret []string
    35  	for _, l := range lines[1:] {
    36  		if len(l) == 0 {
    37  			continue
    38  		}
    39  		ret = append(ret, l)
    40  	}
    41  	return ret, nil
    42  }
    43  
    44  func CallPgrepWithContext(ctx context.Context, invoke Invoker, pid int32) ([]int32, error) {
    45  	out, err := invoke.CommandWithContext(ctx, "pgrep", "-P", strconv.Itoa(int(pid)))
    46  	if err != nil {
    47  		return []int32{}, err
    48  	}
    49  	lines := strings.Split(string(out), "\n")
    50  	ret := make([]int32, 0, len(lines))
    51  	for _, l := range lines {
    52  		if len(l) == 0 {
    53  			continue
    54  		}
    55  		i, err := strconv.ParseInt(l, 10, 32)
    56  		if err != nil {
    57  			continue
    58  		}
    59  		ret = append(ret, int32(i))
    60  	}
    61  	return ret, nil
    62  }