Commit 9b2561ef authored by Alex Brainman's avatar Alex Brainman

os: request appropriate access rights before calling windows TerminateProcess

Fixes #5615.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/9651047
parent 02a891b3
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment