Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Benjamin Gray and committed by
Michael Ellerman
8d7253dc 5c20de57

+71 -109
+1
tools/testing/selftests/powerpc/include/utils.h
··· 42 42 43 43 int read_file(const char *path, char *buf, size_t count, size_t *len); 44 44 int write_file(const char *path, const char *buf, size_t count); 45 + int read_file_alloc(const char *path, char **buf, size_t *len); 45 46 int read_long(const char *path, long *result, int base); 46 47 int write_long(const char *path, long result, int base); 47 48 int read_ulong(const char *path, unsigned long *result, int base);
+1 -37
tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
··· 143 143 return i; 144 144 } 145 145 146 - /* Caller must free the allocated buffer return nonzero on error. */ 147 - int read_alloc_input_file(char *fname, char **buf, size_t *bufsize) 148 - { 149 - int err; 150 - struct stat statbuf; 151 - char *p; 152 - size_t num_bytes; 153 - 154 - if (stat(fname, &statbuf)) { 155 - perror(fname); 156 - return -1; 157 - } 158 - 159 - assert(NULL != (p = (char *) malloc(statbuf.st_size))); 160 - 161 - err = read_file(fname, p, statbuf.st_size, &num_bytes); 162 - if (err) { 163 - perror(fname); 164 - goto fail; 165 - } 166 - 167 - if (num_bytes != statbuf.st_size) { 168 - fprintf(stderr, "Actual bytes != expected bytes\n"); 169 - err = -1; 170 - goto fail; 171 - } 172 - 173 - *buf = p; 174 - *bufsize = num_bytes; 175 - return 0; 176 - 177 - fail: 178 - free(p); 179 - return err; 180 - } 181 - 182 146 /* 183 147 * Z_SYNC_FLUSH as described in zlib.h. 184 148 * Returns number of appended bytes ··· 209 245 fprintf(stderr, "usage: %s <fname>\n", argv[0]); 210 246 exit(-1); 211 247 } 212 - if (read_alloc_input_file(argv[1], &inbuf, &inlen)) 248 + if (read_file_alloc(argv[1], &inbuf, &inlen)) 213 249 exit(-1); 214 250 fprintf(stderr, "file %s read, %ld bytes\n", argv[1], inlen); 215 251
+1 -1
tools/testing/selftests/powerpc/syscalls/Makefile
··· 6 6 top_srcdir = ../../../../.. 7 7 include ../../lib.mk 8 8 9 - $(TEST_GEN_PROGS): ../harness.c 9 + $(TEST_GEN_PROGS): ../harness.c ../utils.c
+10 -71
tools/testing/selftests/powerpc/syscalls/rtas_filter.c
··· 8 8 #include <byteswap.h> 9 9 #include <stdint.h> 10 10 #include <inttypes.h> 11 + #include <linux/limits.h> 11 12 #include <stdio.h> 12 13 #include <string.h> 13 14 #include <sys/syscall.h> ··· 51 50 struct region *next; 52 51 }; 53 52 54 - int read_entire_file(int fd, char **buf, size_t *len) 55 - { 56 - size_t buf_size = 0; 57 - size_t off = 0; 58 - int rc; 59 - 60 - *buf = NULL; 61 - do { 62 - buf_size += BLOCK_SIZE; 63 - if (*buf == NULL) 64 - *buf = malloc(buf_size); 65 - else 66 - *buf = realloc(*buf, buf_size); 67 - 68 - if (*buf == NULL) 69 - return -ENOMEM; 70 - 71 - rc = read(fd, *buf + off, BLOCK_SIZE); 72 - if (rc < 0) 73 - return -EIO; 74 - 75 - off += rc; 76 - } while (rc == BLOCK_SIZE); 77 - 78 - if (len) 79 - *len = off; 80 - 81 - return 0; 82 - } 83 - 84 - static int open_prop_file(const char *prop_path, const char *prop_name, int *fd) 85 - { 86 - char *path; 87 - int len; 88 - 89 - /* allocate enough for two string, a slash and trailing NULL */ 90 - len = strlen(prop_path) + strlen(prop_name) + 1 + 1; 91 - path = malloc(len); 92 - if (path == NULL) 93 - return -ENOMEM; 94 - 95 - snprintf(path, len, "%s/%s", prop_path, prop_name); 96 - 97 - *fd = open(path, O_RDONLY); 98 - free(path); 99 - if (*fd < 0) 100 - return -errno; 101 - 102 - return 0; 103 - } 104 - 105 53 static int get_property(const char *prop_path, const char *prop_name, 106 54 char **prop_val, size_t *prop_len) 107 55 { 108 - int rc, fd; 56 + char path[PATH_MAX]; 109 57 110 - rc = open_prop_file(prop_path, prop_name, &fd); 111 - if (rc) 112 - return rc; 58 + int len = snprintf(path, sizeof(path), "%s/%s", prop_path, prop_name); 59 + if (len < 0 || len >= sizeof(path)) 60 + return -ENOMEM; 113 61 114 - rc = read_entire_file(fd, prop_val, prop_len); 115 - close(fd); 116 - 117 - return rc; 62 + return read_file_alloc(path, prop_val, prop_len); 118 63 } 119 64 120 65 int rtas_token(const char *call_name) ··· 85 138 static int read_kregion_bounds(struct region *kregion) 86 139 { 87 140 char *buf; 88 - int fd; 89 - int rc; 141 + int err; 90 142 91 - fd = open("/proc/ppc64/rtas/rmo_buffer", O_RDONLY); 92 - if (fd < 0) { 93 - printf("Could not open rmo_buffer file\n"); 143 + err = read_file_alloc("/proc/ppc64/rtas/rmo_buffer", &buf, NULL); 144 + if (err) { 145 + perror("Could not open rmo_buffer file"); 94 146 return RTAS_IO_ASSERT; 95 - } 96 - 97 - rc = read_entire_file(fd, &buf, NULL); 98 - close(fd); 99 - if (rc) { 100 - free(buf); 101 - return rc; 102 147 } 103 148 104 149 sscanf(buf, "%" SCNx64 " %x", &kregion->addr, &kregion->size);
+58
tools/testing/selftests/powerpc/utils.c
··· 65 65 return err; 66 66 } 67 67 68 + int read_file_alloc(const char *path, char **buf, size_t *len) 69 + { 70 + size_t read_offset = 0; 71 + size_t buffer_len = 0; 72 + char *buffer = NULL; 73 + int err; 74 + int fd; 75 + 76 + fd = open(path, O_RDONLY); 77 + if (fd < 0) 78 + return -errno; 79 + 80 + /* 81 + * We don't use stat & preallocate st_size because some non-files 82 + * report 0 file size. Instead just dynamically grow the buffer 83 + * as needed. 84 + */ 85 + while (1) { 86 + ssize_t rc; 87 + 88 + if (read_offset >= buffer_len / 2) { 89 + char *next_buffer; 90 + 91 + buffer_len = buffer_len ? buffer_len * 2 : 4096; 92 + next_buffer = realloc(buffer, buffer_len); 93 + if (!next_buffer) { 94 + err = -errno; 95 + goto out; 96 + } 97 + buffer = next_buffer; 98 + } 99 + 100 + rc = read(fd, buffer + read_offset, buffer_len - read_offset); 101 + if (rc < 0) { 102 + err = -errno; 103 + goto out; 104 + } 105 + 106 + if (rc == 0) 107 + break; 108 + 109 + read_offset += rc; 110 + } 111 + 112 + *buf = buffer; 113 + if (len) 114 + *len = read_offset; 115 + 116 + err = 0; 117 + 118 + out: 119 + close(fd); 120 + if (err) 121 + free(buffer); 122 + errno = -err; 123 + return err; 124 + } 125 + 68 126 int write_file(const char *path, const char *buf, size_t count) 69 127 { 70 128 int fd;