Skip to content

Commit fd032cb

Browse files
author
miktwon
committed
0.0.1
1 parent f846ea6 commit fd032cb

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@
1212

1313
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
1414
.glide/
15+
16+
debug
17+
docker-fpm-wrapper

dataListener.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"fmt"
7+
"net"
8+
"os"
9+
)
10+
11+
type DataListener struct {
12+
socketPath string
13+
listener net.Listener
14+
dataChan chan string
15+
errorChan chan error
16+
}
17+
18+
func NewDataListener(socketPath string, dataChan chan string, errorChan chan error) *DataListener {
19+
return &DataListener{socketPath, nil, dataChan, errorChan}
20+
}
21+
22+
func (l *DataListener) handleConnection(conn net.Conn) {
23+
buf := bytes.NewBuffer(make([]byte, 0, bytes.MinRead))
24+
25+
_, err := buf.ReadFrom(conn)
26+
conn.Close()
27+
28+
if err != nil {
29+
l.errorChan <- err
30+
return
31+
}
32+
33+
l.dataChan <- buf.String()
34+
}
35+
36+
func (l *DataListener) initSocket() error {
37+
var err error
38+
var c net.Conn
39+
40+
if _, err = os.Stat(l.socketPath); !os.IsNotExist(err) {
41+
// socket exists
42+
c, err = net.Dial("unix", l.socketPath)
43+
if err == nil {
44+
c.Close()
45+
// socket exists and listening
46+
return errors.New(fmt.Sprintf("Socket %s already exists and listening", l.socketPath))
47+
}
48+
49+
err = os.Remove(l.socketPath)
50+
if err != nil {
51+
return err
52+
}
53+
}
54+
55+
l.listener, err = net.Listen("unix", l.socketPath)
56+
57+
return err
58+
}
59+
60+
func (l *DataListener) acceptConnections() {
61+
for {
62+
conn, err := l.listener.Accept()
63+
if err != nil {
64+
l.errorChan <- err
65+
return
66+
}
67+
68+
go l.handleConnection(conn)
69+
}
70+
}
71+
72+
func (l *DataListener) Start() error {
73+
err := l.initSocket()
74+
75+
if err == nil {
76+
go l.acceptConnections()
77+
}
78+
79+
return err
80+
}
81+
82+
func (l *DataListener) Stop() {
83+
l.listener.Close()
84+
}

main.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"os/signal"
8+
"syscall"
9+
10+
"github.com/FZambia/viper-lite"
11+
"github.com/spf13/pflag"
12+
)
13+
14+
func init() {
15+
pflag.StringP("fpm", "f", "", "path to php-fpm")
16+
pflag.StringP("socket", "s", "", "path to socket")
17+
pflag.Parse()
18+
19+
viper.BindPFlags(pflag.CommandLine)
20+
}
21+
22+
func main() {
23+
signalCh := make(chan os.Signal, 1)
24+
signal.Notify(signalCh, os.Interrupt)
25+
signal.Notify(signalCh, os.Kill)
26+
27+
cmd := exec.Command(viper.GetString("fpm"))
28+
cmd.Stdout = os.Stdout
29+
cmd.Stderr = os.Stderr
30+
cmd.Env = os.Environ()
31+
cmd.Env = append(cmd.Env, fmt.Sprintf("LOGGER_SOCK_PATH=%s", viper.GetString("socket")))
32+
cmd.Args = append(cmd.Args, "--nodaemonize")
33+
cmd.Args = append(cmd.Args, findFpmArgs()...)
34+
35+
err := cmd.Start()
36+
if err != nil {
37+
fmt.Printf("exec.Command: %v", err)
38+
os.Exit(1)
39+
}
40+
41+
go handleSignals(cmd, signalCh)
42+
procErrCh := make(chan error, 1)
43+
go func() {
44+
procErrCh <- cmd.Wait()
45+
}()
46+
47+
dataChan := make(chan string, 1)
48+
errChan := make(chan error, 1)
49+
dataListener := NewDataListener(viper.GetString("socket"), dataChan, errChan)
50+
51+
dataListener.Start()
52+
defer dataListener.Stop()
53+
54+
for {
55+
select {
56+
case data := <-dataChan:
57+
os.Stderr.WriteString(data)
58+
case err := <-errChan:
59+
if err != nil {
60+
panic(err)
61+
}
62+
case err := <-procErrCh:
63+
if err == nil {
64+
os.Exit(0)
65+
}
66+
if exiterr, ok := err.(*exec.ExitError); ok {
67+
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
68+
os.Exit(status.ExitStatus())
69+
}
70+
} else {
71+
panic(err)
72+
}
73+
}
74+
}
75+
}
76+
77+
func findFpmArgs() []string {
78+
doubleDashIndex := -1
79+
80+
for i := range os.Args {
81+
if os.Args[i] == "--" {
82+
doubleDashIndex = i
83+
break
84+
}
85+
}
86+
if doubleDashIndex == -1 || doubleDashIndex+1 == len(os.Args) {
87+
return nil
88+
}
89+
90+
return os.Args[doubleDashIndex+1:]
91+
}
92+
93+
func handleSignals(cmd *exec.Cmd, signalCh chan os.Signal) {
94+
for {
95+
err := cmd.Process.Signal(<-signalCh)
96+
if err != nil {
97+
fmt.Printf("cmd.Process.Signal: %v", err)
98+
os.Exit(1)
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)