gf/os/gproc/gproc.go

120 lines
3.1 KiB
Go

// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
// Package gproc implements management and communication for processes.
package gproc
import (
"os"
"runtime"
"time"
"github.com/gogf/gf/v2/os/genv"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
)
const (
envKeyPPid = "GPROC_PPID"
tracingInstrumentName = "github.com/gogf/gf/v2/os/gproc.Process"
)
var (
processPid = os.Getpid() // processPid is the pid of current process.
processStartTime = time.Now() // processStartTime is the start time of current process.
)
// Pid returns the pid of current process.
func Pid() int {
return processPid
}
// PPid returns the custom parent pid if exists, or else it returns the system parent pid.
func PPid() int {
if !IsChild() {
return Pid()
}
ppidValue := os.Getenv(envKeyPPid)
if ppidValue != "" && ppidValue != "0" {
return gconv.Int(ppidValue)
}
return PPidOS()
}
// PPidOS returns the system parent pid of current process.
// Note that the difference between PPidOS and PPid function is that the PPidOS returns
// the system ppid, but the PPid functions may return the custom pid by gproc if the custom
// ppid exists.
func PPidOS() int {
return os.Getppid()
}
// IsChild checks and returns whether current process is a child process.
// A child process is forked by another gproc process.
func IsChild() bool {
ppidValue := os.Getenv(envKeyPPid)
return ppidValue != "" && ppidValue != "0"
}
// SetPPid sets custom parent pid for current process.
func SetPPid(ppid int) error {
if ppid > 0 {
return os.Setenv(envKeyPPid, gconv.String(ppid))
} else {
return os.Unsetenv(envKeyPPid)
}
}
// StartTime returns the start time of current process.
func StartTime() time.Time {
return processStartTime
}
// Uptime returns the duration which current process has been running
func Uptime() time.Duration {
return time.Since(processStartTime)
}
// SearchBinary searches the binary `file` in current working folder and PATH environment.
func SearchBinary(file string) string {
// Check if it is absolute path of exists at current working directory.
if gfile.Exists(file) {
return file
}
return SearchBinaryPath(file)
}
// SearchBinaryPath searches the binary `file` in PATH environment.
func SearchBinaryPath(file string) string {
array := ([]string)(nil)
switch runtime.GOOS {
case "windows":
envPath := genv.Get("PATH", genv.Get("Path")).String()
if gstr.Contains(envPath, ";") {
array = gstr.SplitAndTrim(envPath, ";")
} else if gstr.Contains(envPath, ":") {
array = gstr.SplitAndTrim(envPath, ":")
}
if gfile.Ext(file) != ".exe" {
file += ".exe"
}
default:
array = gstr.SplitAndTrim(genv.Get("PATH").String(), ":")
}
if len(array) > 0 {
path := ""
for _, v := range array {
path = v + gfile.Separator + file
if gfile.Exists(path) && gfile.IsFile(path) {
return path
}
}
}
return ""
}