github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/pkg/pidfile/pidfile.go (about) 1 // Package pidfile provides structure and helper functions to create and remove 2 // PID file. A PID file is usually a file used to store the process ID of a 3 // running process. 4 package pidfile // import "github.com/docker/docker/pkg/pidfile" 5 6 import ( 7 "bytes" 8 "fmt" 9 "os" 10 "strconv" 11 12 "github.com/docker/docker/pkg/process" 13 ) 14 15 // Read reads the "PID file" at path, and returns the PID if it contains a 16 // valid PID of a running process, or 0 otherwise. It returns an error when 17 // failing to read the file, or if the file doesn't exist, but malformed content 18 // is ignored. Consumers should therefore check if the returned PID is a non-zero 19 // value before use. 20 func Read(path string) (pid int, err error) { 21 pidByte, err := os.ReadFile(path) 22 if err != nil { 23 return 0, err 24 } 25 pid, err = strconv.Atoi(string(bytes.TrimSpace(pidByte))) 26 if err != nil { 27 return 0, nil 28 } 29 if pid != 0 && process.Alive(pid) { 30 return pid, nil 31 } 32 return 0, nil 33 } 34 35 // Write writes a "PID file" at the specified path. It returns an error if the 36 // file exists and contains a valid PID of a running process, or when failing 37 // to write the file. 38 func Write(path string, pid int) error { 39 if pid < 1 { 40 // We might be running as PID 1 when running docker-in-docker, 41 // but 0 or negative PIDs are not acceptable. 42 return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid) 43 } 44 oldPID, err := Read(path) 45 if err != nil && !os.IsNotExist(err) { 46 return err 47 } 48 if oldPID != 0 { 49 return fmt.Errorf("process with PID %d is still running", oldPID) 50 } 51 return os.WriteFile(path, []byte(strconv.Itoa(pid)), 0o644) 52 }