Browse Source

print error that caused an external command to exit (#1869)

pull/1871/head
Alessandro Ros 3 years ago committed by GitHub
parent
commit
128f2d3e20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      internal/core/path.go
  2. 8
      internal/core/rtmp_conn.go
  3. 4
      internal/core/rtsp_conn.go
  4. 4
      internal/core/rtsp_session.go
  5. 41
      internal/externalcmd/cmd.go
  6. 11
      internal/externalcmd/cmd_unix.go
  7. 11
      internal/externalcmd/cmd_win.go

12
internal/core/path.go

@ -333,8 +333,8 @@ func (pa *path) run() {
pa.conf.RunOnInit, pa.conf.RunOnInit,
pa.conf.RunOnInitRestart, pa.conf.RunOnInitRestart,
pa.externalCmdEnv(), pa.externalCmdEnv(),
func(co int) { func(err error) {
pa.Log(logger.Info, "runOnInit command exited with code %d", co) pa.Log(logger.Info, "runOnInit command exited: %v", err)
}) })
} }
@ -588,8 +588,8 @@ func (pa *path) onDemandPublisherStart() {
pa.conf.RunOnDemand, pa.conf.RunOnDemand,
pa.conf.RunOnDemandRestart, pa.conf.RunOnDemandRestart,
pa.externalCmdEnv(), pa.externalCmdEnv(),
func(co int) { func(err error) {
pa.Log(logger.Info, "runOnDemand command exited with code %d", co) pa.Log(logger.Info, "runOnDemand command exited: %v", err)
}) })
pa.onDemandPublisherReadyTimer.Stop() pa.onDemandPublisherReadyTimer.Stop()
@ -647,8 +647,8 @@ func (pa *path) sourceSetReady(medias media.Medias, allocateEncoder bool) error
pa.conf.RunOnReady, pa.conf.RunOnReady,
pa.conf.RunOnReadyRestart, pa.conf.RunOnReadyRestart,
pa.externalCmdEnv(), pa.externalCmdEnv(),
func(co int) { func(err error) {
pa.Log(logger.Info, "runOnReady command exited with code %d", co) pa.Log(logger.Info, "runOnReady command exited: %v", err)
}) })
} }

8
internal/core/rtmp_conn.go

@ -299,8 +299,8 @@ func (c *rtmpConn) run() {
"RTSP_PATH": "", "RTSP_PATH": "",
"RTSP_PORT": port, "RTSP_PORT": port,
}, },
func(co int) { func(err error) {
c.Log(logger.Info, "runOnConnect command exited with code %d", co) c.Log(logger.Info, "runOnConnect command exited: %v", err)
}) })
defer func() { defer func() {
@ -424,8 +424,8 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
pathConf.RunOnRead, pathConf.RunOnRead,
pathConf.RunOnReadRestart, pathConf.RunOnReadRestart,
res.path.externalCmdEnv(), res.path.externalCmdEnv(),
func(co int) { func(err error) {
c.Log(logger.Info, "runOnRead command exited with code %d", co) c.Log(logger.Info, "runOnRead command exited: %v", err)
}) })
defer func() { defer func() {
onReadCmd.Close() onReadCmd.Close()

4
internal/core/rtsp_conn.go

@ -80,8 +80,8 @@ func newRTSPConn(
"RTSP_PATH": "", "RTSP_PATH": "",
"RTSP_PORT": port, "RTSP_PORT": port,
}, },
func(co int) { func(err error) {
c.Log(logger.Info, "runOnInit command exited with code %d", co) c.Log(logger.Info, "runOnInit command exited: %v", err)
}) })
} }

4
internal/core/rtsp_session.go

@ -276,8 +276,8 @@ func (s *rtspSession) onPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Respo
pathConf.RunOnRead, pathConf.RunOnRead,
pathConf.RunOnReadRestart, pathConf.RunOnReadRestart,
s.path.externalCmdEnv(), s.path.externalCmdEnv(),
func(co int) { func(err error) {
s.Log(logger.Info, "runOnRead command exited with code %d", co) s.Log(logger.Info, "runOnRead command exited: %v", err)
}) })
} }

41
internal/externalcmd/cmd.go

