pkg/pidfile, pkg/process: use single implementation for process alive
Using the implementation from pkg/pidfile for windows, as that implementation looks to be handling more cases to check if a process is still alive (or to be considered alive). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
9d5e754caa
commit
55d15e9d05
6 changed files with 50 additions and 74 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/docker/pkg/process"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
)
|
||||
|
||||
|
@ -22,7 +23,7 @@ func checkPIDFileAlreadyExists(path string) error {
|
|||
return err
|
||||
}
|
||||
pid, err := strconv.Atoi(string(bytes.TrimSpace(pidByte)))
|
||||
if err == nil && processExists(pid) {
|
||||
if err == nil && process.Alive(pid) {
|
||||
return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package pidfile // import "github.com/docker/docker/pkg/pidfile"
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func processExists(pid int) bool {
|
||||
// OS X does not have a proc filesystem.
|
||||
// Use kill -0 pid to judge if the process exists.
|
||||
err := unix.Kill(pid, 0)
|
||||
return err == nil
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
//go:build !windows && !darwin
|
||||
// +build !windows,!darwin
|
||||
|
||||
package pidfile // import "github.com/docker/docker/pkg/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
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package pidfile // import "github.com/docker/docker/pkg/pidfile"
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func processExists(pid int) bool {
|
||||
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
var c uint32
|
||||
err = windows.GetExitCodeProcess(h, &c)
|
||||
_ = windows.CloseHandle(h)
|
||||
if err != nil {
|
||||
// From the GetExitCodeProcess function (processthreadsapi.h) API docs:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess
|
||||
//
|
||||
// The GetExitCodeProcess function returns a valid error code defined by the
|
||||
// application only after the thread terminates. Therefore, an application should
|
||||
// not use STILL_ACTIVE (259) as an error code (STILL_ACTIVE is a macro for
|
||||
// STATUS_PENDING (minwinbase.h)). If a thread returns STILL_ACTIVE (259) as
|
||||
// an error code, then applications that test for that value could interpret it
|
||||
// to mean that the thread is still running, and continue to test for the
|
||||
// completion of the thread after the thread has terminated, which could put
|
||||
// the application into an infinite loop.
|
||||
return c == uint32(windows.STATUS_PENDING)
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
//go:build linux || freebsd || darwin
|
||||
// +build linux freebsd darwin
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package process
|
||||
|
||||
|
@ -7,18 +7,32 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Alive returns true if process with a given pid is running.
|
||||
func Alive(pid int) bool {
|
||||
err := unix.Kill(pid, 0)
|
||||
if err == nil || err == unix.EPERM {
|
||||
return true
|
||||
}
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
// OS X does not have a proc filesystem. Use kill -0 pid to judge if the
|
||||
// process exists. From KILL(2): https://www.freebsd.org/cgi/man.cgi?query=kill&sektion=2&manpath=OpenDarwin+7.2.1
|
||||
//
|
||||
// Sig may be one of the signals specified in sigaction(2) or it may
|
||||
// be 0, in which case error checking is performed but no signal is
|
||||
// actually sent. This can be used to check the validity of pid.
|
||||
err := unix.Kill(pid, 0)
|
||||
|
||||
return false
|
||||
// Either the PID was found (no error) or we get an EPERM, which means
|
||||
// the PID exists, but we don't have permissions to signal it.
|
||||
return err == nil || err == unix.EPERM
|
||||
default:
|
||||
_, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid)))
|
||||
return err == nil
|
||||
}
|
||||
}
|
||||
|
||||
// Kill force-stops a process.
|
||||
|
|
|
@ -1,12 +1,35 @@
|
|||
package process
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Alive returns true if process with a given pid is running.
|
||||
func Alive(pid int) bool {
|
||||
_, err := os.FindProcess(pid)
|
||||
|
||||
return err == nil
|
||||
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
var c uint32
|
||||
err = windows.GetExitCodeProcess(h, &c)
|
||||
_ = windows.CloseHandle(h)
|
||||
if err != nil {
|
||||
// From the GetExitCodeProcess function (processthreadsapi.h) API docs:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess
|
||||
//
|
||||
// The GetExitCodeProcess function returns a valid error code defined by the
|
||||
// application only after the thread terminates. Therefore, an application should
|
||||
// not use STILL_ACTIVE (259) as an error code (STILL_ACTIVE is a macro for
|
||||
// STATUS_PENDING (minwinbase.h)). If a thread returns STILL_ACTIVE (259) as
|
||||
// an error code, then applications that test for that value could interpret it
|
||||
// to mean that the thread is still running, and continue to test for the
|
||||
// completion of the thread after the thread has terminated, which could put
|
||||
// the application into an infinite loop.
|
||||
return c == uint32(windows.STATUS_PENDING)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Kill force-stops a process.
|
||||
|
|
Loading…
Reference in a new issue