github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/cmd/state-svc/internal/rtwatcher/entry.go (about) 1 package rtwatcher 2 3 import ( 4 "errors" 5 6 "github.com/ActiveState/cli/internal/analytics/dimensions" 7 "github.com/ActiveState/cli/internal/errs" 8 "github.com/ActiveState/cli/internal/fileutils" 9 "github.com/ActiveState/cli/internal/logging" 10 "github.com/shirou/gopsutil/v3/process" 11 ) 12 13 type entry struct { 14 PID int `json:"pid"` 15 Exec string `json:"exec"` 16 Source string `json:"source"` 17 Dims *dimensions.Values `json:"dims"` 18 } 19 20 // processError wraps an OS-level error, not a State Tool error. 21 type processError struct { 22 *errs.WrapperError 23 } 24 25 func (e entry) IsRunning() (bool, error) { 26 logging.Debug("Checking if %s (%d) is still running", e.Exec, e.PID) 27 28 proc, err := process.NewProcess(int32(e.PID)) 29 if err != nil { 30 if errors.Is(err, process.ErrorProcessNotRunning) { 31 logging.Debug("Process %d is no longer running, recieved error: %s", e.PID, err.Error()) 32 return false, nil 33 } 34 return false, errs.Wrap(err, "Could not find process: %d", e.PID) 35 } 36 37 exe, err := proc.Exe() 38 if err != nil { 39 return false, &processError{errs.Wrap(err, "Could not get executable of process: %d", e.PID)} 40 } 41 42 match, err := fileutils.PathsMatch(exe, e.Exec) 43 if err != nil { 44 return false, errs.Wrap(err, "Could not compare paths: %s, %s", exe, e.Exec) 45 } 46 if match { 47 logging.Debug("Process %d matched", e.PID) 48 return true, nil 49 } 50 51 logging.Debug("Process %d not matched, expected %s to match %s", e.PID, exe, e.Exec) 52 return false, nil 53 }