pkg.re/essentialkaos/ek.v11@v12.41.0+incompatible/pid/pid.go (about) 1 // Package pid provides methods for working with PID files 2 package pid 3 4 // ////////////////////////////////////////////////////////////////////////////////// // 5 // // 6 // Copyright (c) 2022 ESSENTIAL KAOS // 7 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 8 // // 9 // ////////////////////////////////////////////////////////////////////////////////// // 10 11 import ( 12 "errors" 13 "fmt" 14 "io/ioutil" 15 "os" 16 "strconv" 17 "strings" 18 19 "pkg.re/essentialkaos/ek.v12/fsutil" 20 ) 21 22 // ////////////////////////////////////////////////////////////////////////////////// // 23 24 // Dir is a path to directory with PID files 25 var Dir = "/var/run" 26 27 // ////////////////////////////////////////////////////////////////////////////////// // 28 29 // Create creates file with process PID file 30 func Create(name string) error { 31 err := checkPIDDir(Dir, true) 32 33 if err != nil { 34 return err 35 } 36 37 if name == "" { 38 return errors.New("PID file name can't be blank") 39 } 40 41 pidFile := Dir + "/" + normalizePIDFilename(name) 42 43 if fsutil.IsExist(pidFile) { 44 os.Remove(pidFile) 45 } 46 47 return ioutil.WriteFile( 48 pidFile, 49 []byte(fmt.Sprintf("%d\n", os.Getpid())), 50 0644, 51 ) 52 } 53 54 // Remove removes file with process PID file 55 func Remove(name string) error { 56 err := checkPIDDir(Dir, true) 57 58 if err != nil { 59 return err 60 } 61 62 pidFile := Dir + "/" + normalizePIDFilename(name) 63 64 return os.Remove(pidFile) 65 } 66 67 // Get returns PID from PID file 68 func Get(name string) int { 69 err := checkPIDDir(Dir, false) 70 71 if err != nil { 72 return -1 73 } 74 75 pidFile := Dir + "/" + normalizePIDFilename(name) 76 77 return Read(pidFile) 78 } 79 80 // Read just reads PID from PID file 81 func Read(pidFile string) int { 82 data, err := ioutil.ReadFile(pidFile) 83 84 if err != nil { 85 return -1 86 } 87 88 pid, err := strconv.Atoi(strings.TrimRight(string(data), "\n")) 89 90 if err != nil { 91 return -1 92 } 93 94 return pid 95 } 96 97 // ////////////////////////////////////////////////////////////////////////////////// // 98 99 // checkPIDDir checks directory path and return error if directory not ok 100 func checkPIDDir(path string, requireModify bool) error { 101 switch { 102 case !fsutil.IsExist(path): 103 return errors.New("Directory " + path + " does not exist") 104 105 case !fsutil.IsDir(path): 106 return errors.New(path + " is not directory") 107 108 case !fsutil.IsWritable(path) && requireModify: 109 return errors.New("Directory " + path + " is not writable") 110 111 case !fsutil.IsReadable(path): 112 return errors.New("Directory " + path + " is not readable") 113 } 114 115 return nil 116 } 117 118 // normalizePIDFilename returns PID file name with extension 119 func normalizePIDFilename(name string) string { 120 if !strings.Contains(name, ".pid") { 121 return name + ".pid" 122 } 123 124 return name 125 }