diff options
author | Markos Fountoulakis <44345837+mfundul@users.noreply.github.com> | 2019-12-15 20:56:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-15 20:56:56 +0200 |
commit | 0c06f38f6e9e687814e245b01f4b4f7af2314eda (patch) | |
tree | cc5bab3c1428b50c496ae8fc8363744df8f5386b /daemon | |
parent | fc0570fecaab8008673f6f90bc638f931f110a89 (diff) |
Fix valgrind errors (#7532)
* Add callbacks to pipe handle destructors
* Fix valgrind errors
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/commands.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/daemon/commands.c b/daemon/commands.c index fc68ed59a7..6847e9f0be 100644 --- a/daemon/commands.c +++ b/daemon/commands.c @@ -18,16 +18,19 @@ char cmd_prefix_by_status[] = { static int command_thread_error; static int command_thread_shutdown; static unsigned clients = 0; -static char command_string[MAX_COMMAND_LENGTH]; -static unsigned command_string_size; struct command_context { + /* embedded client pipe structure at address 0 */ + uv_pipe_t client; + uv_work_t work; - uv_stream_t *client; + uv_write_t write_req; cmd_t idx; char *args; char *message; cmd_status_t status; + char command_string[MAX_COMMAND_LENGTH]; + unsigned command_string_size; }; /* Forward declarations */ @@ -219,13 +222,18 @@ static void cmd_unlock_high_priority(unsigned index) (void)index; } +static void pipe_close_cb(uv_handle_t* handle) +{ + /* Also frees command context */ + freez(handle); +} + static void pipe_write_cb(uv_write_t* req, int status) { (void)status; uv_pipe_t *client = req->data; - uv_close((uv_handle_t *)client, NULL); - freez(client); + uv_close((uv_handle_t *)client, pipe_close_cb); --clients; info("Command Clients = %u\n", clients); } @@ -244,14 +252,14 @@ static inline void add_string_to_command_reply(char *reply_string, unsigned *rep *reply_string_size += len; } -static void send_command_reply(uv_stream_t *client, cmd_status_t status, char *message) +static void send_command_reply(struct command_context *cmd_ctx, cmd_status_t status, char *message) { int ret; char reply_string[MAX_COMMAND_LENGTH] = {'\0', }; char exit_status_string[MAX_EXIT_STATUS_LENGTH + 1] = {'\0', }; unsigned reply_string_size = 0; uv_buf_t write_buf; - uv_write_t write_req; + uv_stream_t *client = (uv_stream_t *)(uv_pipe_t *)cmd_ctx; snprintfz(exit_status_string, MAX_EXIT_STATUS_LENGTH, "%u", status); add_char_to_command_reply(reply_string, &reply_string_size, CMD_PREFIX_EXIT_CODE); @@ -263,10 +271,10 @@ static void send_command_reply(uv_stream_t *client, cmd_status_t status, char *m add_string_to_command_reply(reply_string, &reply_string_size, message); } - write_req.data = client; + cmd_ctx->write_req.data = client; write_buf.base = reply_string; write_buf.len = reply_string_size; - ret = uv_write(&write_req, (uv_stream_t *)client, &write_buf, 1, pipe_write_cb); + ret = uv_write(&cmd_ctx->write_req, (uv_stream_t *)client, &write_buf, 1, pipe_write_cb); if (ret) { error("uv_write(): %s", uv_strerror(ret)); } @@ -291,7 +299,7 @@ static void after_schedule_command(uv_work_t *req, int status) (void)status; - send_command_reply(cmd_ctx->client, cmd_ctx->status, cmd_ctx->message); + send_command_reply(cmd_ctx, cmd_ctx->status, cmd_ctx->message); if (cmd_ctx->message) freez(cmd_ctx->message); } @@ -303,22 +311,19 @@ static void schedule_command(uv_work_t *req) cmd_ctx->status = execute_command(cmd_ctx->idx, cmd_ctx->args, &cmd_ctx->message); } -static void parse_commands(uv_stream_t *client) +static void parse_commands(struct command_context *cmd_ctx) { char *message = NULL, *pos; cmd_t i; cmd_status_t status; - struct command_context *cmd_ctx; status = CMD_STATUS_FAILURE; /* Skip white-space characters */ - for (pos = command_string ; isspace(*pos) && ('\0' != *pos) ; ++pos) {;} + for (pos = cmd_ctx->command_string ; isspace(*pos) && ('\0' != *pos) ; ++pos) {;} for (i = 0 ; i < CMD_TOTAL_COMMANDS ; ++i) { if (!strncmp(pos, command_info_array[i].cmd_str, strlen(command_info_array[i].cmd_str))) { - cmd_ctx = mallocz(sizeof(*cmd_ctx)); cmd_ctx->work.data = cmd_ctx; - cmd_ctx->client = client; cmd_ctx->idx = i; cmd_ctx->args = pos + strlen(command_info_array[i].cmd_str); cmd_ctx->message = NULL; @@ -330,18 +335,20 @@ static void parse_commands(uv_stream_t *client) if (CMD_TOTAL_COMMANDS == i) { /* no command found */ message = strdupz("Illegal command. Please type \"help\" for instructions."); - send_command_reply(client, status, message); + send_command_reply(cmd_ctx, status, message); freez(message); } } static void pipe_read_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) { + struct command_context *cmd_ctx = (struct command_context *)client; + if (0 == nread) { info("%s: Zero bytes read by command pipe.", __func__); } else if (UV_EOF == nread) { info("EOF found in command pipe."); - parse_commands(client); + parse_commands(cmd_ctx); } else if (nread < 0) { error("%s: %s", __func__, uv_strerror(nread)); } @@ -351,17 +358,17 @@ static void pipe_read_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf } else if (nread) { size_t to_copy; - to_copy = MIN(nread, MAX_COMMAND_LENGTH - 1 - command_string_size); - strncpyz(command_string + command_string_size, buf->base, to_copy); - command_string_size += to_copy; + to_copy = MIN(nread, MAX_COMMAND_LENGTH - 1 - cmd_ctx->command_string_size); + memcpy(cmd_ctx->command_string + cmd_ctx->command_string_size, buf->base, to_copy); + cmd_ctx->command_string_size += to_copy; + cmd_ctx->command_string[cmd_ctx->command_string_size] = '\0'; } if (buf && buf->len) { freez(buf->base); } if (nread < 0 && UV_EOF != nread) { - uv_close((uv_handle_t *)client, NULL); - freez(client); + uv_close((uv_handle_t *)client, pipe_close_cb); --clients; info("Command Clients = %u\n", clients); } @@ -379,34 +386,35 @@ static void connection_cb(uv_stream_t *server, int status) { int ret; uv_pipe_t *client; + struct command_context *cmd_ctx; assert(status == 0); - client = mallocz(sizeof(*client)); + /* combined allocation of client pipe and command context */ + cmd_ctx = mallocz(sizeof(*cmd_ctx)); + client = (uv_pipe_t *)cmd_ctx; ret = uv_pipe_init(server->loop, client, 1); if (ret) { error("uv_pipe_init(): %s", uv_strerror(ret)); - freez(client); + freez(cmd_ctx); return; } ret = uv_accept(server, (uv_stream_t *)client); if (ret) { error("uv_accept(): %s", uv_strerror(ret)); - uv_close((uv_handle_t *)client, NULL); - freez(client); + uv_close((uv_handle_t *)client, pipe_close_cb); return; } ++clients; info("Command Clients = %u\n", clients); /* Start parsing a new command */ - command_string_size = 0; - command_string[0] = '\0'; + cmd_ctx->command_string_size = 0; + cmd_ctx->command_string[0] = '\0'; ret = uv_read_start((uv_stream_t*)client, alloc_cb, pipe_read_cb); if (ret) { error("uv_read_start(): %s", uv_strerror(ret)); - uv_close((uv_handle_t *)client, NULL); - freez(client); + uv_close((uv_handle_t *)client, pipe_close_cb); --clients; info("Command Clients = %u\n", clients); return; |