aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/msg.c
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2023-05-13 08:59:43 +0200
committerEgor Tensin <Egor.Tensin@gmail.com>2023-05-13 11:37:46 +0200
commitf471fbdf27462b82febe4e8db8358ab3380d2a28 (patch)
tree6c41abf4e32214cd8bdb0f8a377f93b3c7c0d830 /src/msg.c
parentci_queue: fix a broken getter (diff)
downloadcimple-f471fbdf27462b82febe4e8db8358ab3380d2a28.tar.gz
cimple-f471fbdf27462b82febe4e8db8358ab3380d2a28.zip
add command module to handle request-response communications
Diffstat (limited to '')
-rw-r--r--src/msg.c143
1 files changed, 100 insertions, 43 deletions
diff --git a/src/msg.c b/src/msg.c
index 0c8dfc7..18e4c25 100644
--- a/src/msg.c
+++ b/src/msg.c
@@ -13,13 +13,28 @@
#include <stdlib.h>
#include <string.h>
-int msg_success(struct msg *msg)
+struct msg {
+ size_t argc;
+ const char **argv;
+};
+
+size_t msg_get_length(const struct msg *msg)
+{
+ return msg->argc;
+}
+
+const char **msg_get_words(const struct msg *msg)
+{
+ return msg->argv;
+}
+
+int msg_success(struct msg **msg)
{
const char *argv[] = {"success", NULL};
return msg_from_argv(msg, argv);
}
-int msg_error(struct msg *msg)
+int msg_error(struct msg **msg)
{
const char *argv[] = {"error", NULL};
return msg_from_argv(msg, argv);
@@ -37,82 +52,107 @@ int msg_is_error(const struct msg *msg)
static int msg_copy_argv(struct msg *msg, const char **argv)
{
- msg->argv = calloc(msg->argc, sizeof(const char *));
+ size_t copied = 0;
+ msg->argv = calloc(msg->argc + 1, sizeof(const char *));
if (!msg->argv) {
log_errno("calloc");
return -1;
}
- for (int i = 0; i < msg->argc; ++i) {
- msg->argv[i] = strdup(argv[i]);
- if (!msg->argv[i]) {
+ for (copied = 0; copied < msg->argc; ++copied) {
+ msg->argv[copied] = strdup(argv[copied]);
+ if (!msg->argv[copied]) {
log_errno("strdup");
- goto free;
+ goto free_copied;
}
}
return 0;
-free:
- msg_free(msg);
+free_copied:
+ for (size_t i = 0; i < copied; ++i) {
+ free((char *)msg->argv[i]);
+ }
+
+ free(msg->argv);
return -1;
}
-struct msg *msg_copy(const struct msg *src)
+int msg_copy(struct msg **_dest, const struct msg *src)
{
- struct msg *dest;
+ struct msg *dest = NULL;
int ret = 0;
- dest = malloc(sizeof(*dest));
- if (!dest) {
- log_errno("calloc");
- return NULL;
+ *_dest = malloc(sizeof(struct msg));
+ if (!_dest) {
+ log_errno("malloc");
+ return -1;
}
+ dest = *_dest;
+
dest->argc = src->argc;
ret = msg_copy_argv(dest, (const char **)src->argv);
if (ret < 0)
goto free;
- return dest;
+ return 0;
free:
free(dest);
- return NULL;
+ return -1;
}
-void msg_free(const struct msg *msg)
+void msg_free(struct msg *msg)
{
- for (int i = 0; i < msg->argc; ++i)
+ for (size_t i = 0; i < msg->argc; ++i)
free((char *)msg->argv[i]);
free(msg->argv);
+ free(msg);
}
-int msg_from_argv(struct msg *msg, const char **argv)
+int msg_from_argv(struct msg **_msg, const char **argv)
{
- int argc = 0;
+ struct msg *msg = NULL;
+ int ret = 0;
+
+ *_msg = malloc(sizeof(struct msg));
+ if (!*_msg) {
+ log_errno("malloc");
+ return -1;
+ }
+ msg = *_msg;
+ msg->argc = 0;
for (const char **s = argv; *s; ++s)
- ++argc;
+ ++msg->argc;
+
+ ret = msg_copy_argv(msg, argv);
+ if (ret < 0)
+ goto free;
+
+ return 0;
+
+free:
+ free(msg);
- msg->argc = argc;
- return msg_copy_argv(msg, argv);
+ return -1;
}
static uint32_t calc_buf_size(const struct msg *msg)
{
uint32_t len = 0;
- for (int i = 0; i < msg->argc; ++i)
+ for (size_t i = 0; i < msg->argc; ++i)
len += strlen(msg->argv[i]) + 1;
return len;
}
-static int calc_argv_len(const void *buf, size_t len)
+static size_t calc_argv_len(const void *buf, size_t len)
{
- int argc = 0;
+ size_t argc = 0;
for (const char *it = buf; it < (const char *)buf + len; it += strlen(it) + 1)
++argc;
return argc;
@@ -120,7 +160,7 @@ static int calc_argv_len(const void *buf, size_t len)
static void argv_pack(char *dest, const struct msg *msg)
{
- for (int i = 0; i < msg->argc; ++i) {
+ for (size_t i = 0; i < msg->argc; ++i) {
strcpy(dest, msg->argv[i]);
dest += strlen(msg->argv[i]) + 1;
}
@@ -128,28 +168,31 @@ static void argv_pack(char *dest, const struct msg *msg)
static int argv_unpack(struct msg *msg, const char *src)
{
- msg->argv = calloc(msg->argc, sizeof(char *));
+ size_t copied = 0;
+
+ msg->argv = calloc(msg->argc + 1, sizeof(const char *));
if (!msg->argv) {
log_errno("calloc");
return -1;
}
- for (int i = 0; i < msg->argc; ++i) {
- size_t len = strlen(src);
-
- msg->argv[i] = malloc(len + 1);
- if (!msg->argv[i]) {
- log_errno("malloc");
+ for (copied = 0; copied < msg->argc; ++copied) {
+ msg->argv[copied] = strdup(src);
+ if (!msg->argv[copied]) {
+ log_errno("strdup");
goto free;
}
- strcpy(msg->argv[i], src);
- src += len + 1;
+ src += strlen(msg->argv[copied]) + 1;
}
return 0;
free:
+ for (size_t i = 0; i < copied; ++i) {
+ free((char *)msg->argv[i]);
+ }
+
msg_free(msg);
return -1;
@@ -185,7 +228,7 @@ free_data:
return ret;
}
-int msg_send_and_wait(int fd, const struct msg *request, struct msg *response)
+int msg_send_and_wait(int fd, const struct msg *request, struct msg **response)
{
int ret = 0;
@@ -200,20 +243,34 @@ int msg_send_and_wait(int fd, const struct msg *request, struct msg *response)
return ret;
}
-int msg_recv(int fd, struct msg *msg)
+int msg_recv(int fd, struct msg **_msg)
{
- struct buf *buf;
+ struct msg *msg = NULL;
+ struct buf *buf = NULL;
int ret = 0;
ret = net_recv_buf(fd, &buf);
if (ret < 0)
return ret;
+ *_msg = malloc(sizeof(struct msg));
+ if (!*_msg) {
+ log_errno("malloc");
+ ret = -1;
+ goto destroy_buf;
+ }
+ msg = *_msg;
+
msg->argc = calc_argv_len(buf_get_data(buf), buf_get_size(buf));
ret = argv_unpack(msg, buf_get_data(buf));
if (ret < 0)
- goto destroy_buf;
+ goto free_msg;
+
+ goto destroy_buf;
+
+free_msg:
+ free(msg);
destroy_buf:
buf_destroy(buf);
@@ -223,7 +280,7 @@ destroy_buf:
void msg_dump(const struct msg *msg)
{
- log("Message[%d]:\n", msg->argc);
- for (int i = 0; i < msg->argc; ++i)
+ log("Message[%zu]:\n", msg->argc);
+ for (size_t i = 0; i < msg->argc; ++i)
log("\t%s\n", msg->argv[i]);
}