From: Willy Tarreau Date: Thu, 6 Jul 2023 16:31:53 +0000 (+0200) Subject: MINOR: tools: add function read_line_to_trash() to read a line of a file X-Git-Tag: v2.9-dev5~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f2433fb6a0889dbcc0a85eddfc9a59e835c6128;p=thirdparty%2Fhaproxy.git MINOR: tools: add function read_line_to_trash() to read a line of a file This function takes on input a printf format for the file name, making it particularly suitable for /proc or /sys entries which take a lot of numbers. It also automatically trims the trailing CR and/or LF chars. --- diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h index 1f6c2008e5..2fc92bb902 100644 --- a/include/haproxy/tools.h +++ b/include/haproxy/tools.h @@ -908,6 +908,7 @@ int my_unsetenv(const char *name); */ char *env_expand(char *in); uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbargs, uint32_t opts, const char **errptr); +ssize_t read_line_to_trash(const char *path_fmt, ...); size_t sanitize_for_printing(char *line, size_t pos, size_t width); void update_word_fingerprint(uint8_t *fp, const char *word); void make_word_fingerprint(uint8_t *fp, const char *word); diff --git a/src/tools.c b/src/tools.c index a9a114bca2..20d13c3841 100644 --- a/src/tools.c +++ b/src/tools.c @@ -5827,6 +5827,50 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg } #undef EMIT_CHAR +/* Use and following arguments as a printf format to build up the + * name of a file, whose first line will be read into the trash buffer. The + * trailing CR and LF if any are stripped. On success, it sets trash.data to + * the number of resulting bytes in the trash and returns this value. Otherwise + * on failure it returns -1 if it could not build the path, -2 on file access + * access error (e.g. permissions), or -3 on file read error. The trash is + * always reset before proceeding. Too large lines are truncated to the size + * of the trash. + */ +ssize_t read_line_to_trash(const char *path_fmt, ...) +{ + va_list args; + FILE *file; + ssize_t ret; + + chunk_reset(&trash); + + va_start(args, path_fmt); + ret = vsnprintf(trash.area, trash.size, path_fmt, args); + va_end(args); + + if (ret >= trash.size) + return -1; + + file = fopen(trash.area, "r"); + if (!file) + return -2; + + ret = -3; + chunk_reset(&trash); + if (fgets(trash.area, trash.size, file)) { + trash.data = strlen(trash.area); + while (trash.data && + (trash.area[trash.data - 1] == '\r' || + trash.area[trash.data - 1] == '\n')) + trash.data--; + trash.area[trash.data] = 0; + ret = trash.data; // success + } + + fclose(file); + return ret; +} + /* This is used to sanitize an input line that's about to be used for error reporting. * It will adjust to print approximately chars around , trying to * preserve the beginning, with leading or trailing "..." when the line is truncated.