]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: add function read_line_to_trash() to read a line of a file
authorWilly Tarreau <w@1wt.eu>
Thu, 6 Jul 2023 16:31:53 +0000 (18:31 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 8 Sep 2023 14:25:19 +0000 (16:25 +0200)
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.

include/haproxy/tools.h
src/tools.c

index 1f6c2008e5e91e01e88fe9d73d804041388a9181..2fc92bb902e9efbdf0df65488746a46fe3da2a16 100644 (file)
@@ -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);
index a9a114bca2b7a1f49ca7fc74e3887274e10ae561..20d13c38414588b959e8c42ae111f4e4d2c5eae9 100644 (file)
@@ -5827,6 +5827,50 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg
 }
 #undef EMIT_CHAR
 
+/* Use <path_fmt> 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 <line> to print approximately <width> chars around <pos>, trying to
  * preserve the beginning, with leading or trailing "..." when the line is truncated.