Permalink
Browse files

meek-client-wrapper: give child processes a chance to clean up, fixes…

… 15125
  • Loading branch information...
infinity0 committed Mar 4, 2015
1 parent 91e4560 commit 36bcdcab6dedd950e694b84987282961ab7f3f6f
Showing with 43 additions and 14 deletions.
  1. +43 −14 meek-client-wrapper/meek-client-wrapper.go
@@ -43,6 +43,7 @@ import (
"os/signal"
"regexp"
"syscall"
"time"
)
// This magic string is emitted by meek-http-helper.
@@ -53,13 +54,33 @@ func usage() {
flag.PrintDefaults()
}
// Log a call to os.Process.Kill.
func logKill(p *os.Process) error {
log.Printf("killing PID %d", p.Pid)
err := p.Kill()
// Log a call to terminate the process
func logTerminate(cmd *exec.Cmd, stdin io.WriteCloser) error {
var err error
p := cmd.Process
timer := time.AfterFunc(16 * time.Second, func() {
log.Printf("killing PID %d", p.Pid)
err := p.Kill()
if err != nil {
log.Fatal(err)
}
})
defer timer.Stop()
log.Printf("closing stdin of and sending TERM to PID %d", p.Pid)
// tell child process on a "best-effort" basis to clean up and close itself
stdin.Close()
// below returns an error (effectively a nop) on Windows, ignore it -
// hopefully child got the hint with stdin.Close().
p.Signal(syscall.SIGTERM)
_, err = p.Wait()
if err != nil {
log.Print(err)
}
log.Printf("cleanly closed PID %d", p.Pid)
return err
}
@@ -74,9 +95,13 @@ func logSignal(p *os.Process, sig os.Signal) error {
}
// Run browser helper and return its exec.Cmd and stdout pipe.
func runBrowserHelper(browserHelperPath string) (cmd *exec.Cmd, stdout io.Reader, err error) {
func runBrowserHelper(browserHelperPath string) (cmd *exec.Cmd, stdin io.WriteCloser, stdout io.Reader, err error) {
cmd = exec.Command(browserHelperPath)
cmd.Stderr = os.Stderr
stdin, err = cmd.StdinPipe()
if err != nil {
return
}
stdout, err = cmd.StdoutPipe()
if err != nil {
return
@@ -87,7 +112,7 @@ func runBrowserHelper(browserHelperPath string) (cmd *exec.Cmd, stdout io.Reader
return
}
log.Printf("browser-helper started with pid %d", cmd.Process.Pid)
return cmd, stdout, nil
return cmd, stdin, stdout, nil
}
// Look for the magic meek-http-helper address string in the Reader, and return
@@ -117,11 +142,15 @@ func grepHelperAddr(r io.Reader) (string, error) {
}
// Run meek-client and return its exec.Cmd.
func runMeekClient(helperAddr string, meekClientCommandLine []string) (cmd *exec.Cmd, err error) {
func runMeekClient(helperAddr string, meekClientCommandLine []string) (cmd *exec.Cmd, stdin io.WriteCloser, err error) {
meekClientPath := meekClientCommandLine[0]
args := meekClientCommandLine[1:]
args = append(args, []string{"--helper", helperAddr}...)
cmd = exec.Command(meekClientPath, args...)
stdin, err = cmd.StdinPipe()
if err != nil {
return
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
log.Printf("running meek-client command %q", cmd.Args)
@@ -130,7 +159,7 @@ func runMeekClient(helperAddr string, meekClientCommandLine []string) (cmd *exec
return
}
log.Printf("meek-client started with pid %d", cmd.Process.Pid)
return cmd, nil
return cmd, stdin, nil
}
func main() {
@@ -162,12 +191,12 @@ func main() {
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
// Start browser-helper.
browserHelperCmd, stdout, err := runBrowserHelper(browserHelperPath)
browserHelperCmd, stdin, stdout, err := runBrowserHelper(browserHelperPath)
if err != nil {
log.Print(err)
return
}
defer logKill(browserHelperCmd.Process)
defer logTerminate(browserHelperCmd, stdin)
// Find out the helper's listening address.
helperAddr, err := grepHelperAddr(stdout)
@@ -177,12 +206,12 @@ func main() {
}
// Start meek-client with the helper address.
meekClientCmd, err := runMeekClient(helperAddr, flag.Args())
meekClientCmd, meekClientStdin, err := runMeekClient(helperAddr, flag.Args())
if err != nil {
log.Print(err)
return
}
defer logKill(meekClientCmd.Process)
defer logTerminate(meekClientCmd, meekClientStdin)
if exitOnStdinEOF {
// On Windows, we don't get a SIGINT or SIGTERM, rather we are
@@ -199,7 +228,7 @@ func main() {
}
sig := <-sigChan
log.Printf("sig %s", sig)
log.Printf("received signal %s", sig)
err = logSignal(meekClientCmd.Process, sig)
if err != nil {
log.Print(err)
@@ -208,7 +237,7 @@ func main() {
// If SIGINT, wait for a second SIGINT.
if sig == syscall.SIGINT {
sig := <-sigChan
log.Printf("sig %s", sig)
log.Printf("received signal %s", sig)
err = logSignal(meekClientCmd.Process, sig)
if err != nil {
log.Print(err)

0 comments on commit 36bcdca

Please sign in to comment.