summaryrefslogtreecommitdiff
path: root/vendor/github.com/xlgmokha/minit/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/xlgmokha/minit/main.go')
-rw-r--r--vendor/github.com/xlgmokha/minit/main.go122
1 files changed, 73 insertions, 49 deletions
diff --git a/vendor/github.com/xlgmokha/minit/main.go b/vendor/github.com/xlgmokha/minit/main.go
index 8fcf0e0..1e94c00 100644
--- a/vendor/github.com/xlgmokha/minit/main.go
+++ b/vendor/github.com/xlgmokha/minit/main.go
@@ -1,79 +1,103 @@
package main
import (
- "bufio"
+ "flag"
+ "log"
"os"
- "os/exec"
"os/signal"
"strings"
"sync"
"sync/atomic"
"syscall"
"time"
+
+ "github.com/xlgmokha/minit/pkg/procfile"
)
-func main() {
- file, _ := os.Open("Procfile")
- defer file.Close()
+var (
+ pidMutex sync.Mutex
+ pids []int
+ procfilePath *string
+)
+
+func init() {
+ procfilePath = flag.String("f", "Procfile", "path to Procfile")
+ flag.Parse()
+ log.SetFlags(0)
+}
+
+func addPid(pid int) {
+ pidMutex.Lock()
+ defer pidMutex.Unlock()
+ pids = append(pids, pid)
+}
+
+func removePid(pid int) {
+ pidMutex.Lock()
+ defer pidMutex.Unlock()
+
+ for i, p := range pids {
+ if p == pid {
+ pids = append(pids[:i], pids[i+1:]...)
+ break
+ }
+ }
+}
- var cmds []*exec.Cmd
+func forwardSignalToAll(sig os.Signal) {
+ pidMutex.Lock()
+ defer pidMutex.Unlock()
+
+ signal := sig.(syscall.Signal)
+ for _, pid := range pids {
+ syscall.Kill(-pid, signal)
+ }
+}
+
+func main() {
var wg sync.WaitGroup
var shutdown int32
- scanner := bufio.NewScanner(file)
- for scanner.Scan() {
- line := strings.TrimSpace(scanner.Text())
- if line == "" || strings.HasPrefix(line, "#") {
- continue
+ for _, path := range strings.Split(*procfilePath, ",") {
+ procs, err := procfile.ParseFile(path)
+ if err != nil {
+ log.Fatalln(err)
}
- parts := strings.SplitN(line, ":", 2)
- if len(parts) != 2 {
- continue
- }
+ for _, proc := range procs {
+ wg.Add(1)
+ go func(proc *procfile.Proc) {
+ defer wg.Done()
- args := strings.Fields(os.ExpandEnv(strings.TrimSpace(parts[1])))
- if len(args) == 0 {
- continue
- }
+ for atomic.LoadInt32(&shutdown) == 0 {
+ cmd := proc.NewCommand()
+
+ if cmd.Start() != nil {
+ time.Sleep(2 * time.Second)
+ continue
+ }
- cmd := exec.Command(args[0], args[1:]...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
-
- cmds = append(cmds, cmd)
-
- wg.Add(1)
- go func(args []string) {
- defer wg.Done()
- for atomic.LoadInt32(&shutdown) == 0 {
- cmd := exec.Command(args[0], args[1:]...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
-
- if cmd.Start() != nil {
- time.Sleep(2 * time.Second)
- continue
+ addPid(cmd.Process.Pid)
+ cmd.Wait()
+ removePid(cmd.Process.Pid)
+ time.Sleep(time.Second)
}
- cmd.Wait()
- time.Sleep(time.Second)
- }
- }(args)
+ }(proc)
+ }
}
sigChan := make(chan os.Signal, 1)
- signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
+ signal.Notify(sigChan)
go func() {
- <-sigChan
- atomic.StoreInt32(&shutdown, 1)
-
- for _, cmd := range cmds {
- if cmd.Process != nil {
- syscall.Kill(-cmd.Process.Pid, syscall.SIGTERM)
+ for sig := range sigChan {
+ if sig == syscall.SIGINT || sig == syscall.SIGTERM {
+ atomic.StoreInt32(&shutdown, 1)
+ forwardSignalToAll(sig)
+ return
}
+
+ forwardSignalToAll(sig)
}
}()