diff options
author | Ahmad Sherif <me@ahmadsherif.com> | 2016-12-07 15:11:37 +0300 |
---|---|---|
committer | Ahmad Sherif <me@ahmadsherif.com> | 2016-12-07 15:11:37 +0300 |
commit | 0fa244f63e245bad7b9a91bfeb524f7ece7d5dd7 (patch) | |
tree | e5d181330b039fc1ce9cec991f97f2e36069543c | |
parent | 833612ed9466df4d6b3d55373cb1e8369eda460f (diff) |
Return exit status along with the command response
-rw-r--r-- | server/command_executor.go | 33 | ||||
-rw-r--r-- | server/command_executor_test.go | 12 |
2 files changed, 34 insertions, 11 deletions
diff --git a/server/command_executor.go b/server/command_executor.go index 0c9108a3a..e2a41b72a 100644 --- a/server/command_executor.go +++ b/server/command_executor.go @@ -13,8 +13,9 @@ type cmdRequest struct { } type cmdResponse struct { - Status string `json:"status"` - Message string `json:"message"` + Status string `json:"status"` + Message string `json:"message"` + ExitStatus int `json:"exit_status"` } func CommandExecutorCallback(input []byte) []byte { @@ -22,13 +23,16 @@ func CommandExecutorCallback(input []byte) []byte { err := json.Unmarshal(input, &req) if err != nil { - return errorResponse("Error parsing JSON request") + return errorResponse("Error parsing JSON request", 255) } output, err := runCommand(req.Cmd[0], req.Cmd[1:]...) if err != nil { - return errorResponse(string(output.Bytes())) + return errorResponse( + string(output.Bytes()), + extractExitStatusFromError(err.(*exec.ExitError)), + ) } return successResponse(string(output.Bytes())) @@ -62,16 +66,27 @@ func makeCommand(name string, args ...string) *exec.Cmd { return cmd } -func errorResponse(message string) []byte { - return makeResponse("error", message) +func extractExitStatusFromError(err *exec.ExitError) int { + processState := err.ProcessState + status := processState.Sys().(syscall.WaitStatus) + + if status.Exited() { + return status.ExitStatus() + } + + return 255 +} + +func errorResponse(message string, exit_status int) []byte { + return makeResponse("error", message, exit_status) } func successResponse(message string) []byte { - return makeResponse("success", message) + return makeResponse("success", message, 0) } -func makeResponse(status string, message string) []byte { - res := cmdResponse{status, message} +func makeResponse(status string, message string, exit_status int) []byte { + res := cmdResponse{status, message, exit_status} tempBuf, err := json.Marshal(res) if err != nil { diff --git a/server/command_executor_test.go b/server/command_executor_test.go index eeb37ce31..2dadfd673 100644 --- a/server/command_executor_test.go +++ b/server/command_executor_test.go @@ -3,8 +3,8 @@ package server import ( "bufio" "bytes" - "os" "net" + "os" "testing" "time" ) @@ -27,6 +27,10 @@ func TestRunningCommandSuccessfully(t *testing.T) { if !bytes.Contains(res, []byte(`{"status":"success","message":"total`)) { t.Fatalf("Expected a successful response, got this response: %s", res) } + + if !bytes.Contains(res, []byte(`"exit_status":0`)) { + t.Fatalf("Expected response to contain exit status of 0, found none in: %s", res) + } } func TestRunningCommandUnsuccessfully(t *testing.T) { @@ -35,12 +39,16 @@ func TestRunningCommandUnsuccessfully(t *testing.T) { if !bytes.Contains(res, []byte(`{"status":"error","message":"ls: cannot access`)) { t.Fatalf("Expected a failure response, got this response: %s", res) } + + if !bytes.Contains(res, []byte(`"exit_status":2`)) { + t.Fatalf("Expected response to contain exit status of 2, found none in: %s", res) + } } func TestMalformedCommand(t *testing.T) { res := responseForCommand(`{"cmd":["ls", "/file-that-does-not-exist"}`, t) - if !bytes.Equal(res, []byte(`{"status":"error","message":"Error parsing JSON request"}`)) { + if !bytes.Equal(res, []byte(`{"status":"error","message":"Error parsing JSON request","exit_status":255}`)) { t.Fatalf("Expected a failure response, got this response: %s", res) } } |