$OpenBSD$

Index: vendor/github.com/ayufan/golang-kardianos-service/service_rc_openbsd.go
--- vendor/github.com/ayufan/golang-kardianos-service/service_rc_openbsd.go.orig
+++ vendor/github.com/ayufan/golang-kardianos-service/service_rc_openbsd.go
@@ -0,0 +1,168 @@
+// Copyright 2018 Aaron Bieber
+// Use of this source code is governed by a zlib-style
+// license that can be found in the LICENSE file.
+
+package service
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"os/signal"
+	"syscall"
+	"text/template"
+	"time"
+)
+
+type rc struct {
+	i Interface
+	*Config
+}
+
+func newRCService(i Interface, c *Config) (Service, error) {
+	s := &rc{
+		i:      i,
+		Config: c,
+	}
+
+	return s, nil
+}
+
+func (s *rc) String() string {
+	if len(s.DisplayName) > 0 {
+		return s.DisplayName
+	}
+	return s.Name
+}
+
+var errNoUserServiceRC = errors.New("user services are not supported on OpenBSD rc")
+
+func (s *rc) configPath() (cp string, err error) {
+	if s.Option.bool(optionUserService, optionUserServiceDefault) {
+		err = errNoUserServiceRC
+		return
+	}
+	cp = "/etc/rc.d/" + s.Config.Name
+	return
+}
+
+func (s *rc) template() (*template.Template, error) {
+	script := rcScript
+	return template.Must(template.New("").Funcs(tf).Parse(script)), nil
+}
+
+func (s *rc) Install() error {
+	confPath, err := s.configPath()
+	if err != nil {
+		return err
+	}
+	_, err = os.Stat(confPath)
+	if err == nil {
+		return fmt.Errorf("rc already exists: %s", confPath)
+	}
+
+	f, err := os.Create(confPath)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	path, err := s.execPath()
+	if err != nil {
+		return err
+	}
+
+	var to = &struct {
+		*Config
+		Path string
+	}{
+		s.Config,
+		path,
+	}
+
+	template, err := s.template()
+	if err != nil {
+		return err
+	}
+	err = template.Execute(f, to)
+	if err != nil {
+		return err
+	}
+
+	if err = os.Chmod(confPath, 0700); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (s *rc) Uninstall() error {
+	cp, err := s.configPath()
+	if err != nil {
+		return err
+	}
+	if err := os.Remove(cp); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *rc) Logger(errs chan<- error) (Logger, error) {
+	if system.Interactive() {
+		return ConsoleLogger, nil
+	}
+	return s.SystemLogger(errs)
+}
+func (s *rc) SystemLogger(errs chan<- error) (Logger, error) {
+	return newSysLogger(s.Name, errs)
+}
+
+func (s *rc) Run() (err error) {
+	err = s.i.Start(s)
+	if err != nil {
+		return err
+	}
+
+	s.Option.funcSingle(optionRunWait, func() {
+		var sigChan = make(chan os.Signal, 3)
+		signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
+		<-sigChan
+	})()
+
+	return s.i.Stop(s)
+}
+
+func (s *rc) Start() error {
+	return run("service", s.Name, "start")
+}
+
+func (s *rc) Stop() error {
+	return run("service", s.Name, "stop")
+}
+
+func (s *rc) Status() error {
+	return checkStatus("service", []string{s.Name, "status"}, "is running", "unrecognized service")
+}
+
+func (s *rc) Restart() error {
+	err := s.Stop()
+	if err != nil {
+		return err
+	}
+	time.Sleep(50 * time.Millisecond)
+	return s.Start()
+}
+
+const rcScript = `#!/bin/ksh
+# Auto generated by: {{.Name}}
+
+daemon="{{.Path}}"
+daemon_flags="{{range .Arguments}} {{.|cmd}}{{end}}"
+daemon_user="{{.UserName}}"
+
+. /etc/rc.d/rc.subr
+
+rc_bg=YES
+
+rc_cmd $1
+`
