From 0d585e5959035408c1a4f1eec89e83a9ef43535e Mon Sep 17 00:00:00 2001 From: sawka Date: Wed, 6 Jul 2022 00:21:44 -0700 Subject: [PATCH] clean up --single detached mode --- pkg/packet/packet.go | 6 +++--- pkg/server/server.go | 2 +- pkg/shexec/shexec.go | 37 ++++++++++++++++++------------------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/pkg/packet/packet.go b/pkg/packet/packet.go index b6142406d..0c1527f2e 100644 --- a/pkg/packet/packet.go +++ b/pkg/packet/packet.go @@ -316,8 +316,8 @@ type ResponsePacketType struct { Type string `json:"type"` RespId string `json:"respid"` Success bool `json:"success"` - Error string `json:"error"` - Data interface{} `json:"data"` + Error string `json:"error,omitempty"` + Data interface{} `json:"data,omitempty"` } func (*ResponsePacketType) GetType() string { @@ -476,7 +476,7 @@ type RunDataType struct { type RunPacketType struct { Type string `json:"type"` - ReqId string `json:"packetid"` + ReqId string `json:"reqid"` CK base.CommandKey `json:"ck"` Command string `json:"command"` Cwd string `json:"cwd,omitempty"` diff --git a/pkg/server/server.go b/pkg/server/server.go index ab66c35e5..668c0172b 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -114,7 +114,7 @@ func (m *MServer) RemoveFdContext(ck base.CommandKey) { func (m *MServer) runCommand(runPacket *packet.RunPacketType) { if err := runPacket.CK.Validate("packet"); err != nil { - m.Sender.SendResponse(runPacket.ReqId, fmt.Errorf("server run packets require valid ck: %s", err)) + m.Sender.SendErrorResponse(runPacket.ReqId, fmt.Errorf("server run packets require valid ck: %s", err)) return } fdContext := m.MakeServerFdContext(runPacket.CK) diff --git a/pkg/shexec/shexec.go b/pkg/shexec/shexec.go index 8eb2c46f5..44ed76e1b 100644 --- a/pkg/shexec/shexec.go +++ b/pkg/shexec/shexec.go @@ -850,33 +850,30 @@ func SetupSignalsForDetach() { func (cmd *ShExecType) DetachedWait(startPacket *packet.CmdStartPacketType) { // after Start(), any output/errors must go to DetachedOutput - // close stdin/stdout/stderr, but wait for cmdstart packet to get sent - nullFd, err := os.OpenFile("/dev/null", os.O_RDWR, 0) - if err != nil { - cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot open /dev/null: %w", err)) - } - if nullFd != nil { - err := unix.Dup2(int(nullFd.Fd()), int(os.Stdin.Fd())) - if err != nil { - cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot dup2 stdin to /dev/null: %w", err)) - } - err = unix.Dup2(int(nullFd.Fd()), int(os.Stdout.Fd())) - if err != nil { - cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot dup2 stdin to /dev/null: %w", err)) - } - err = unix.Dup2(int(nullFd.Fd()), int(os.Stderr.Fd())) - if err != nil { - cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot dup2 stdin to /dev/null: %w", err)) - } - } + // close stdin, redirect stdout/stderr to /dev/null, but wait for cmdstart packet to get sent cmd.DetachedOutput.SendPacket(startPacket) + err := os.Stdin.Close() + if err != nil { + cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot close stdin: %w", err)) + } + err = unix.Dup2(int(cmd.RunnerOutFd.Fd()), int(os.Stdout.Fd())) + if err != nil { + cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot dup2 stdin to runout: %w", err)) + } + err = unix.Dup2(int(cmd.RunnerOutFd.Fd()), int(os.Stderr.Fd())) + if err != nil { + cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot dup2 stdin to runout: %w", err)) + } ptyOutFd, err := os.OpenFile(cmd.FileNames.PtyOutFile, os.O_TRUNC|os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600) if err != nil { cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("cannot open ptyout file '%s': %w", cmd.FileNames.PtyOutFile, err)) // don't return (command is already running) } + ptyCopyDone := make(chan bool) go func() { // copy pty output to .ptyout file + defer close(ptyCopyDone) + defer ptyOutFd.Close() _, copyErr := io.Copy(ptyOutFd, cmd.CmdPty) if copyErr != nil { cmd.DetachedOutput.SendCmdError(cmd.CK, fmt.Errorf("copying pty output to ptyout file: %w", copyErr)) @@ -891,6 +888,8 @@ func (cmd *ShExecType) DetachedWait(startPacket *packet.CmdStartPacketType) { }() donePacket := cmd.WaitForCommand() cmd.DetachedOutput.SendPacket(donePacket) + <-ptyCopyDone + cmd.Close() return }