write a dynamic file reader and remove str library
This commit is contained in:
23
src/files.c
23
src/files.c
@@ -1,25 +1,16 @@
|
||||
#include "files.h"
|
||||
|
||||
#include "logger.h"
|
||||
#include "str.h"
|
||||
#include "types.h"
|
||||
#include "string/hi_string.h"
|
||||
|
||||
HiloadResult read_file_to_str(str *s, const char *filename) {
|
||||
const char* hi_file_to_str_dyn(const char *filename) {
|
||||
|
||||
int copied = str_from_file(s, filename);
|
||||
if (copied != 0) {
|
||||
size_t n = 0;
|
||||
const char *s = hi_string_from_file_dyn(filename, 0, 0);
|
||||
if (!s) {
|
||||
sc_log_error("Failed to read file: %s\n", filename);
|
||||
return HILOAD_FAIL;
|
||||
return 0;
|
||||
}
|
||||
return HILOAD_OK;
|
||||
}
|
||||
|
||||
HiloadResult read_stream_to_str(str *s, const char *filename) {
|
||||
int nread = 0;
|
||||
int copied = str_from_stream(s, filename, &nread);
|
||||
if (copied != 0) {
|
||||
sc_log_error("Failed to read file: %s\n", filename);
|
||||
return HILOAD_FAIL;
|
||||
}
|
||||
return HILOAD_OK;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#ifndef FILES_H_
|
||||
#define FILES_H_
|
||||
|
||||
#include "str.h"
|
||||
#include "types.h"
|
||||
|
||||
HiloadResult read_file_to_str(str *s, const char *);
|
||||
HiloadResult read_stream_to_str(str *s, const char *);
|
||||
const char* hi_file_to_str_dyn(const char *filename);
|
||||
|
||||
#endif // FILES_H_
|
||||
|
||||
12
src/memory.c
12
src/memory.c
@@ -32,16 +32,16 @@ HiloadResult memory_find_pointer(uptr ptr,
|
||||
}
|
||||
|
||||
HiloadResult read_memory_maps_self(struct sc_array_memreg *regions) {
|
||||
str memory_str = str_null;
|
||||
|
||||
sc_array_clear(regions);
|
||||
sc_array_init(regions);
|
||||
|
||||
HiloadResult res = read_stream_to_str(&memory_str, "/proc/self/maps");
|
||||
if (res == HILOAD_FAIL)
|
||||
const char* maps_str = hi_file_to_str_dyn("/proc/self/maps");
|
||||
if (!maps_str)
|
||||
return HILOAD_FAIL;
|
||||
|
||||
char *strptr = (char *)str_ptr(memory_str);
|
||||
sc_log_debug("/proc/self/maps:\n%s", maps_str);
|
||||
|
||||
char *strptr = (char *)maps_str;
|
||||
char *line = strtok(strptr, "\n");
|
||||
while (line) {
|
||||
MemoryRegion reg = {0};
|
||||
@@ -80,7 +80,7 @@ HiloadResult read_memory_maps_self(struct sc_array_memreg *regions) {
|
||||
line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
str_free(memory_str);
|
||||
free((void*)maps_str);
|
||||
|
||||
return HILOAD_OK;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define MEMORY_H_
|
||||
|
||||
#include "array.h"
|
||||
#include "str.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
68
src/string/hi_string.c
Normal file
68
src/string/hi_string.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "hi_string.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char *hi_string_from_file_dyn(const char *filename, size_t *nread,
|
||||
size_t nmax) {
|
||||
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
perror("Failed to open file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if nmax is set, use that as the chunk size and don't reallocate after
|
||||
bool reallocate = true;
|
||||
off_t chunk_size = 4096;
|
||||
|
||||
if (nmax > 0) {
|
||||
chunk_size = nmax;
|
||||
reallocate = false;
|
||||
}
|
||||
|
||||
char *buf = malloc(chunk_size);
|
||||
char *end = buf + chunk_size;
|
||||
size_t total_read = 0;
|
||||
char *p = buf;
|
||||
size_t n = 0;
|
||||
do {
|
||||
n = fread(p, 1, end - p, f);
|
||||
total_read += n;
|
||||
p += n;
|
||||
|
||||
if (p == end && reallocate) {
|
||||
chunk_size *= 2;
|
||||
char *new_buf = realloc(buf, chunk_size);
|
||||
if (!new_buf) {
|
||||
perror("Couldn't realloc memory");
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
buf = new_buf;
|
||||
p = buf + total_read;
|
||||
end = buf + chunk_size;
|
||||
}
|
||||
} while (n > 0);
|
||||
|
||||
// If we didn't happen to read just one byte less than the max length,
|
||||
// then reallocate again to shrink the memory to fit what's read
|
||||
if (p != (end - 1)) {
|
||||
char *new_buf = realloc(buf, total_read + 1);
|
||||
if (!new_buf) {
|
||||
perror("Couldn't realloc memory");
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
buf = new_buf;
|
||||
}
|
||||
|
||||
buf[total_read] = '\0';
|
||||
|
||||
if (nread)
|
||||
*nread = total_read;
|
||||
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
21
src/string/hi_string.h
Normal file
21
src/string/hi_string.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef HI_STRING_H_
|
||||
#define HI_STRING_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/***
|
||||
* @brief Copy file content to a null terminated string, allocating memory while reading.
|
||||
*
|
||||
* This doesn't assume it can read file size, so it allocates memory in chunks
|
||||
* (default 4096 bytes) and keeps reading until 0 bytes is read. If nmax is non-zero, instead that amount of bytes is allocated
|
||||
* and that is read.
|
||||
*
|
||||
* In either case, the string is reallocated to match the length before returning.
|
||||
* @param filename
|
||||
* @param nread if not null, this will have the total amount read in bytes
|
||||
* @param nmax if not 0, this amount of memory in bytes is read ant allocated
|
||||
***/
|
||||
const char *hi_string_from_file_dyn(const char *filename, size_t *nread,
|
||||
size_t nmax);
|
||||
|
||||
#endif // HI_STRING_H_
|
||||
Reference in New Issue
Block a user