]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: add fgets_from_mem
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Mon, 5 Aug 2024 08:03:46 +0000 (10:03 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 7 Aug 2024 16:41:41 +0000 (18:41 +0200)
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
src/tools.c

index c010af2a0e75dd54c9e3f509e4eea927d06e5a6e..adadee5c51669054b8ac16ba2c3c8ee3eeeac809 100644 (file)
@@ -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 */
index 124b2b74154f6fa49f5c9a1f1cc7fff2a72355d6..220f3fec25b00ae504615fe2b1bed91d675f2a70 100644 (file)
@@ -6659,6 +6659,46 @@ static int init_tools_per_thread()
 }
 REGISTER_PER_THREAD_INIT(init_tools_per_thread);
 
+/* reads at most one less than <size> 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