Windows: don't overwrite PID file if process exists

pidfile.New() was opening a file in /proc to determine if the owning
process still exists. Use syscall.OpenProcess() on Windows instead.

Other OSes may also need to be updated here.

Signed-off-by: John Starks <jostarks@microsoft.com>
This commit is contained in:
John Starks 2016-04-18 15:09:55 -07:00
parent c35a0da252
commit 95e8c2599c
4 changed files with 47 additions and 3 deletions

View file

@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
) )
@ -21,7 +20,7 @@ func checkPIDFileAlreadyExists(path string) error {
if pidByte, err := ioutil.ReadFile(path); err == nil { if pidByte, err := ioutil.ReadFile(path); err == nil {
pidString := strings.TrimSpace(string(pidByte)) pidString := strings.TrimSpace(string(pidByte))
if pid, err := strconv.Atoi(pidString); err == nil { if pid, err := strconv.Atoi(pidString); err == nil {
if _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid))); err == nil { if processExists(pid) {
return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path) return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path)
} }
} }

View file

@ -13,11 +13,17 @@ func TestNewAndRemove(t *testing.T) {
t.Fatal("Could not create test directory") t.Fatal("Could not create test directory")
} }
file, err := New(filepath.Join(dir, "testfile")) path := filepath.Join(dir, "testfile")
file, err := New(path)
if err != nil { if err != nil {
t.Fatal("Could not create test file", err) t.Fatal("Could not create test file", err)
} }
_, err = New(path)
if err == nil {
t.Fatal("Test file creation not blocked")
}
if err := file.Remove(); err != nil { if err := file.Remove(); err != nil {
t.Fatal("Could not delete created test file") t.Fatal("Could not delete created test file")
} }

16
pidfile/pidfile_unix.go Normal file
View file

@ -0,0 +1,16 @@
// +build !windows
package pidfile
import (
"os"
"path/filepath"
"strconv"
)
func processExists(pid int) bool {
if _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid))); err == nil {
return true
}
return false
}

View file

@ -0,0 +1,23 @@
package pidfile
import "syscall"
const (
processQueryLimitedInformation = 0x1000
stillActive = 259
)
func processExists(pid int) bool {
h, err := syscall.OpenProcess(processQueryLimitedInformation, false, uint32(pid))
if err != nil {
return false
}
var c uint32
err = syscall.GetExitCodeProcess(h, &c)
syscall.Close(h)
if err != nil {
return c == stillActive
}
return true
}