@ -2,6 +2,7 @@
package externalcmd package externalcmd
import ( import (
"errors"
"strings" "strings"
"time" "time"
) )
@ -10,6 +11,8 @@ const (
restartPause = 5 * time.Second restartPause = 5 * time.Second
) )
var errTerminated = errors.New("terminated")
// Environment is a Cmd environment. // Environment is a Cmd environment.
type Environment map[string]string type Environment map[string]string
@ -19,7 +22,7 @@ type Cmd struct {
cmdstr string cmdstr string
restart bool restart bool
env Environment env Environment
onExit func(int) onExit func(error)
// in // in
terminate chan struct{} terminate chan struct{}
@ -31,7 +34,7 @@ func NewCmd(
cmdstr string, cmdstr string,
restart bool, restart bool,
env Environment, env Environment,
onExit func(int), onExit func(error),
) *Cmd { ) *Cmd {
// replace variables in both Linux and Windows, in order to allow using the // replace variables in both Linux and Windows, in order to allow using the
// same commands on both of them. // same commands on both of them.
@ -64,30 +67,22 @@ func (e *Cmd) run() {
defer e.pool.wg.Done() defer e.pool.wg.Done()
for { for {
ok := e.runInner() err := e.runOSSpecific()
if !ok { if err == errTerminated {
break return
} }
}
}
func (e *Cmd) runInner() bool {
c, ok := e.runOSSpecific()
if !ok {
return false
}
e.onExit(c) e.onExit(err)
if !e.restart { if !e.restart {
<-e.terminate <-e.terminate
return false return
} }
select { select {
case <-time.After(restartPause): case <-time.After(restartPause):
return true case <-e.terminate:
case <-e.terminate: return
return false }
} }
} }

11
internal/externalcmd/cmd_unix.go

@ -4,6 +4,7 @@
package externalcmd package externalcmd
import ( import (
"fmt"
"os" "os"
"os/exec" "os/exec"
"syscall" "syscall"
@ -11,10 +12,10 @@ import (
"github.com/kballard/go-shellquote" "github.com/kballard/go-shellquote"
) )
func (e *Cmd) runOSSpecific() (int, bool) { func (e *Cmd) runOSSpecific() error {
cmdParts, err := shellquote.Split(e.cmdstr) cmdParts, err := shellquote.Split(e.cmdstr)
if err != nil { if err != nil {
return 0, true return err
} }
cmd := exec.Command(cmdParts[0], cmdParts[1:]...) cmd := exec.Command(cmdParts[0], cmdParts[1:]...)
@ -29,7 +30,7 @@ func (e *Cmd) runOSSpecific() (int, bool) {
err = cmd.Start() err = cmd.Start()
if err != nil { if err != nil {
return 0, true return err
} }
cmdDone := make(chan int) cmdDone := make(chan int)
@ -51,9 +52,9 @@ func (e *Cmd) runOSSpecific() (int, bool) {
case <-e.terminate: case <-e.terminate:
syscall.Kill(cmd.Process.Pid, syscall.SIGINT) syscall.Kill(cmd.Process.Pid, syscall.SIGINT)
<-cmdDone <-cmdDone
return 0, false return errTerminated
case c := <-cmdDone: case c := <-cmdDone:
return c, true return fmt.Errorf("command returned code %d", c)
} }
} }

11
internal/externalcmd/cmd_win.go

@ -4,6 +4,7 @@
package externalcmd package externalcmd
import ( import (
"fmt"
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
@ -12,7 +13,7 @@ import (
"github.com/kballard/go-shellquote" "github.com/kballard/go-shellquote"
) )
func (e *Cmd) runOSSpecific() (int, bool) { func (e *Cmd) runOSSpecific() error {
var cmd *exec.Cmd var cmd *exec.Cmd
// from Golang documentation: // from Golang documentation:
@ -32,7 +33,7 @@ func (e *Cmd) runOSSpecific() (int, bool) {
} else { } else {
cmdParts, err := shellquote.Split(e.cmdstr) cmdParts, err := shellquote.Split(e.cmdstr)
if err != nil { if err != nil {
return 0, true return err
} }
cmd = exec.Command(cmdParts[0], cmdParts[1:]...) cmd = exec.Command(cmdParts[0], cmdParts[1:]...)
@ -48,7 +49,7 @@ func (e *Cmd) runOSSpecific() (int, bool) {
err := cmd.Start() err := cmd.Start()
if err != nil { if err != nil {
return 0, true return err
} }
cmdDone := make(chan int) cmdDone := make(chan int)
@ -72,9 +73,9 @@ func (e *Cmd) runOSSpecific() (int, bool) {
// Kill() is the only supported way. // Kill() is the only supported way.
cmd.Process.Kill() cmd.Process.Kill()
<-cmdDone <-cmdDone
return 0, false return errTerminated
case c := <-cmdDone: case c := <-cmdDone:
return c, true return fmt.Errorf("command returned code %d", c)
} }
} }

Loading…
Cancel
Save