]> Cypherpunks repositories - gostls13.git/commitdiff
os: request appropriate access rights before calling windows TerminateProcess
authorAlex Brainman <alex.brainman@gmail.com>
Tue, 11 Jun 2013 03:06:38 +0000 (13:06 +1000)
committerAlex Brainman <alex.brainman@gmail.com>
Tue, 11 Jun 2013 03:06:38 +0000 (13:06 +1000)
Fixes #5615.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/9651047

src/pkg/os/exec_windows.go
src/pkg/os/os_test.go
src/pkg/syscall/ztypes_windows.go

index 4aa2ade631ed7b151ec831aaf3a083681f6923af..c4f3d4f8530dafb30f4a425f5d88c94713c030cd 100644 (file)
@@ -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)
index 1009600fef8399a143844b68c4c530bccd892685..025b709b81ce3e811f51e3945f4689984396c6ba 100644 (file)
@@ -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)
+               }
+       })
+}
index fb74b3e57ce18dcdc4e93fa401eab47e666ca625..2e9508b1fe2954012ad1896e651e069295047c13 100644 (file)
@@ -151,6 +151,7 @@ const (
        CREATE_NEW_PROCESS_GROUP   = 0x00000200
        CREATE_UNICODE_ENVIRONMENT = 0x00000400
 
+       PROCESS_TERMINATE         = 1
        PROCESS_QUERY_INFORMATION = 0x00000400
        SYNCHRONIZE               = 0x00100000