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  }