mirror of
https://github.com/golang/go
synced 2024-11-24 18:00:02 -07:00
os: add Process.Kill and Process.Signal
R=alex.brainman, r, rsc, krasin, iant, rsc, r CC=golang-dev https://golang.org/cl/4437091
This commit is contained in:
parent
7dd47326e5
commit
94b974a22d
@ -27,6 +27,7 @@ GOFILES_freebsd=\
|
||||
sys_bsd.go\
|
||||
exec_posix.go\
|
||||
exec_unix.go\
|
||||
signal_unix.go\
|
||||
|
||||
GOFILES_darwin=\
|
||||
dir_unix.go\
|
||||
@ -38,6 +39,7 @@ GOFILES_darwin=\
|
||||
sys_bsd.go\
|
||||
exec_posix.go\
|
||||
exec_unix.go\
|
||||
signal_unix.go\
|
||||
|
||||
GOFILES_linux=\
|
||||
dir_unix.go\
|
||||
@ -49,6 +51,7 @@ GOFILES_linux=\
|
||||
sys_linux.go\
|
||||
exec_posix.go\
|
||||
exec_unix.go\
|
||||
signal_unix.go\
|
||||
|
||||
GOFILES_windows=\
|
||||
dir_windows.go\
|
||||
@ -60,6 +63,7 @@ GOFILES_windows=\
|
||||
sys_windows.go\
|
||||
exec_posix.go\
|
||||
exec_windows.go\
|
||||
signal_windows.go\
|
||||
|
||||
GOFILES_plan9=\
|
||||
dir_plan9.go\
|
||||
@ -72,4 +76,12 @@ GOFILES_plan9=\
|
||||
|
||||
GOFILES+=$(GOFILES_$(GOOS))
|
||||
|
||||
CLEANFILES+=signal_unix.go signal_windows.go
|
||||
|
||||
include ../../Make.pkg
|
||||
|
||||
signal_unix.go: ../syscall/zerrors_$(GOOS)_$(GOARCH).go
|
||||
./mkunixsignals.sh $< > $@ || rm -f $@
|
||||
|
||||
signal_windows.go: ../syscall/ztypes_$(GOOS)_$(GOARCH).go
|
||||
./mkunixsignals.sh $< > $@ || rm -f $@
|
||||
|
@ -4,7 +4,25 @@
|
||||
|
||||
package os
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"runtime"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// A Signal can represent any operating system signal.
|
||||
type Signal interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
type UnixSignal int32
|
||||
|
||||
func (sig UnixSignal) String() string {
|
||||
s := runtime.Signame(int32(sig))
|
||||
if len(s) > 0 {
|
||||
return s
|
||||
}
|
||||
return "UnixSignal"
|
||||
}
|
||||
|
||||
// StartProcess starts a new process with the program, arguments and attributes
|
||||
// specified by name, argv and attr.
|
||||
@ -34,6 +52,11 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err E
|
||||
return newProcess(pid, h), nil
|
||||
}
|
||||
|
||||
// Kill causes the Process to exit immediately.
|
||||
func (p *Process) Kill() Error {
|
||||
return p.Signal(SIGKILL)
|
||||
}
|
||||
|
||||
// Exec replaces the current process with an execution of the
|
||||
// named binary, with arguments argv and environment envv.
|
||||
// If successful, Exec never returns. If it fails, it returns an Error.
|
||||
|
@ -45,6 +45,14 @@ func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// Signal sends a signal to the Process.
|
||||
func (p *Process) Signal(sig Signal) Error {
|
||||
if e := syscall.Kill(p.Pid, int(sig.(UnixSignal))); e != 0 {
|
||||
return Errno(e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Release releases any resources associated with the Process.
|
||||
func (p *Process) Release() Error {
|
||||
// NOOP for unix.
|
||||
|
@ -20,13 +20,23 @@ func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
|
||||
return nil, ErrorString("os: unexpected result from WaitForSingleObject")
|
||||
}
|
||||
var ec uint32
|
||||
e = syscall.GetExitCodeProcess(uint32(p.handle), &ec)
|
||||
e = syscall.GetExitCodeProcess(int32(p.handle), &ec)
|
||||
if e != 0 {
|
||||
return nil, NewSyscallError("GetExitCodeProcess", e)
|
||||
}
|
||||
return &Waitmsg{p.Pid, syscall.WaitStatus{s, ec}, new(syscall.Rusage)}, nil
|
||||
}
|
||||
|
||||
// Signal sends a signal to the Process.
|
||||
func (p *Process) Signal(sig Signal) Error {
|
||||
switch sig.(UnixSignal) {
|
||||
case SIGKILL:
|
||||
e := syscall.TerminateProcess(int32(p.handle), 1)
|
||||
return NewSyscallError("TerminateProcess", e)
|
||||
}
|
||||
return Errno(syscall.EWINDOWS)
|
||||
}
|
||||
|
||||
func (p *Process) Release() Error {
|
||||
if p.handle == -1 {
|
||||
return EINVAL
|
||||
|
@ -8,7 +8,7 @@ echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
|
||||
echo
|
||||
|
||||
cat <<EOH
|
||||
package signal
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall"
|
@ -7,11 +7,5 @@ include ../../../Make.inc
|
||||
TARG=os/signal
|
||||
GOFILES=\
|
||||
signal.go\
|
||||
unix.go\
|
||||
|
||||
CLEANFILES+=unix.go
|
||||
|
||||
include ../../../Make.pkg
|
||||
|
||||
unix.go: ../../syscall/zerrors_$(GOOS)_$(GOARCH).go
|
||||
./mkunix.sh $< > $@ || rm -f $@
|
||||
|
@ -6,35 +6,20 @@
|
||||
package signal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// A Signal can represent any operating system signal.
|
||||
type Signal interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
type UnixSignal int32
|
||||
|
||||
func (sig UnixSignal) String() string {
|
||||
s := runtime.Signame(int32(sig))
|
||||
if len(s) > 0 {
|
||||
return s
|
||||
}
|
||||
return "Signal " + strconv.Itoa(int(sig))
|
||||
}
|
||||
|
||||
// Incoming is the global signal channel.
|
||||
// All signals received by the program will be delivered to this channel.
|
||||
var Incoming <-chan Signal
|
||||
var Incoming <-chan os.Signal
|
||||
|
||||
func process(ch chan<- Signal) {
|
||||
func process(ch chan<- os.Signal) {
|
||||
for {
|
||||
var mask uint32 = runtime.Sigrecv()
|
||||
for sig := uint(0); sig < 32; sig++ {
|
||||
if mask&(1<<sig) != 0 {
|
||||
ch <- UnixSignal(sig)
|
||||
ch <- os.UnixSignal(sig)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,7 +27,7 @@ func process(ch chan<- Signal) {
|
||||
|
||||
func init() {
|
||||
runtime.Siginit()
|
||||
ch := make(chan Signal) // Done here so Incoming can have type <-chan Signal
|
||||
ch := make(chan os.Signal) // Done here so Incoming can have type <-chan Signal
|
||||
Incoming = ch
|
||||
go process(ch)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
package signal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
@ -13,7 +14,7 @@ func TestSignal(t *testing.T) {
|
||||
// Send this process a SIGHUP.
|
||||
syscall.Syscall(syscall.SYS_KILL, uintptr(syscall.Getpid()), syscall.SIGHUP, 0)
|
||||
|
||||
if sig := (<-Incoming).(UnixSignal); sig != SIGHUP {
|
||||
t.Errorf("signal was %v, want %v", sig, SIGHUP)
|
||||
if sig := (<-Incoming).(os.UnixSignal); sig != os.SIGHUP {
|
||||
t.Errorf("signal was %v, want %v", sig, os.SIGHUP)
|
||||
}
|
||||
}
|
||||
|
@ -141,8 +141,9 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, errno
|
||||
//sys GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (errno int)
|
||||
//sys CancelIo(s uint32) (errno int)
|
||||
//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (errno int) = CreateProcessW
|
||||
//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle uint32, errno int)
|
||||
//sys GetExitCodeProcess(handle uint32, exitcode *uint32) (errno int)
|
||||
//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle int32, errno int)
|
||||
//sys TerminateProcess(handle int32, exitcode uint32) (errno int)
|
||||
//sys GetExitCodeProcess(handle int32, exitcode *uint32) (errno int)
|
||||
//sys GetStartupInfo(startupInfo *StartupInfo) (errno int) = GetStartupInfoW
|
||||
//sys GetCurrentProcess() (pseudoHandle int32, errno int)
|
||||
//sys DuplicateHandle(hSourceProcessHandle int32, hSourceHandle int32, hTargetProcessHandle int32, lpTargetHandle *int32, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (errno int)
|
||||
@ -697,10 +698,6 @@ func BindToDevice(fd int, device string) (errno int) { return
|
||||
|
||||
// TODO(brainman): fix all needed for os
|
||||
|
||||
const (
|
||||
SIGTRAP = 5
|
||||
)
|
||||
|
||||
func Getpid() (pid int) { return -1 }
|
||||
func Getppid() (ppid int) { return -1 }
|
||||
|
||||
|
@ -46,6 +46,7 @@ var (
|
||||
procCancelIo = getSysProcAddr(modkernel32, "CancelIo")
|
||||
procCreateProcessW = getSysProcAddr(modkernel32, "CreateProcessW")
|
||||
procOpenProcess = getSysProcAddr(modkernel32, "OpenProcess")
|
||||
procTerminateProcess = getSysProcAddr(modkernel32, "TerminateProcess")
|
||||
procGetExitCodeProcess = getSysProcAddr(modkernel32, "GetExitCodeProcess")
|
||||
procGetStartupInfoW = getSysProcAddr(modkernel32, "GetStartupInfoW")
|
||||
procGetCurrentProcess = getSysProcAddr(modkernel32, "GetCurrentProcess")
|
||||
@ -542,7 +543,7 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA
|
||||
return
|
||||
}
|
||||
|
||||
func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle uint32, errno int) {
|
||||
func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle int32, errno int) {
|
||||
var _p0 uint32
|
||||
if inheritHandle {
|
||||
_p0 = 1
|
||||
@ -550,7 +551,7 @@ func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle uint32, errn
|
||||
_p0 = 0
|
||||
}
|
||||
r0, _, e1 := Syscall(procOpenProcess, 3, uintptr(da), uintptr(_p0), uintptr(pid))
|
||||
handle = uint32(r0)
|
||||
handle = int32(r0)
|
||||
if handle == 0 {
|
||||
if e1 != 0 {
|
||||
errno = int(e1)
|
||||
@ -563,7 +564,21 @@ func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle uint32, errn
|
||||
return
|
||||
}
|
||||
|
||||
func GetExitCodeProcess(handle uint32, exitcode *uint32) (errno int) {
|
||||
func TerminateProcess(handle int32, exitcode uint32) (errno int) {
|
||||
r1, _, e1 := Syscall(procTerminateProcess, 2, uintptr(handle), uintptr(exitcode), 0)
|
||||
if int(r1) == 0 {
|
||||
if e1 != 0 {
|
||||
errno = int(e1)
|
||||
} else {
|
||||
errno = EINVAL
|
||||
}
|
||||
} else {
|
||||
errno = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetExitCodeProcess(handle int32, exitcode *uint32) (errno int) {
|
||||
r1, _, e1 := Syscall(procGetExitCodeProcess, 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
|
||||
if int(r1) == 0 {
|
||||
if e1 != 0 {
|
||||
|
@ -48,6 +48,23 @@ const (
|
||||
O_CLOEXEC = 0x80000
|
||||
)
|
||||
|
||||
const (
|
||||
// More invented values for signals
|
||||
SIGHUP = 0x1
|
||||
SIGINT = 0x2
|
||||
SIGQUIT = 0x3
|
||||
SIGILL = 0x4
|
||||
SIGTRAP = 0x5
|
||||
SIGABRT = 0x6
|
||||
SIGBUS = 0x7
|
||||
SIGFPE = 0x8
|
||||
SIGKILL = 0x9
|
||||
SIGSEGV = 0xb
|
||||
SIGPIPE = 0xd
|
||||
SIGALRM = 0xe
|
||||
SIGTERM = 0xf
|
||||
)
|
||||
|
||||
const (
|
||||
GENERIC_READ = 0x80000000
|
||||
GENERIC_WRITE = 0x40000000
|
||||
|
Loading…
Reference in New Issue
Block a user