summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/powerpc/utils.c
diff options
context:
space:
mode:
authorBenjamin Gray <bgray@linux.ibm.com>2023-02-03 03:39:47 +0300
committerMichael Ellerman <mpe@ellerman.id.au>2023-02-09 15:56:45 +0300
commit8d7253dc447473dfcf3f09fb0fa2bd6f7d05b43b (patch)
treecbf5ab6fd7a01894b5482ba47c5d6d95dfded4e4 /tools/testing/selftests/powerpc/utils.c
parent5c20de57888f0962e25a0eeec1a59c98056fc42e (diff)
downloadlinux-8d7253dc447473dfcf3f09fb0fa2bd6f7d05b43b.tar.xz
selftests/powerpc: Add automatically allocating read_file
A couple of tests roll their own auto-allocating file read logic. Add a generic implementation and convert them to use it. Signed-off-by: Benjamin Gray <bgray@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20230203003947.38033-6-bgray@linux.ibm.com
Diffstat (limited to 'tools/testing/selftests/powerpc/utils.c')
-rw-r--r--tools/testing/selftests/powerpc/utils.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c
index 1017f1738619..7c8cfedb012a 100644
--- a/tools/testing/selftests/powerpc/utils.c
+++ b/tools/testing/selftests/powerpc/utils.c
@@ -65,6 +65,64 @@ out:
return err;
}
+int read_file_alloc(const char *path, char **buf, size_t *len)
+{
+ size_t read_offset = 0;
+ size_t buffer_len = 0;
+ char *buffer = NULL;
+ int err;
+ int fd;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -errno;
+
+ /*
+ * We don't use stat & preallocate st_size because some non-files
+ * report 0 file size. Instead just dynamically grow the buffer
+ * as needed.
+ */
+ while (1) {
+ ssize_t rc;
+
+ if (read_offset >= buffer_len / 2) {
+ char *next_buffer;
+
+ buffer_len = buffer_len ? buffer_len * 2 : 4096;
+ next_buffer = realloc(buffer, buffer_len);
+ if (!next_buffer) {
+ err = -errno;
+ goto out;
+ }
+ buffer = next_buffer;
+ }
+
+ rc = read(fd, buffer + read_offset, buffer_len - read_offset);
+ if (rc < 0) {
+ err = -errno;
+ goto out;
+ }
+
+ if (rc == 0)
+ break;
+
+ read_offset += rc;
+ }
+
+ *buf = buffer;
+ if (len)
+ *len = read_offset;
+
+ err = 0;
+
+out:
+ close(fd);
+ if (err)
+ free(buffer);
+ errno = -err;
+ return err;
+}
+
int write_file(const char *path, const char *buf, size_t count)
{
int fd;