From 007f7f2f0243384c941bd8bcb93bf022d0dae9a2 Mon Sep 17 00:00:00 2001 From: Valentine Krasnobaeva Date: Mon, 5 Aug 2024 10:03:46 +0200 Subject: [PATCH] MINOR: tools: add fgets_from_mem Add fgets_from_mem() helper to read lines from configuration files, stored now as memory chunks. In order to limit changes in the first-level parser code (readcfgfile()), it is better to reimplement the standard fgets, i.e. to have a fgets, which can read the serialized data line by line from some memory area, instead of file stream, and can keep the same behaviour as libc implementations fgets. --- include/haproxy/tools.h | 3 +++ src/tools.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h index c010af2a0..adadee5c5 100644 --- a/include/haproxy/tools.h +++ b/include/haproxy/tools.h @@ -1217,4 +1217,7 @@ int openssl_compare_current_name(const char *name); void vma_set_name(void *addr, size_t size, const char *type, const char *name); void vma_set_name_id(void *addr, size_t size, const char *type, const char *name, unsigned int id); +/* cfgparse helpers */ +char *fgets_from_mem(char* buf, int size, const char **position, const char *end); + #endif /* _HAPROXY_TOOLS_H */ diff --git a/src/tools.c b/src/tools.c index 124b2b741..220f3fec2 100644 --- a/src/tools.c +++ b/src/tools.c @@ -6659,6 +6659,46 @@ static int init_tools_per_thread() } REGISTER_PER_THREAD_INIT(init_tools_per_thread); +/* reads at most one less than from an arbitrary memory buffer and + * imitates the fgets behaviour, i.e. stops at '\n' or at 'EOF' and returns read + * data in the area pointed by <*buf>. <*position> ptr keeps the current + * position, from which we will start/resume reading, <*end> is a ptr to the end + * of the buffer to read, as we suppose don't have the EOF (see more details on + * it in load_cfg_in_mem(), which is now the only one producer of memory buffers + * to read for fgets_from_mem). + */ +char *fgets_from_mem(char* buf, int size, const char **position, const char *end) +{ + char *new_pos; + int len = 0; + + /* keep fgets behaviour */ + if (size <= 0) + return NULL; + + /* EOF */ + if (*position == end) + return NULL; + + size--; /* keep fgets behaviour, reads at most one less than size */ + new_pos = memchr(*position, '\n', size); + if (new_pos) { + /* '+1' to grab and copy '\n' at the end of line */ + len = (new_pos + 1) - *position; + } else { + /* just copy either the given size, or the rest of the line + * until the end + */ + len = MIN((end - *position), size); + } + + memcpy(buf, *position, len); + *(buf + len) = '\0'; + *position += len; + + return buf; +} + /* * Local variables: * c-indent-level: 8