Read entire file into malloc'd buffer. Sets *out_len. Returns NULL on error. */
| 130 | |
| 131 | /* Read entire file into malloc'd buffer. Sets *out_len. Returns NULL on error. */ |
| 132 | static char *read_file_alloc(const char *path, size_t *out_len) { |
| 133 | FILE *fp = cbm_fopen(path, "rb"); |
| 134 | if (!fp) { |
| 135 | return NULL; |
| 136 | } |
| 137 | (void)fseek(fp, 0, SEEK_END); |
| 138 | long sz = ftell(fp); |
| 139 | if (sz <= 0) { |
| 140 | (void)fclose(fp); |
| 141 | return NULL; |
| 142 | } |
| 143 | (void)fseek(fp, 0, SEEK_SET); |
| 144 | char *buf = malloc((size_t)sz); |
| 145 | if (!buf) { |
| 146 | (void)fclose(fp); |
| 147 | return NULL; |
| 148 | } |
| 149 | size_t rd = fread(buf, ART_NUL, (size_t)sz, fp); |
| 150 | (void)fclose(fp); |
| 151 | if ((long)rd != sz) { |
| 152 | free(buf); |
| 153 | return NULL; |
| 154 | } |
| 155 | *out_len = (size_t)sz; |
| 156 | return buf; |
| 157 | } |
| 158 | |
| 159 | /* Write buffer to file atomically (write to tmp, rename). Returns 0 on success. */ |
| 160 | static int write_file_atomic(const char *path, const char *data, size_t len, |
no test coverage detected