xref: /spdk/lib/util/file.c (revision b6875e1ce57743f3b1416016b9c624d79a862af9)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2015 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/file.h"
7 #include "spdk/string.h"
8 
9 void *
10 spdk_posix_file_load(FILE *file, size_t *size)
11 {
12 	uint8_t *newbuf, *buf = NULL;
13 	size_t rc, buf_size, cur_size = 0;
14 
15 	*size = 0;
16 	buf_size = 128 * 1024;
17 
18 	while (buf_size <= 1024 * 1024 * 1024) {
19 		newbuf = realloc(buf, buf_size);
20 		if (newbuf == NULL) {
21 			free(buf);
22 			return NULL;
23 		}
24 		buf = newbuf;
25 
26 		rc = fread(buf + cur_size, 1, buf_size - cur_size, file);
27 		cur_size += rc;
28 
29 		if (feof(file)) {
30 			*size = cur_size;
31 			return buf;
32 		}
33 
34 		if (ferror(file)) {
35 			free(buf);
36 			return NULL;
37 		}
38 
39 		buf_size *= 2;
40 	}
41 
42 	free(buf);
43 	return NULL;
44 }
45 
46 void *
47 spdk_posix_file_load_from_name(const char *file_name, size_t *size)
48 {
49 	FILE *file = fopen(file_name, "r");
50 	void *data;
51 
52 	if (file == NULL) {
53 		return NULL;
54 	}
55 
56 	data = spdk_posix_file_load(file, size);
57 	fclose(file);
58 
59 	return data;
60 }
61 
62 static int
63 read_sysfs_attribute(char **attribute_p, const char *format, va_list args)
64 {
65 	char *attribute;
66 	FILE *file;
67 	char *path;
68 	size_t len = 0;
69 	ssize_t read;
70 
71 	path = spdk_vsprintf_alloc(format, args);
72 	if (path == NULL) {
73 		return -ENOMEM;
74 	}
75 
76 	file = fopen(path, "r");
77 	free(path);
78 	if (file == NULL) {
79 		return -errno;
80 	}
81 
82 	*attribute_p = NULL;
83 	read = getline(attribute_p, &len, file);
84 	fclose(file);
85 	attribute = *attribute_p;
86 	if (read == -1) {
87 		/* getline man page says line should be freed even on failure. */
88 		free(attribute);
89 		return -errno;
90 	}
91 
92 	/* len is the length of the allocated buffer, which may be more than
93 	 * the string's length. Reuse len to hold the actual strlen.
94 	 */
95 	len = strlen(attribute);
96 	if (attribute[len - 1] == '\n') {
97 		attribute[len - 1] = '\0';
98 	}
99 
100 	return 0;
101 }
102 
103 int
104 spdk_read_sysfs_attribute(char **attribute_p, const char *path_format, ...)
105 {
106 	va_list args;
107 	int rc;
108 
109 	va_start(args, path_format);
110 	rc = read_sysfs_attribute(attribute_p, path_format, args);
111 	va_end(args);
112 
113 	return rc;
114 }
115 
116 int
117 spdk_read_sysfs_attribute_uint32(uint32_t *attribute, const char *path_format, ...)
118 {
119 	char *attribute_str = NULL;
120 	long long int val;
121 	va_list args;
122 	int rc;
123 
124 	va_start(args, path_format);
125 	rc = read_sysfs_attribute(&attribute_str, path_format, args);
126 	va_end(args);
127 
128 	if (rc != 0) {
129 		return rc;
130 	}
131 
132 	val = spdk_strtoll(attribute_str, 0);
133 	free(attribute_str);
134 	if (val < 0 || val > UINT32_MAX) {
135 		return -EINVAL;
136 	}
137 
138 	*attribute = (uint32_t)val;
139 	return 0;
140 }
141