print error that caused an external command to exit (#1869)
This commit is contained in:
parent
06cc28b372
commit
128f2d3e20
|
@ -333,8 +333,8 @@ func (pa *path) run() {
|
|||
pa.conf.RunOnInit,
|
||||
pa.conf.RunOnInitRestart,
|
||||
pa.externalCmdEnv(),
|
||||
func(co int) {
|
||||
pa.Log(logger.Info, "runOnInit command exited with code %d", co)
|
||||
func(err error) {
|
||||
pa.Log(logger.Info, "runOnInit command exited: %v", err)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -588,8 +588,8 @@ func (pa *path) onDemandPublisherStart() {
|
|||
pa.conf.RunOnDemand,
|
||||
pa.conf.RunOnDemandRestart,
|
||||
pa.externalCmdEnv(),
|
||||
func(co int) {
|
||||
pa.Log(logger.Info, "runOnDemand command exited with code %d", co)
|
||||
func(err error) {
|
||||
pa.Log(logger.Info, "runOnDemand command exited: %v", err)
|
||||
})
|
||||
|
||||
pa.onDemandPublisherReadyTimer.Stop()
|
||||
|
@ -647,8 +647,8 @@ func (pa *path) sourceSetReady(medias media.Medias, allocateEncoder bool) error
|
|||
pa.conf.RunOnReady,
|
||||
pa.conf.RunOnReadyRestart,
|
||||
pa.externalCmdEnv(),
|
||||
func(co int) {
|
||||
pa.Log(logger.Info, "runOnReady command exited with code %d", co)
|
||||
func(err error) {
|
||||
pa.Log(logger.Info, "runOnReady command exited: %v", err)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -299,8 +299,8 @@ func (c *rtmpConn) run() {
|
|||
"RTSP_PATH": "",
|
||||
"RTSP_PORT": port,
|
||||
},
|
||||
func(co int) {
|
||||
c.Log(logger.Info, "runOnConnect command exited with code %d", co)
|
||||
func(err error) {
|
||||
c.Log(logger.Info, "runOnConnect command exited: %v", err)
|
||||
})
|
||||
|
||||
defer func() {
|
||||
|
@ -424,8 +424,8 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
|
|||
pathConf.RunOnRead,
|
||||
pathConf.RunOnReadRestart,
|
||||
res.path.externalCmdEnv(),
|
||||
func(co int) {
|
||||
c.Log(logger.Info, "runOnRead command exited with code %d", co)
|
||||
func(err error) {
|
||||
c.Log(logger.Info, "runOnRead command exited: %v", err)
|
||||
})
|
||||
defer func() {
|
||||
onReadCmd.Close()
|
||||
|
|
|
@ -80,8 +80,8 @@ func newRTSPConn(
|
|||
"RTSP_PATH": "",
|
||||
"RTSP_PORT": port,
|
||||
},
|
||||
func(co int) {
|
||||
c.Log(logger.Info, "runOnInit command exited with code %d", co)
|
||||
func(err error) {
|
||||
c.Log(logger.Info, "runOnInit command exited: %v", err)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -276,8 +276,8 @@ func (s *rtspSession) onPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Respo
|
|||
pathConf.RunOnRead,
|
||||
pathConf.RunOnReadRestart,
|
||||
s.path.externalCmdEnv(),
|
||||
func(co int) {
|
||||
s.Log(logger.Info, "runOnRead command exited with code %d", co)
|
||||
func(err error) {
|
||||
s.Log(logger.Info, "runOnRead command exited: %v", err)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package externalcmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
@ -10,6 +11,8 @@ const (
|
|||
restartPause = 5 * time.Second
|
||||
)
|
||||
|
||||
var errTerminated = errors.New("terminated")
|
||||
|
||||
// Environment is a Cmd environment.
|
||||
type Environment map[string]string
|
||||
|
||||
|
@ -19,7 +22,7 @@ type Cmd struct {
|
|||
cmdstr string
|
||||
restart bool
|
||||
env Environment
|
||||
onExit func(int)
|
||||
onExit func(error)
|
||||
|
||||
// in
|
||||
terminate chan struct{}
|
||||
|
@ -31,7 +34,7 @@ func NewCmd(
|
|||
cmdstr string,
|
||||
restart bool,
|
||||
env Environment,
|
||||
onExit func(int),
|
||||
onExit func(error),
|
||||
) *Cmd {
|
||||
// replace variables in both Linux and Windows, in order to allow using the
|
||||
// same commands on both of them.
|
||||
|
@ -64,30 +67,22 @@ func (e *Cmd) run() {
|
|||
defer e.pool.wg.Done()
|
||||
|
||||
for {
|
||||
ok := e.runInner()
|
||||
if !ok {
|
||||
break
|
||||
err := e.runOSSpecific()
|
||||
if err == errTerminated {
|
||||
return
|
||||
}
|
||||
|
||||
e.onExit(err)
|
||||
|
||||
if !e.restart {
|
||||
<-e.terminate
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(restartPause):
|
||||
case <-e.terminate:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Cmd) runInner() bool {
|
||||
c, ok := e.runOSSpecific()
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
e.onExit(c)
|
||||
|
||||
if !e.restart {
|
||||
<-e.terminate
|
||||
return false
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(restartPause):
|
||||
return true
|
||||
case <-e.terminate:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package externalcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
@ -11,10 +12,10 @@ import (
|
|||
"github.com/kballard/go-shellquote"
|
||||
)
|
||||
|
||||
func (e *Cmd) runOSSpecific() (int, bool) {
|
||||
func (e *Cmd) runOSSpecific() error {
|
||||
cmdParts, err := shellquote.Split(e.cmdstr)
|
||||
if err != nil {
|
||||
return 0, true
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command(cmdParts[0], cmdParts[1:]...)
|
||||
|
@ -29,7 +30,7 @@ func (e *Cmd) runOSSpecific() (int, bool) {
|
|||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return 0, true
|
||||
return err
|
||||
}
|
||||
|
||||
cmdDone := make(chan int)
|
||||
|
@ -51,9 +52,9 @@ func (e *Cmd) runOSSpecific() (int, bool) {
|
|||
case <-e.terminate:
|
||||
syscall.Kill(cmd.Process.Pid, syscall.SIGINT)
|
||||
<-cmdDone
|
||||
return 0, false
|
||||
return errTerminated
|
||||
|
||||
case c := <-cmdDone:
|
||||
return c, true
|
||||
return fmt.Errorf("command returned code %d", c)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package externalcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
"github.com/kballard/go-shellquote"
|
||||
)
|
||||
|
||||
func (e *Cmd) runOSSpecific() (int, bool) {
|
||||
func (e *Cmd) runOSSpecific() error {
|
||||
var cmd *exec.Cmd
|
||||
|
||||
// from Golang documentation:
|
||||
|
@ -32,7 +33,7 @@ func (e *Cmd) runOSSpecific() (int, bool) {
|
|||
} else {
|
||||
cmdParts, err := shellquote.Split(e.cmdstr)
|
||||
if err != nil {
|
||||
return 0, true
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command(cmdParts[0], cmdParts[1:]...)
|
||||
|
@ -48,7 +49,7 @@ func (e *Cmd) runOSSpecific() (int, bool) {
|
|||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return 0, true
|
||||
return err
|
||||
}
|
||||
|
||||
cmdDone := make(chan int)
|
||||
|
@ -72,9 +73,9 @@ func (e *Cmd) runOSSpecific() (int, bool) {
|
|||
// Kill() is the only supported way.
|
||||
cmd.Process.Kill()
|
||||
<-cmdDone
|
||||
return 0, false
|
||||
return errTerminated
|
||||
|
||||
case c := <-cmdDone:
|
||||
return c, true
|
||||
return fmt.Errorf("command returned code %d", c)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue