utils.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 #include "utils.h" 4 5 #include <sys/mman.h> 6 #include <sys/stat.h> 7 #include <fcntl.h> 8 #include <unistd.h> 9 10 #include <errno.h> 11 #include <limits.h> 12 #include <stdbool.h> 13 #include <stddef.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 18 void *xmalloc(size_t size) 19 { 20 void *p = malloc(size); 21 if (p == NULL) { 22 fprintf(stderr, "Failed to allocate memory\n"); 23 abort(); 24 } 25 return p; 26 } 27 28 char *to_chars(const CHAR16 uchars[], size_t size) 29 { 30 char *chars = xmalloc(size / 2 + 1); 31 32 const CHAR16 *from = uchars; 33 char *to = chars; 34 while (*from != 0) { 35 CHAR16 uc = *from++; 36 if (uc < CHAR_MAX) 37 *to++ = uc; 38 else 39 *to++ = '?'; 40 } 41 42 // In case there was no terminating NUL. 43 if (to != chars && to[-1] != '\0') 44 *to = '\0'; 45 46 return chars; 47 } 48 49 CHAR16 *to_uchars(const char chars[], size_t *size) 50 { 51 *size = (strlen(chars) + 1) * 2; 52 CHAR16 *uchars = xmalloc(*size); 53 54 const char *from = chars; 55 CHAR16 *to = uchars; 56 while (*from != '\0') 57 *to++ = *from++; 58 *to = 0; 59 60 return uchars; 61 } 62 63 bool str_eq(const char lhs[], const char rhs[]) 64 { 65 return strcmp(lhs, rhs) == 0; 66 } 67 68 struct mem_range_t map_file(const char path[], bool rw) 69 { 70 struct mem_range_t range = {0}; 71 72 int open_flags = rw ? O_RDWR : O_RDONLY; 73 int mmap_flags = rw ? PROT_READ | PROT_WRITE : PROT_READ; 74 75 int fd = open(path, open_flags); 76 if (fd == -1) { 77 fprintf(stderr, "Failed to open(): %s\n", strerror(errno)); 78 return range; 79 } 80 81 struct stat stat_buf; 82 if (fstat(fd, &stat_buf) != 0) { 83 (void)close(fd); 84 fprintf(stderr, "Failed to fstat(): %s\n", strerror(errno)); 85 return range; 86 } 87 88 if (stat_buf.st_size == 0) { 89 (void)close(fd); 90 fprintf(stderr, "Can't map an empty \"%s\" file\n", path); 91 return range; 92 } 93 94 uint8_t *mem = mmap(/*addr=*/NULL, stat_buf.st_size, mmap_flags, 95 MAP_SHARED | MAP_POPULATE, fd, /*offset=*/0); 96 (void)close(fd); 97 if (mem == MAP_FAILED) { 98 fprintf(stderr, "Failed to mmap(): %s\n", strerror(errno)); 99 return range; 100 } 101 102 range.start = mem; 103 range.length = stat_buf.st_size; 104 return range; 105 } 106 107 void unmap_file(struct mem_range_t store) 108 { 109 if (munmap(store.start, store.length) != 0) 110 fprintf(stderr, "Failed to munmap(): %s\n", strerror(errno)); 111 }