diff --git a/main.go b/main.go index c55f0b4..cf843a1 100644 --- a/main.go +++ b/main.go @@ -1,22 +1,60 @@ package main import ( + "bytes" + "encoding/binary" + "errors" "log" "os" + "os/exec" "sync" ) var config Config const sockfile = "/tmp/gopaper.sock" +const pidfilePath = "/var/run/gopaper.pid" func main() { - - //TODO:kill existing processes - log.SetFlags(log.LstdFlags | log.Lshortfile) - err := config.load() + //MANAGE PIDFILES + //check if pidfile already exists + if _, err := os.Stat(pidfilePath); !errors.Is(err, os.ErrNotExist) { + //if it does, kill the process and delete the pidfile + prexPid, err := os.ReadFile(pidfilePath) + if err != nil { + log.Println("unable to read pre-existing pidfile", err) + cleanExit(1) + } + //kill process + err = exec.Command("kill", "-9", string(prexPid)).Run() + if err != nil { + log.Printf("unable to kill process %v\n", prexPid) + cleanExit(1) + } + //remove pidfile + err = os.Remove(pidfilePath) + if err != nil { + log.Printf("unable to remove pidfile %v\n", pidfilePath) + cleanExit(1) + } + } + + //create new pidfile + pid := os.Getpid() + pidfile, err := os.Create(pidfilePath) + if err != nil { + log.Println("could not create pidfile", err) + cleanExit(1) + } + buf := new(bytes.Buffer) + err = binary.Write(buf, binary.LittleEndian, pid) + if err != nil { + } + pidfile.Write(buf.Bytes()) + + err = config.load() logfile, err := openLogfile() if err != nil { log.Println("failed to load config", err) @@ -33,7 +71,7 @@ func main() { func() { defer func() { if r := recover(); r != nil { - log.Println("Panic recovered at top level. Closing gracefully.", r) + log.Println("Panic recovered at top level", r) cleanExit(1) } }() @@ -63,6 +101,24 @@ func openLogfile() (*os.File, error) { } func cleanExit(code int) { - os.Remove(sockfile) + if code == 1 { + log.Println("shutting down gracefully after errors") + } else { + log.Println("shutting down gracefully") + } + + err := os.Remove(sockfile) + if err != nil { + log.Printf("unable to remove sockfile at %v. Error: %v\n", sockfile, err) + } else { + log.Println("sockfile removed") + } + + err = os.Remove(pidfilePath) + if err != nil { + log.Printf("unable to remove pidfile at %v. Error: %v\n", pidfilePath, err) + } else { + log.Println("pidfile removed") + } os.Exit(code) } diff --git a/server.go b/server.go index e5247db..06cdf8d 100644 --- a/server.go +++ b/server.go @@ -25,8 +25,7 @@ func server(slideshowDir chan string) { signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c - os.Remove(sockfile) - os.Exit(1) + cleanExit(0) }() for {