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:
parent
c35a0da252
commit
95e8c2599c
4 changed files with 47 additions and 3 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
16
pidfile/pidfile_unix.go
Normal 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
|
||||||
|
}
|
23
pidfile/pidfile_windows.go
Normal file
23
pidfile/pidfile_windows.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in a new issue