Skip to content

Instantly share code, notes, and snippets.

@Miguel-Dorta
Last active April 18, 2020 23:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Miguel-Dorta/b7ac93db04da7e55a2f5bed7f2348958 to your computer and use it in GitHub Desktop.
Save Miguel-Dorta/b7ac93db04da7e55a2f5bed7f2348958 to your computer and use it in GitHub Desktop.
Systemd wrapper for Minecraft servers.
// MIT License <https://opensource.org/licenses/MIT> - Copyright (c) 2020 Miguel Dorta
package main
import (
"fmt"
"golang.org/x/sys/unix"
"io"
"os"
"os/exec"
"os/signal"
)
const programName = "MinecraftSystemdWrapper"
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: " + programName + " [command]")
os.Exit(1)
}
cmd := exec.Command(os.Args[1], os.Args[2:]...)
cmd.SysProcAttr = &unix.SysProcAttr{Setpgid:true}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
stdin, err := cmd.StdinPipe()
if err != nil {
printError("error getting process stdin pipe: %s", err)
os.Exit(1)
}
exited := make(chan bool, 1)
quit := make(chan os.Signal, 2)
signal.Notify(quit, unix.SIGINT, unix.SIGTERM)
go func() {
if err := cmd.Run(); err != nil {
printError("minecraft process returned an error: %s", err)
os.Exit(1)
}
exited <- true
}()
select {
case <-exited:
os.Exit(0)
case <-quit:
}
if _, err := io.WriteString(stdin, "stop\n"); err != nil {
printError("error writing stop command to minecraft process: %s", err)
if err := cmd.Process.Kill(); err != nil {
printError("error killing minecraft process: %s", err)
}
os.Exit(1)
}
<- exited
os.Exit(0)
}
func printError(format string, a ...interface{}) {
format = fmt.Sprintf("%s: %s\n", programName, format)
_, _ = fmt.Fprintf(os.Stderr, format, a...)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment