mirror of
https://github.com/golang/go
synced 2024-11-24 13:50:13 -07:00
2580d0e08d
And then revert the bootstrap cmd directories and certain testdata. And adjust tests as needed. Not reverting the changes in std that are bootstrapped, because some of those changes would appear in API docs, and we want to use any consistently. Instead, rewrite 'any' to 'interface{}' in cmd/dist for those directories when preparing the bootstrap copy. A few files changed as a result of running gofmt -w not because of interface{} -> any but because they hadn't been updated for the new //go:build lines. Fixes #49884. Change-Id: Ie8045cba995f65bd79c694ec77a1b3d1fe01bb09 Reviewed-on: https://go-review.googlesource.com/c/go/+/368254 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
150 lines
3.3 KiB
Go
150 lines
3.3 KiB
Go
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package os
|
|
|
|
import (
|
|
"internal/itoa"
|
|
"runtime"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// The only signal values guaranteed to be present in the os package
|
|
// on all systems are Interrupt (send the process an interrupt) and
|
|
// Kill (force the process to exit). Interrupt is not implemented on
|
|
// Windows; using it with os.Process.Signal will return an error.
|
|
var (
|
|
Interrupt Signal = syscall.Note("interrupt")
|
|
Kill Signal = syscall.Note("kill")
|
|
)
|
|
|
|
func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
|
|
sysattr := &syscall.ProcAttr{
|
|
Dir: attr.Dir,
|
|
Env: attr.Env,
|
|
Sys: attr.Sys,
|
|
}
|
|
|
|
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)
|
|
if e != nil {
|
|
return nil, &PathError{Op: "fork/exec", Path: name, Err: e}
|
|
}
|
|
|
|
return newProcess(pid, h), nil
|
|
}
|
|
|
|
func (p *Process) writeProcFile(file string, data string) error {
|
|
f, e := OpenFile("/proc/"+itoa.Itoa(p.Pid)+"/"+file, O_WRONLY, 0)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
defer f.Close()
|
|
_, e = f.Write([]byte(data))
|
|
return e
|
|
}
|
|
|
|
func (p *Process) signal(sig Signal) error {
|
|
if p.done() {
|
|
return ErrProcessDone
|
|
}
|
|
if e := p.writeProcFile("note", sig.String()); e != nil {
|
|
return NewSyscallError("signal", e)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *Process) kill() error {
|
|
return p.signal(Kill)
|
|
}
|
|
|
|
func (p *Process) wait() (ps *ProcessState, err error) {
|
|
var waitmsg syscall.Waitmsg
|
|
|
|
if p.Pid == -1 {
|
|
return nil, ErrInvalid
|
|
}
|
|
err = syscall.WaitProcess(p.Pid, &waitmsg)
|
|
if err != nil {
|
|
return nil, NewSyscallError("wait", err)
|
|
}
|
|
|
|
p.setDone()
|
|
ps = &ProcessState{
|
|
pid: waitmsg.Pid,
|
|
status: &waitmsg,
|
|
}
|
|
return ps, nil
|
|
}
|
|
|
|
func (p *Process) release() error {
|
|
// NOOP for Plan 9.
|
|
p.Pid = -1
|
|
// no need for a finalizer anymore
|
|
runtime.SetFinalizer(p, nil)
|
|
return nil
|
|
}
|
|
|
|
func findProcess(pid int) (p *Process, err error) {
|
|
// NOOP for Plan 9.
|
|
return newProcess(pid, 0), nil
|
|
}
|
|
|
|
// ProcessState stores information about a process, as reported by Wait.
|
|
type ProcessState struct {
|
|
pid int // The process's id.
|
|
status *syscall.Waitmsg // System-dependent status info.
|
|
}
|
|
|
|
// Pid returns the process id of the exited process.
|
|
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.status
|
|
}
|
|
|
|
func (p *ProcessState) userTime() time.Duration {
|
|
return time.Duration(p.status.Time[0]) * time.Millisecond
|
|
}
|
|
|
|
func (p *ProcessState) systemTime() time.Duration {
|
|
return time.Duration(p.status.Time[1]) * time.Millisecond
|
|
}
|
|
|
|
func (p *ProcessState) String() string {
|
|
if p == nil {
|
|
return "<nil>"
|
|
}
|
|
return "exit status: " + p.status.Msg
|
|
}
|
|
|
|
// ExitCode returns the exit code of the exited process, or -1
|
|
// if the process hasn't exited or was terminated by a signal.
|
|
func (p *ProcessState) ExitCode() int {
|
|
// return -1 if the process hasn't started.
|
|
if p == nil {
|
|
return -1
|
|
}
|
|
return p.status.ExitStatus()
|
|
}
|