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.
This commit is contained in:
Valentine Krasnobaeva 2024-08-05 10:03:46 +02:00 committed by Willy Tarreau
parent 03e63b98ca
commit 007f7f2f02
2 changed files with 43 additions and 0 deletions

View 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 */

View 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