1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2015 Intel Corporation. 3ad8bd8e3SChangpeng Liu * All rights reserved. 4ad8bd8e3SChangpeng Liu */ 5ad8bd8e3SChangpeng Liu 6ad8bd8e3SChangpeng Liu #include "spdk/file.h" 74897a330SJim Harris #include "spdk/string.h" 8ad8bd8e3SChangpeng Liu 9ad8bd8e3SChangpeng Liu void * 10ad8bd8e3SChangpeng Liu spdk_posix_file_load(FILE *file, size_t *size) 11ad8bd8e3SChangpeng Liu { 12075d422fSKonrad Sztyber uint8_t *newbuf, *buf = NULL; 13ad8bd8e3SChangpeng Liu size_t rc, buf_size, cur_size = 0; 14ad8bd8e3SChangpeng Liu 15ad8bd8e3SChangpeng Liu *size = 0; 16ad8bd8e3SChangpeng Liu buf_size = 128 * 1024; 17ad8bd8e3SChangpeng Liu 18ad8bd8e3SChangpeng Liu while (buf_size <= 1024 * 1024 * 1024) { 19ad8bd8e3SChangpeng Liu newbuf = realloc(buf, buf_size); 20ad8bd8e3SChangpeng Liu if (newbuf == NULL) { 21ad8bd8e3SChangpeng Liu free(buf); 22ad8bd8e3SChangpeng Liu return NULL; 23ad8bd8e3SChangpeng Liu } 24ad8bd8e3SChangpeng Liu buf = newbuf; 25ad8bd8e3SChangpeng Liu 26ad8bd8e3SChangpeng Liu rc = fread(buf + cur_size, 1, buf_size - cur_size, file); 27ad8bd8e3SChangpeng Liu cur_size += rc; 28ad8bd8e3SChangpeng Liu 29ad8bd8e3SChangpeng Liu if (feof(file)) { 30ad8bd8e3SChangpeng Liu *size = cur_size; 31ad8bd8e3SChangpeng Liu return buf; 32ad8bd8e3SChangpeng Liu } 33ad8bd8e3SChangpeng Liu 34ad8bd8e3SChangpeng Liu if (ferror(file)) { 35ad8bd8e3SChangpeng Liu free(buf); 36ad8bd8e3SChangpeng Liu return NULL; 37ad8bd8e3SChangpeng Liu } 38ad8bd8e3SChangpeng Liu 39ad8bd8e3SChangpeng Liu buf_size *= 2; 40ad8bd8e3SChangpeng Liu } 41ad8bd8e3SChangpeng Liu 42ad8bd8e3SChangpeng Liu free(buf); 43ad8bd8e3SChangpeng Liu return NULL; 44ad8bd8e3SChangpeng Liu } 452284b56bSKrzysztof Karas 462284b56bSKrzysztof Karas void * 472284b56bSKrzysztof Karas spdk_posix_file_load_from_name(const char *file_name, size_t *size) 482284b56bSKrzysztof Karas { 492284b56bSKrzysztof Karas FILE *file = fopen(file_name, "r"); 502284b56bSKrzysztof Karas void *data; 512284b56bSKrzysztof Karas 522284b56bSKrzysztof Karas if (file == NULL) { 532284b56bSKrzysztof Karas return NULL; 542284b56bSKrzysztof Karas } 552284b56bSKrzysztof Karas 562284b56bSKrzysztof Karas data = spdk_posix_file_load(file, size); 572284b56bSKrzysztof Karas fclose(file); 582284b56bSKrzysztof Karas 592284b56bSKrzysztof Karas return data; 602284b56bSKrzysztof Karas } 614897a330SJim Harris 624897a330SJim Harris static int 634897a330SJim Harris read_sysfs_attribute(char **attribute_p, const char *format, va_list args) 644897a330SJim Harris { 654897a330SJim Harris char *attribute; 664897a330SJim Harris FILE *file; 674897a330SJim Harris char *path; 684897a330SJim Harris size_t len = 0; 694897a330SJim Harris ssize_t read; 70*084afa90SKonrad Sztyber int errsv; 714897a330SJim Harris 724897a330SJim Harris path = spdk_vsprintf_alloc(format, args); 734897a330SJim Harris if (path == NULL) { 744897a330SJim Harris return -ENOMEM; 754897a330SJim Harris } 764897a330SJim Harris 774897a330SJim Harris file = fopen(path, "r"); 78*084afa90SKonrad Sztyber errsv = errno; 794897a330SJim Harris free(path); 804897a330SJim Harris if (file == NULL) { 81*084afa90SKonrad Sztyber assert(errsv != 0); 82*084afa90SKonrad Sztyber return -errsv; 834897a330SJim Harris } 844897a330SJim Harris 854897a330SJim Harris *attribute_p = NULL; 864897a330SJim Harris read = getline(attribute_p, &len, file); 87*084afa90SKonrad Sztyber errsv = errno; 884897a330SJim Harris fclose(file); 894897a330SJim Harris attribute = *attribute_p; 904897a330SJim Harris if (read == -1) { 914897a330SJim Harris /* getline man page says line should be freed even on failure. */ 924897a330SJim Harris free(attribute); 93*084afa90SKonrad Sztyber assert(errsv != 0); 94*084afa90SKonrad Sztyber return -errsv; 954897a330SJim Harris } 964897a330SJim Harris 974897a330SJim Harris /* len is the length of the allocated buffer, which may be more than 984897a330SJim Harris * the string's length. Reuse len to hold the actual strlen. 994897a330SJim Harris */ 1004897a330SJim Harris len = strlen(attribute); 1014897a330SJim Harris if (attribute[len - 1] == '\n') { 1024897a330SJim Harris attribute[len - 1] = '\0'; 1034897a330SJim Harris } 1044897a330SJim Harris 1054897a330SJim Harris return 0; 1064897a330SJim Harris } 1074897a330SJim Harris 1084897a330SJim Harris int 1094897a330SJim Harris spdk_read_sysfs_attribute(char **attribute_p, const char *path_format, ...) 1104897a330SJim Harris { 1114897a330SJim Harris va_list args; 1124897a330SJim Harris int rc; 1134897a330SJim Harris 1144897a330SJim Harris va_start(args, path_format); 1154897a330SJim Harris rc = read_sysfs_attribute(attribute_p, path_format, args); 1164897a330SJim Harris va_end(args); 1174897a330SJim Harris 1184897a330SJim Harris return rc; 1194897a330SJim Harris } 1202276e22dSJim Harris 1212276e22dSJim Harris int 1222276e22dSJim Harris spdk_read_sysfs_attribute_uint32(uint32_t *attribute, const char *path_format, ...) 1232276e22dSJim Harris { 1242276e22dSJim Harris char *attribute_str = NULL; 1252276e22dSJim Harris long long int val; 1262276e22dSJim Harris va_list args; 1272276e22dSJim Harris int rc; 1282276e22dSJim Harris 1292276e22dSJim Harris va_start(args, path_format); 1302276e22dSJim Harris rc = read_sysfs_attribute(&attribute_str, path_format, args); 1312276e22dSJim Harris va_end(args); 1322276e22dSJim Harris 1332276e22dSJim Harris if (rc != 0) { 1342276e22dSJim Harris return rc; 1352276e22dSJim Harris } 1362276e22dSJim Harris 1372276e22dSJim Harris val = spdk_strtoll(attribute_str, 0); 1382276e22dSJim Harris free(attribute_str); 1392276e22dSJim Harris if (val < 0 || val > UINT32_MAX) { 1402276e22dSJim Harris return -EINVAL; 1412276e22dSJim Harris } 1422276e22dSJim Harris 1432276e22dSJim Harris *attribute = (uint32_t)val; 1442276e22dSJim Harris return 0; 1452276e22dSJim Harris } 146