package os
import (
"internal/itoa"
"internal/syscall/execenv"
"runtime"
"syscall"
)
var (
Interrupt Signal = syscall .SIGINT
Kill Signal = syscall .SIGKILL
)
func startProcess(name string , argv []string , attr *ProcAttr ) (p *Process , err error ) {
if attr != nil && attr .Sys == nil && attr .Dir != "" {
if _ , err := Stat (attr .Dir ); err != nil {
pe := err .(*PathError )
pe .Op = "chdir"
return nil , pe
}
}
sysattr := &syscall .ProcAttr {
Dir : attr .Dir ,
Env : attr .Env ,
Sys : ensurePidfd (attr .Sys ),
}
if sysattr .Env == nil {
sysattr .Env , err = execenv .Default (sysattr .Sys )
if err != nil {
return nil , err
}
}
sysattr .Files = make ([]uintptr , 0 , len (attr .Files ))
for _ , f := range attr .Files {
sysattr .Files = append (sysattr .Files , f .Fd ())
}
pid , h , e := syscall .StartProcess (name , argv , sysattr )
runtime .KeepAlive (attr )
if e != nil {
return nil , &PathError {Op : "fork/exec" , Path : name , Err : e }
}
if runtime .GOOS != "windows" {
var ok bool
h , ok = getPidfd (sysattr .Sys )
if !ok {
return newPIDProcess (pid ), nil
}
}
return newHandleProcess (pid , h ), nil
}
func (p *Process ) kill () error {
return p .Signal (Kill )
}
type ProcessState struct {
pid int
status syscall .WaitStatus
rusage *syscall .Rusage
}
func (p *ProcessState ) Pid () int {
return p .pid
}
func (p *ProcessState ) exited () bool {
return p .status .Exited ()
}
func (p *ProcessState ) success () bool {
return p .status .ExitStatus () == 0
}
func (p *ProcessState ) sys () any {
return p .status
}
func (p *ProcessState ) sysUsage () any {
return p .rusage
}
func (p *ProcessState ) String () string {
if p == nil {
return "<nil>"
}
status := p .Sys ().(syscall .WaitStatus )
res := ""
switch {
case status .Exited ():
code := status .ExitStatus ()
if runtime .GOOS == "windows" && uint (code ) >= 1 <<16 {
res = "exit status " + itoa .Uitox (uint (code ))
} else {
res = "exit status " + itoa .Itoa (code )
}
case status .Signaled ():
res = "signal: " + status .Signal ().String ()
case status .Stopped ():
res = "stop signal: " + status .StopSignal ().String ()
if status .StopSignal () == syscall .SIGTRAP && status .TrapCause () != 0 {
res += " (trap " + itoa .Itoa (status .TrapCause ()) + ")"
}
case status .Continued ():
res = "continued"
}
if status .CoreDump () {
res += " (core dumped)"
}
return res
}
func (p *ProcessState ) ExitCode () int {
if p == nil {
return -1
}
return p .status .ExitStatus ()
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .