SOL_API int sol_util_load_file_fd_buffer(int fd, struct sol_buffer *buf) { struct stat st; ssize_t ret; int r; SOL_INT_CHECK(fd, < 0, -EINVAL); SOL_NULL_CHECK(buf, -EINVAL); if (fstat(fd, &st) >= 0 && st.st_size) { ret = sol_util_fill_buffer(fd, buf, st.st_size); } else { do { ret = sol_util_fill_buffer(fd, buf, CHUNK_SIZE); } while (ret > 0); } r = (int)ret; SOL_INT_CHECK(r, < 0, r); return 0; }
struct sol_buffer * sol_util_load_file_raw(const int fd) { struct stat st; ssize_t ret; struct sol_buffer *buffer; if (fd < 0) return NULL; buffer = sol_buffer_new(); SOL_NULL_CHECK(buffer, NULL); buffer->flags = SOL_BUFFER_FLAGS_NO_NUL_BYTE; if (fstat(fd, &st) >= 0 && st.st_size) { ret = sol_util_fill_buffer(fd, buffer, st.st_size); } else { do { ret = sol_util_fill_buffer(fd, buffer, CHUNK_SIZE); } while (ret > 0); } if (ret < 0) goto err; if (sol_buffer_trim(buffer) < 0) goto err; return buffer; err: sol_buffer_free(buffer); return NULL; }
static int child_read(struct sol_blob **p_blob, bool *eof, int fd) { struct sol_buffer buf = SOL_BUFFER_INIT_EMPTY; struct timespec start = sol_util_timespec_get_current(); size_t size; void *v; int ret = 0; *eof = false; do { struct timespec now = sol_util_timespec_get_current(); struct timespec elapsed; ssize_t r; sol_util_timespec_sub(&now, &start, &elapsed); if (elapsed.tv_sec > 0 || elapsed.tv_nsec > (time_t)CHUNK_MAX_TIME_NS) break; r = sol_util_fill_buffer(fd, &buf, CHUNK_READ_SIZE); if (r == 0) { *eof = true; break; } else if (r < 0) { /* Not a problem if failed because buffer could not be increased */ if (r != -ENOMEM) ret = -errno; break; } } while (1); if (ret < 0 && ret != -EAGAIN) { sol_buffer_fini(&buf); return ret; } v = sol_buffer_steal(&buf, &size); *p_blob = sol_blob_new(&SOL_BLOB_TYPE_DEFAULT, NULL, v, size); SOL_NULL_CHECK_GOTO(*p_blob, blob_error); return 0; blob_error: sol_buffer_fini(&buf); return -ENOMEM; }