mirror of
https://github.com/golang/go
synced 2024-11-22 14:34:45 -07:00
os: request appropriate access rights before calling windows TerminateProcess
Fixes #5615. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/9651047
This commit is contained in:
parent
02a891b30b
commit
9b2561ef16
@ -42,13 +42,22 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
|
||||
}
|
||||
|
||||
func terminateProcess(pid, exitcode int) error {
|
||||
h, e := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(pid))
|
||||
if e != nil {
|
||||
return NewSyscallError("OpenProcess", e)
|
||||
}
|
||||
defer syscall.CloseHandle(h)
|
||||
e = syscall.TerminateProcess(h, uint32(exitcode))
|
||||
return NewSyscallError("TerminateProcess", e)
|
||||
}
|
||||
|
||||
func (p *Process) signal(sig Signal) error {
|
||||
if p.done() {
|
||||
return errors.New("os: process already finished")
|
||||
}
|
||||
if sig == Kill {
|
||||
e := syscall.TerminateProcess(syscall.Handle(p.handle), 1)
|
||||
return NewSyscallError("TerminateProcess", e)
|
||||
return terminateProcess(p.Pid, 1)
|
||||
}
|
||||
// TODO(rsc): Handle Interrupt too?
|
||||
return syscall.Errno(syscall.EWINDOWS)
|
||||
|
@ -11,11 +11,13 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
. "os"
|
||||
osexec "os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -1130,3 +1132,72 @@ func TestReadAtEOF(t *testing.T) {
|
||||
t.Fatalf("ReadAt failed: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testKillProcess(t *testing.T, processKiller func(p *Process)) {
|
||||
dir, err := ioutil.TempDir("", "go-build")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer RemoveAll(dir)
|
||||
|
||||
src := filepath.Join(dir, "main.go")
|
||||
f, err := Create(src)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create %v: %v", src, err)
|
||||
}
|
||||
st := template.Must(template.New("source").Parse(`
|
||||
package main
|
||||
import "time"
|
||||
func main() {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
`))
|
||||
err = st.Execute(f, nil)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
t.Fatalf("Failed to execute template: %v", err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
exe := filepath.Join(dir, "main.exe")
|
||||
output, err := osexec.Command("go", "build", "-o", exe, src).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to build exe %v: %v %v", exe, err, string(output))
|
||||
}
|
||||
|
||||
cmd := osexec.Command(exe)
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to start test process: %v", err)
|
||||
}
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
processKiller(cmd.Process)
|
||||
}()
|
||||
err = cmd.Wait()
|
||||
if err == nil {
|
||||
t.Errorf("Test process succeeded, but expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestKillStartProcess(t *testing.T) {
|
||||
testKillProcess(t, func(p *Process) {
|
||||
err := p.Kill()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to kill test process: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestKillFindProcess(t *testing.T) {
|
||||
testKillProcess(t, func(p *Process) {
|
||||
p2, err := FindProcess(p.Pid)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to find test process: %v", err)
|
||||
}
|
||||
err = p2.Kill()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to kill test process: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -151,6 +151,7 @@ const (
|
||||
CREATE_NEW_PROCESS_GROUP = 0x00000200
|
||||
CREATE_UNICODE_ENVIRONMENT = 0x00000400
|
||||
|
||||
PROCESS_TERMINATE = 1
|
||||
PROCESS_QUERY_INFORMATION = 0x00000400
|
||||
SYNCHRONIZE = 0x00100000
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user