summaryrefslogtreecommitdiff
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
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
-rw-r--r--tools/testing/selftests/powerpc/include/utils.h1
-rw-r--r--tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c38
-rw-r--r--tools/testing/selftests/powerpc/syscalls/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/syscalls/rtas_filter.c81
-rw-r--r--tools/testing/selftests/powerpc/utils.c58
5 files changed, 71 insertions, 109 deletions
diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h
index 311ddc124ebc..eed7dd7582b2 100644
--- a/tools/testing/selftests/powerpc/include/utils.h
+++ b/tools/testing/selftests/powerpc/include/utils.h
@@ -42,6 +42,7 @@ int parse_ulong(const char *buffer, size_t count, unsigned long *result, int bas
int read_file(const char *path, char *buf, size_t count, size_t *len);
int write_file(const char *path, const char *buf, size_t count);
+int read_file_alloc(const char *path, char **buf, size_t *len);
int read_long(const char *path, long *result, int base);
int write_long(const char *path, long result, int base);
int read_ulong(const char *path, unsigned long *result, int base);
diff --git a/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
index fbc3d265155b..4de079923ccb 100644
--- a/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
+++ b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
@@ -143,42 +143,6 @@ int gzip_header_blank(char *buf)
return i;
}
-/* Caller must free the allocated buffer return nonzero on error. */
-int read_alloc_input_file(char *fname, char **buf, size_t *bufsize)
-{
- int err;
- struct stat statbuf;
- char *p;
- size_t num_bytes;
-
- if (stat(fname, &statbuf)) {
- perror(fname);
- return -1;
- }
-
- assert(NULL != (p = (char *) malloc(statbuf.st_size)));
-
- err = read_file(fname, p, statbuf.st_size, &num_bytes);
- if (err) {
- perror(fname);
- goto fail;
- }
-
- if (num_bytes != statbuf.st_size) {
- fprintf(stderr, "Actual bytes != expected bytes\n");
- err = -1;
- goto fail;
- }
-
- *buf = p;
- *bufsize = num_bytes;
- return 0;
-
-fail:
- free(p);
- return err;
-}
-
/*
* Z_SYNC_FLUSH as described in zlib.h.
* Returns number of appended bytes
@@ -245,7 +209,7 @@ int compress_file(int argc, char **argv, void *handle)
fprintf(stderr, "usage: %s <fname>\n", argv[0]);
exit(-1);
}
- if (read_alloc_input_file(argv[1], &inbuf, &inlen))
+ if (read_file_alloc(argv[1], &inbuf, &inlen))
exit(-1);
fprintf(stderr, "file %s read, %ld bytes\n", argv[1], inlen);
diff --git a/tools/testing/selftests/powerpc/syscalls/Makefile b/tools/testing/selftests/powerpc/syscalls/Makefile
index b63f8459c704..54ff5cfffc63 100644
--- a/tools/testing/selftests/powerpc/syscalls/Makefile
+++ b/tools/testing/selftests/powerpc/syscalls/Makefile
@@ -6,4 +6,4 @@ CFLAGS += -I../../../../../usr/include
top_srcdir = ../../../../..
include ../../lib.mk
-$(TEST_GEN_PROGS): ../harness.c
+$(TEST_GEN_PROGS): ../harness.c ../utils.c
diff --git a/tools/testing/selftests/powerpc/syscalls/rtas_filter.c b/tools/testing/selftests/powerpc/syscalls/rtas_filter.c
index 03b487f18d00..9b17780f0b18 100644
--- a/tools/testing/selftests/powerpc/syscalls/rtas_filter.c
+++ b/tools/testing/selftests/powerpc/syscalls/rtas_filter.c
@@ -8,6 +8,7 @@
#include <byteswap.h>
#include <stdint.h>
#include <inttypes.h>
+#include <linux/limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/syscall.h>
@@ -50,70 +51,16 @@ struct region {
struct region *next;
};
-int read_entire_file(int fd, char **buf, size_t *len)
-{
- size_t buf_size = 0;
- size_t off = 0;
- int rc;
-
- *buf = NULL;
- do {
- buf_size += BLOCK_SIZE;
- if (*buf == NULL)
- *buf = malloc(buf_size);
- else
- *buf = realloc(*buf, buf_size);
-
- if (*buf == NULL)
- return -ENOMEM;
-
- rc = read(fd, *buf + off, BLOCK_SIZE);
- if (rc < 0)
- return -EIO;
-
- off += rc;
- } while (rc == BLOCK_SIZE);
-
- if (len)
- *len = off;
-
- return 0;
-}
-
-static int open_prop_file(const char *prop_path, const char *prop_name, int *fd)
-{
- char *path;
- int len;
-
- /* allocate enough for two string, a slash and trailing NULL */
- len = strlen(prop_path) + strlen(prop_name) + 1 + 1;
- path = malloc(len);
- if (path == NULL)
- return -ENOMEM;
-
- snprintf(path, len, "%s/%s", prop_path, prop_name);
-
- *fd = open(path, O_RDONLY);
- free(path);
- if (*fd < 0)
- return -errno;
-
- return 0;
-}
-
static int get_property(const char *prop_path, const char *prop_name,
char **prop_val, size_t *prop_len)
{
- int rc, fd;
-
- rc = open_prop_file(prop_path, prop_name, &fd);
- if (rc)
- return rc;
+ char path[PATH_MAX];
- rc = read_entire_file(fd, prop_val, prop_len);
- close(fd);
+ int len = snprintf(path, sizeof(path), "%s/%s", prop_path, prop_name);
+ if (len < 0 || len >= sizeof(path))
+ return -ENOMEM;
- return rc;
+ return read_file_alloc(path, prop_val, prop_len);
}
int rtas_token(const char *call_name)
@@ -138,22 +85,14 @@ err:
static int read_kregion_bounds(struct region *kregion)
{
char *buf;
- int fd;
- int rc;
+ int err;
- fd = open("/proc/ppc64/rtas/rmo_buffer", O_RDONLY);
- if (fd < 0) {
- printf("Could not open rmo_buffer file\n");
+ err = read_file_alloc("/proc/ppc64/rtas/rmo_buffer", &buf, NULL);
+ if (err) {
+ perror("Could not open rmo_buffer file");
return RTAS_IO_ASSERT;
}
- rc = read_entire_file(fd, &buf, NULL);
- close(fd);
- if (rc) {
- free(buf);
- return rc;
- }
-
sscanf(buf, "%" SCNx64 " %x", &kregion->addr, &kregion->size);
free(buf);
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;