]> git.ozlabs.org Git - ccan/commitdiff
grab_file: clarify API usage, since Sangbida had to write a helper.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 14 Oct 2025 01:57:57 +0000 (12:27 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 14 Oct 2025 01:57:57 +0000 (12:27 +1030)
Turns out many cases just want the damn raw file contents.  So, split the
interface into grab_fd_str/grab_file_str and grab_fd_raw/grab_file_raw
and make a deprecated alias from grab_fd/grab_file to grab_fd_str/grab_file_str.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/tal/grab_file/_info
ccan/tal/grab_file/grab_file.c
ccan/tal/grab_file/grab_file.h
ccan/tal/grab_file/test/run-grab.c

index 056f10990b08111ce1ebdc6c66541c445d87c7d0..0c18e6dc8778045f9ab2ad557370cf462a7732e8 100644 (file)
@@ -45,6 +45,7 @@ int main(int argc, char *argv[])
                return 1;
 
        if (strcmp(argv[1], "depends") == 0) {
+               printf("ccan/compiler\n");
                printf("ccan/tal\n");
                printf("ccan/noerr\n");
                return 0;
index 6528780a67813aae78f43b318ce72e7eaca3b6c1..fcadc8334362558fed87de1149502e7aa093bce4 100644 (file)
@@ -8,7 +8,7 @@
 #include <errno.h>
 #include <fcntl.h>
 
-void *grab_fd(const void *ctx, int fd)
+static void *grab_fd_internal(const void *ctx, int fd, bool add_nul_term)
 {
        int ret;
        size_t max, size;
@@ -22,7 +22,7 @@ void *grab_fd(const void *ctx, int fd)
        else
                max = 16384;
 
-       buffer = tal_arr(ctx, char, max+1);
+       buffer = tal_arr(ctx, char, max+add_nul_term);
        while ((ret = read(fd, buffer + size, max - size)) != 0) {
                if (ret < 0) {
                        if (errno == EINTR)
@@ -35,19 +35,20 @@ void *grab_fd(const void *ctx, int fd)
                        if (extra > 1024 * 1024)
                                extra = 1024 * 1024;
 
-                       if (!tal_resize(&buffer, max+extra+1))
+                       if (!tal_resize(&buffer, max+extra+add_nul_term))
                                return NULL;
 
                        max += extra;
                }
        }
-       buffer[size] = '\0';
-       tal_resize(&buffer, size+1);
+       if (add_nul_term)
+               buffer[size] = '\0';
+       tal_resize(&buffer, size+add_nul_term);
 
        return buffer;
 }
 
-void *grab_file(const void *ctx, const char *filename)
+static void *grab_file_internal(const void *ctx, const char *filename, bool add_nul_term)
 {
        int fd;
        char *buffer;
@@ -60,7 +61,27 @@ void *grab_file(const void *ctx, const char *filename)
        if (fd < 0)
                return NULL;
 
-       buffer = grab_fd(ctx, fd);
+       buffer = grab_fd_internal(ctx, fd, add_nul_term);
        close_noerr(fd);
        return buffer;
 }
+
+void *grab_fd_raw(const void *ctx, int fd)
+{
+       return grab_fd_internal(ctx, fd, false);
+}
+
+void *grab_fd_str(const void *ctx, int fd)
+{
+       return grab_fd_internal(ctx, fd, true);
+}
+
+void *grab_file_str(const void *ctx, const char *filename)
+{
+       return grab_file_internal(ctx, filename, true);
+}
+
+void *grab_file_raw(const void *ctx, const char *filename)
+{
+       return grab_file_internal(ctx, filename, false);
+}
index 2eb1a0082ef7c7efe2610c420199a3677df6a918..f2f7e6731a4362d5eb148d1d04f0d284bfdcbd82 100644 (file)
@@ -2,9 +2,31 @@
 #ifndef CCAN_TAL_GRAB_FILE_H
 #define CCAN_TAL_GRAB_FILE_H
 #include <stdio.h> // For size_t
+#include <ccan/compiler/compiler.h>
 
 /**
- * grab_fd - read all of a file descriptor into memory
+ * grab_fd_raw - read all of a file descriptor into memory WITHOUT adding a nul.
+ * @ctx: the context to tallocate from (often NULL)
+ * @fd: the file descriptor to read from
+ * @size: the (optional) size of the file
+ *
+ * This function reads from the given file descriptor until no more
+ * input is available.  The content is talloced off @ctx, and the
+ * tal_count() is the size in bytes.
+ *
+ * Note that this does *not* currently exit on EINTR, but continues
+ * reading. *
+ * Example:
+ *     // Return the first line.
+ *     static char *read_stdin_all(void)
+ *     {
+ *             return grab_fd_raw(NULL, 0);
+ *     }
+ */
+void *grab_fd_raw(const void *ctx, int fd);
+
+/**
+ * grab_fd_str - read all of a file descriptor into memory with a NUL terminator.
  * @ctx: the context to tallocate from (often NULL)
  * @fd: the file descriptor to read from
  *
@@ -25,7 +47,7 @@
  *     {
  *             char **lines, *all;
  *
- *             all = grab_fd(NULL, 0);
+ *             all = grab_fd_str(NULL, 0);
  *             if (!all)
  *                     return NULL;
  *             lines = tal_strsplit(NULL, all, "\n", STR_EMPTY_OK);
  *             return lines;
  *     }
  */
-void *grab_fd(const void *ctx, int fd);
+void *grab_fd_str(const void *ctx, int fd);
+
+/* Deprecated synonym for grab_fd_str */
+static inline void *grab_fd(const void *ctx, int fd)
+       WARN_DEPRECATED;
+static inline void *grab_fd(const void *ctx, int fd)
+{
+       return grab_fd_str(ctx, fd);
+}
 
 /**
- * grab_file - read all of a file (or stdin) into memory
+ * grab_file_str - read all of a file (or stdin) into memory with a NUL terminator
  * @ctx: the context to tallocate from (often NULL)
  * @filename: the file to read (NULL for stdin)
  *
@@ -51,7 +81,7 @@ void *grab_fd(const void *ctx, int fd);
  *     {
  *             char **lines, *all;
  *
- *             all = grab_file(NULL, filename);
+ *             all = grab_file_str(NULL, filename);
  *             if (!all)
  *                     return NULL;
  *             lines = tal_strsplit(NULL, all, "\n", STR_EMPTY_OK);
@@ -59,5 +89,32 @@ void *grab_fd(const void *ctx, int fd);
  *             return lines;
  *     }
  */
-void *grab_file(const void *ctx, const char *filename);
+void *grab_file_str(const void *ctx, const char *filename);
+
+/**
+ * grab_file_raw - read all of a file (or stdin) into memory WITHOUT a NUL terminator
+ * @ctx: the context to tallocate from (often NULL)
+ * @filename: the file to read (NULL for stdin)
+ * @size: the (optional) size of the file
+ *
+ * This function reads from the given file until no more input is
+ * available.  The content is talloced off @ctx, and the tal_count()
+ * is the size in bytes.
+ *
+ * Example:
+ *     static char *read_file_all(const char *filename)
+ *     {
+ *             return grab_file_raw(NULL, filename);
+ *     }
+ */
+void *grab_file_raw(const void *ctx, const char *filename);
+
+/* Deprecated synonym for grab_file_str */
+static inline void *grab_file(const void *ctx, const char *filename)
+       WARN_DEPRECATED;
+static inline void *grab_file(const void *ctx, const char *filename)
+{
+       return grab_file_str(ctx, filename);
+}
+
 #endif /* CCAN_TAL_GRAB_FILE_H */
index ddb5ca307a48e899fab560df273874ceab7e97b0..02e78aca719e2414fb866e148de50ee6b71bb3a1 100644 (file)
@@ -1,4 +1,4 @@
-/* This is test for grab_file() function
+/* This is test for grab_file_str() and grab_file_raw() functions
  */
 #include <ccan/tal/grab_file/grab_file.h>
 #include <stdlib.h>
@@ -13,25 +13,31 @@ int
 main(void)
 {
        unsigned int    i;
-       char            **split, *str;
+       char            **split, *str, *raw;
        int             length;
        struct          stat st;
 
-       str = grab_file(NULL, "test/run-grab.c");
+       plan_tests(5);
+       str = grab_file_str(NULL, "test/run-grab.c");
        split = tal_strsplit(str, str, "\n", STR_EMPTY_OK);
        length = strlen(split[0]);
-       ok1(!strcmp(split[0], "/* This is test for grab_file() function"));
+       ok1(!strcmp(split[0], "This is test for grab_file_str() and grab_file_raw() functions"));
        for (i = 1; split[i]; i++)
                length += strlen(split[i]);
-       ok1(!strcmp(split[i-1], "/* End of grab_file() test */"));
+       ok1(!strcmp(split[i-1], "/* End of grab_file.c test */"));
        if (stat("test/run-grab.c", &st) != 0)
                /* FIXME: ditto */
                if (stat("ccan/tal/grab_file/test/run-grab.c", &st) != 0)
                        err(1, "Could not stat self");
        ok1(st.st_size == length + i);
+
+       /* Raw does not nul term */
+       raw = grab_file_raw(str, "test/run-grab.c");
+       ok1(tal_count(raw) + 1 == tal_count(str));
+       ok1(memcmp(raw, str, tal_bytelen(raw)) == 0);
        tal_free(str);
 
        return 0;
 }
 
-/* End of grab_file() test */
+/* End of grab_file.c test */