print a message when a custom command exits suddently
This commit is contained in:
parent
a5723c4808
commit
84735426eb
|
@ -343,7 +343,10 @@ func (pa *path) run() {
|
|||
onInitCmd = externalcmd.New(
|
||||
pa.conf.RunOnInit,
|
||||
pa.conf.RunOnInitRestart,
|
||||
pa.externalCmdEnv())
|
||||
pa.externalCmdEnv(),
|
||||
func(co int) {
|
||||
pa.log(logger.Info, "runOnInit command exited with code %d", co)
|
||||
})
|
||||
}
|
||||
|
||||
err := func() error {
|
||||
|
@ -543,7 +546,10 @@ func (pa *path) onDemandStartSource() {
|
|||
pa.onDemandCmd = externalcmd.New(
|
||||
pa.conf.RunOnDemand,
|
||||
pa.conf.RunOnDemandRestart,
|
||||
pa.externalCmdEnv())
|
||||
pa.externalCmdEnv(),
|
||||
func(co int) {
|
||||
pa.log(logger.Info, "runOnDemand command exited with code %d", co)
|
||||
})
|
||||
pa.onDemandReadyTimer = time.NewTimer(time.Duration(pa.conf.RunOnDemandStartTimeout))
|
||||
}
|
||||
|
||||
|
@ -796,7 +802,10 @@ func (pa *path) handlePublisherRecord(req pathPublisherRecordReq) {
|
|||
pa.onPublishCmd = externalcmd.New(
|
||||
pa.conf.RunOnPublish,
|
||||
pa.conf.RunOnPublishRestart,
|
||||
pa.externalCmdEnv())
|
||||
pa.externalCmdEnv(),
|
||||
func(co int) {
|
||||
pa.log(logger.Info, "runOnPublish command exited with code %d", co)
|
||||
})
|
||||
}
|
||||
|
||||
req.Res <- pathPublisherRecordRes{Stream: pa.stream}
|
||||
|
|
|
@ -154,6 +154,9 @@ func (c *rtmpConn) run() {
|
|||
externalcmd.Environment{
|
||||
"RTSP_PATH": "",
|
||||
"RTSP_PORT": port,
|
||||
},
|
||||
func(co int) {
|
||||
c.log(logger.Info, "runOnConnect command exited with code %d", co)
|
||||
})
|
||||
|
||||
defer func() {
|
||||
|
@ -289,7 +292,10 @@ func (c *rtmpConn) runRead(ctx context.Context) error {
|
|||
onReadCmd := externalcmd.New(
|
||||
c.path.Conf().RunOnRead,
|
||||
c.path.Conf().RunOnReadRestart,
|
||||
c.path.externalCmdEnv())
|
||||
c.path.externalCmdEnv(),
|
||||
func(co int) {
|
||||
c.log(logger.Info, "runOnRead command exited with code %d", co)
|
||||
})
|
||||
defer func() {
|
||||
onReadCmd.Close()
|
||||
c.log(logger.Info, "runOnRead command stopped")
|
||||
|
|
|
@ -71,6 +71,9 @@ func newRTSPConn(
|
|||
externalcmd.Environment{
|
||||
"RTSP_PATH": "",
|
||||
"RTSP_PORT": port,
|
||||
},
|
||||
func(co int) {
|
||||
c.log(logger.Info, "runOnInit command exited with code %d", co)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -279,7 +279,10 @@ func (s *rtspSession) onPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Respo
|
|||
s.onReadCmd = externalcmd.New(
|
||||
s.path.Conf().RunOnRead,
|
||||
s.path.Conf().RunOnReadRestart,
|
||||
s.path.externalCmdEnv())
|
||||
s.path.externalCmdEnv(),
|
||||
func(co int) {
|
||||
s.log(logger.Info, "runOnRead command exited with code %d", co)
|
||||
})
|
||||
}
|
||||
|
||||
s.stateMutex.Lock()
|
||||
|
|
|
@ -16,6 +16,7 @@ type Cmd struct {
|
|||
cmdstr string
|
||||
restart bool
|
||||
env Environment
|
||||
onExit func(int)
|
||||
|
||||
// in
|
||||
terminate chan struct{}
|
||||
|
@ -25,11 +26,17 @@ type Cmd struct {
|
|||
}
|
||||
|
||||
// New allocates an Cmd.
|
||||
func New(cmdstr string, restart bool, env Environment) *Cmd {
|
||||
func New(
|
||||
cmdstr string,
|
||||
restart bool,
|
||||
env Environment,
|
||||
onExit func(int),
|
||||
) *Cmd {
|
||||
e := &Cmd{
|
||||
cmdstr: cmdstr,
|
||||
restart: restart,
|
||||
env: env,
|
||||
onExit: onExit,
|
||||
terminate: make(chan struct{}),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
@ -50,11 +57,13 @@ func (e *Cmd) run() {
|
|||
|
||||
for {
|
||||
ok := func() bool {
|
||||
ok := e.runInner()
|
||||
c, ok := e.runInner()
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
e.onExit(c)
|
||||
|
||||
if !e.restart {
|
||||
<-e.terminate
|
||||
return false
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"syscall"
|
||||
)
|
||||
|
||||
func (e *Cmd) runInner() bool {
|
||||
func (e *Cmd) runInner() (int, bool) {
|
||||
cmd := exec.Command("/bin/sh", "-c", "exec "+e.cmdstr)
|
||||
|
||||
cmd.Env = append([]string(nil), os.Environ()...)
|
||||
|
@ -22,22 +22,31 @@ func (e *Cmd) runInner() bool {
|
|||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return true
|
||||
return 0, true
|
||||
}
|
||||
|
||||
cmdDone := make(chan struct{})
|
||||
cmdDone := make(chan int)
|
||||
go func() {
|
||||
defer close(cmdDone)
|
||||
cmd.Wait()
|
||||
cmdDone <- func() int {
|
||||
err := cmd.Wait()
|
||||
if err == nil {
|
||||
return 0
|
||||
}
|
||||
ee, ok := err.(*exec.ExitError)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return ee.ExitCode()
|
||||
}()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-e.terminate:
|
||||
syscall.Kill(cmd.Process.Pid, syscall.SIGINT)
|
||||
<-cmdDone
|
||||
return false
|
||||
return 0, false
|
||||
|
||||
case <-cmdDone:
|
||||
return true
|
||||
case c := <-cmdDone:
|
||||
return c, true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/kballard/go-shellquote"
|
||||
)
|
||||
|
||||
func (e *Cmd) runInner() bool {
|
||||
func (e *Cmd) runInner() (int, bool) {
|
||||
// On Windows, the shell is not used and command is started directly.
|
||||
// Variables are replaced manually in order to guarantee compatibility
|
||||
// with Linux commands.
|
||||
|
@ -21,7 +21,7 @@ func (e *Cmd) runInner() bool {
|
|||
}
|
||||
parts, err := shellquote.Split(tmp)
|
||||
if err != nil {
|
||||
return true
|
||||
return 0, true
|
||||
}
|
||||
|
||||
cmd := exec.Command(parts[0], parts[1:]...)
|
||||
|
@ -36,13 +36,22 @@ func (e *Cmd) runInner() bool {
|
|||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return true
|
||||
return 0, true
|
||||
}
|
||||
|
||||
cmdDone := make(chan struct{})
|
||||
cmdDone := make(chan int)
|
||||
go func() {
|
||||
defer close(cmdDone)
|
||||
cmd.Wait()
|
||||
cmdDone <- func() int {
|
||||
err := cmd.Wait()
|
||||
if err == nil {
|
||||
return 0
|
||||
}
|
||||
ee, ok := err.(*exec.ExitError)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return ee.ExitCode()
|
||||
}()
|
||||
}()
|
||||
|
||||
select {
|
||||
|
@ -51,9 +60,9 @@ func (e *Cmd) runInner() bool {
|
|||
// Kill() is the only supported way.
|
||||
cmd.Process.Kill()
|
||||
<-cmdDone
|
||||
return false
|
||||
return 0, false
|
||||
|
||||
case <-cmdDone:
|
||||
return true
|
||||
case c := <-cmdDone:
|
||||
return c, true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue