summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
authorMarkos Fountoulakis <44345837+mfundul@users.noreply.github.com>2019-12-15 20:56:56 +0200
committerGitHub <noreply@github.com>2019-12-15 20:56:56 +0200
commit0c06f38f6e9e687814e245b01f4b4f7af2314eda (patch)
treecc5bab3c1428b50c496ae8fc8363744df8f5386b /daemon
parentfc0570fecaab8008673f6f90bc638f931f110a89 (diff)
Fix valgrind errors (#7532)
* Add callbacks to pipe handle destructors * Fix valgrind errors
Diffstat (limited to 'daemon')
-rw-r--r--daemon/commands.c68
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;