From 24b4e51e2fedca3417457559399a1d0eaf35c7fd Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Thu, 25 Aug 2022 16:18:52 +0200 Subject: msg: add msg_copy, refactoring --- src/msg.c | 127 +++++++++++++++++++++++++++++++++++--------------------------- src/msg.h | 3 +- 2 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/msg.c b/src/msg.c index 9262f70..863d141 100644 --- a/src/msg.c +++ b/src/msg.c @@ -5,29 +5,16 @@ #include #include -void msg_free(const struct msg *msg) -{ - for (int i = 0; i < msg->argc; ++i) - free(msg->argv[i]); - free(msg->argv); -} - -int msg_from_argv(struct msg *msg, const char *argv[]) +static int msg_copy_argv(struct msg *msg, char **argv) { - int argc = 0; - - for (const char **s = argv; *s; ++s) - ++argc; - - msg->argc = argc; - msg->argv = calloc(argc, sizeof(char *)); + msg->argv = calloc(msg->argc, sizeof(char *)); if (!msg->argv) { print_errno("calloc"); return -1; } - for (int i = 0; i < argc; ++i) { + for (int i = 0; i < msg->argc; ++i) { msg->argv[i] = strdup(argv[i]); if (!msg->argv[i]) { print_errno("strdup"); @@ -38,25 +25,62 @@ int msg_from_argv(struct msg *msg, const char *argv[]) return 0; free: - for (int i = 0; i < argc; ++i) - if (msg->argv[i]) - free(msg->argv[i]); - else - break; + msg_free(msg); - free(msg->argv); return -1; } -static size_t calc_buf_len(int argc, char **argv) +struct msg *msg_copy(const struct msg *src) +{ + struct msg *dest; + int ret = 0; + + dest = malloc(sizeof(*dest)); + if (!dest) { + print_errno("calloc"); + return NULL; + } + dest->argc = src->argc; + + ret = msg_copy_argv(dest, src->argv); + if (ret < 0) + goto free; + + return dest; + +free: + free(dest); + + return NULL; +} + +void msg_free(const struct msg *msg) +{ + for (int i = 0; i < msg->argc; ++i) + free((char *)msg->argv[i]); + free(msg->argv); +} + +int msg_from_argv(struct msg *msg, char **argv) +{ + int argc = 0; + + for (char **s = argv; *s; ++s) + ++argc; + + msg->argc = argc; + return msg_copy_argv(msg, argv); +} + +static size_t calc_buf_len(const struct msg *msg) { size_t len = 0; - for (int i = 0; i < argc; ++i) - len += strlen(argv[i]) + 1; + for (int i = 0; i < msg->argc; ++i) + len += strlen(msg->argv[i]) + 1; return len; } -static int calc_arr_len(const void *buf, size_t len) +static int calc_argv_len(const void *buf, size_t len) { int argc = 0; for (const char *it = buf; it < (const char *)buf + len; it += strlen(it) + 1) @@ -64,37 +88,39 @@ static int calc_arr_len(const void *buf, size_t len) return argc; } -static void arr_pack(char *dest, int argc, char **argv) +static void argv_pack(char *dest, const struct msg *msg) { - for (int i = 0; i < argc; ++i) { - strcpy(dest, argv[i]); - dest += strlen(argv[i]) + 1; + for (int i = 0; i < msg->argc; ++i) { + strcpy(dest, msg->argv[i]); + dest += strlen(msg->argv[i]) + 1; } } -static int arr_unpack(char **argv, int argc, const char *src) +static int argv_unpack(struct msg *msg, const char *src) { - for (int i = 0; i < argc; ++i) { + msg->argv = calloc(msg->argc, sizeof(char *)); + if (!msg->argv) { + print_errno("calloc"); + return -1; + } + + for (int i = 0; i < msg->argc; ++i) { size_t len = strlen(src); - argv[i] = malloc(len); - if (!argv[i]) { + msg->argv[i] = malloc(len); + if (!msg->argv[i]) { print_errno("malloc"); goto free; } - strcpy(argv[i], src); + strcpy(msg->argv[i], src); src += len + 1; } return 0; free: - for (int i = 0; i < argc; ++i) - if (argv[i]) - free(argv[i]); - else - break; + msg_free(msg); return -1; } @@ -103,13 +129,13 @@ int msg_send(int fd, const struct msg *msg) { int ret = 0; - size_t len = calc_buf_len(msg->argc, msg->argv); + size_t len = calc_buf_len(msg); char *buf = malloc(len); if (!buf) { print_errno("malloc"); return -1; } - arr_pack(buf, msg->argc, msg->argv); + argv_pack(buf, msg); ret = net_send_buf(fd, buf, len); if (ret < 0) @@ -146,22 +172,11 @@ int msg_recv(int fd, struct msg *msg) if (ret < 0) return ret; - msg->argc = calc_arr_len(buf, len); - msg->argv = calloc(msg->argc, sizeof(char *)); - if (!msg->argv) { - print_errno("calloc"); - ret = -1; - goto free_buf; - } + msg->argc = calc_argv_len(buf, len); - ret = arr_unpack(msg->argv, msg->argc, buf); + ret = argv_unpack(msg, buf); if (ret < 0) - goto free_argv; - - goto free_buf; - -free_argv: - free(msg->argv); + goto free_buf; free_buf: free(buf); diff --git a/src/msg.h b/src/msg.h index 03e5f89..a71b571 100644 --- a/src/msg.h +++ b/src/msg.h @@ -6,9 +6,10 @@ struct msg { char **argv; }; +struct msg *msg_copy(const struct msg *); void msg_free(const struct msg *); -int msg_from_argv(struct msg *, const char *argv[]); +int msg_from_argv(struct msg *, char **argv); int msg_recv(int fd, struct msg *); int msg_send(int fd, const struct msg *); -- cgit v1.2.3