#ifndef FILE_H #define FILE_H #include #define CONCAT(a, b) CONCAT_INNER(a, b) #define CONCAT_INNER(a, b) a ## b #define UNIQUE_NAME(base) CONCAT(base, __COUNTER__) enum file_err { FILE_ERR_OK, FILE_ERR_FAIL_OPEN, FILE_ERR_FAIL_SEEK, FILE_ERR_FAIL_READ, FILE_ERR_FAIL_WRITE, FILE_ERR_FAIL_CALLOC, FILE_ERR_FAIL_CLOSE, FILE_ERR_FILE_EMPTY, FILE_ERR_FAIL_WROTE_MORE, FILE_ERR_EMPTY, }; struct ret_void_p_err { void *f1; /* ptr */ size_t f2; /* size */ enum file_err f3; /* err */ }; struct ret_void_p_err file_read_all(const char *filepath); enum file_err file_save(const char *filepath, const char *str, size_t str_size); #if defined(BMP_IMP) || defined(IMP) #include #include struct ret_void_p_err file_read_all(const char *filepath) { enum file_err err = FILE_ERR_OK; int32_t fd = open(filepath, O_RDONLY); if ( fd < 0 ) { err = FILE_ERR_FAIL_OPEN; goto err; } off_t file_size = lseek(fd, 0, SEEK_END); if ( file_size < 0 ) { err = FILE_ERR_FAIL_SEEK; goto err_close; } lseek(fd, 0, SEEK_SET); printf("file->size = %ld\n", file_size); if ( file_size == 0 ) { err = FILE_ERR_EMPTY; goto err_close; } const size_t buf_size = ((size_t)file_size) + 1; uint8_t *buf = calloc(sizeof(uint8_t), buf_size); if ( buf == NULL ) { err = FILE_ERR_FAIL_CALLOC; goto err_close; } { ssize_t rd = read(fd, buf, (size_t)file_size); if ( rd < 0 ) { err = FILE_ERR_FAIL_READ; free(buf); goto err_close; } if ( rd == 0 ) { err = FILE_ERR_FILE_EMPTY; free(buf); goto err_close; } } if ( close(fd) != 0 ) { /* It should be possible to handle EIO */ err = FILE_ERR_FAIL_CLOSE; goto err; } return (struct ret_void_p_err) { .f1 = buf, .f2 = buf_size, .f3 = err }; err_close: ; if ( close(fd) != 0 ) { /* It should be possible to handle EIO */ err = FILE_ERR_FAIL_CLOSE; goto err; } err: ; return (struct ret_void_p_err) { .f1 = NULL, .f2 = 0, .f3 = err }; } enum file_err file_save(const char *filepath, const char *str, size_t str_size) { int32_t fd = open(filepath, O_WRONLY); if ( fd < 0 ) { return FILE_ERR_FAIL_OPEN; } ssize_t wrote = write(fd, str, str_size); if ( wrote == -1 ) { return FILE_ERR_FAIL_WRITE; } if ( ((size_t) wrote) != str_size ) { return FILE_ERR_FAIL_WROTE_MORE; } if ( close(fd) != 0 ) { /* It should be possible to handle EIO */ return FILE_ERR_FAIL_CLOSE; } return FILE_ERR_OK; } #endif #endif