|
|
|
@ -118,18 +118,10 @@ liHandlerResult li_chunkiter_read(liVRequest *vr, liChunkIter iter, off_t start,
|
|
|
|
|
|
|
|
|
|
our_start = start + c->offset + c->data.file.start;
|
|
|
|
|
|
|
|
|
|
if (-1 == lseek(c->data.file.file->fd, our_start, SEEK_SET)) {
|
|
|
|
|
VR_ERROR(vr, "lseek failed for '%s' (fd = %i): %s",
|
|
|
|
|
GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
|
|
|
|
|
g_strerror(errno));
|
|
|
|
|
g_byte_array_free(c->mem, TRUE);
|
|
|
|
|
c->mem = NULL;
|
|
|
|
|
return LI_HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
read_chunk:
|
|
|
|
|
if (-1 == (we_have = read(c->data.file.file->fd, c->mem->data, length))) {
|
|
|
|
|
if (-1 == (we_have = pread(c->data.file.file->fd, c->mem->data, length, our_start))) {
|
|
|
|
|
if (EINTR == errno) goto read_chunk;
|
|
|
|
|
VR_ERROR(vr, "read failed for '%s' (fd = %i): %s",
|
|
|
|
|
VR_ERROR(vr, "pread failed for '%s' (fd = %i): %s",
|
|
|
|
|
GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
|
|
|
|
|
g_strerror(errno));
|
|
|
|
|
g_byte_array_free(c->mem, TRUE);
|
|
|
|
@ -139,7 +131,7 @@ read_chunk:
|
|
|
|
|
/* may return less than requested bytes due to signals */
|
|
|
|
|
/* CON_TRACE(srv, "read return unexpected number of bytes"); */
|
|
|
|
|
if (we_have == 0) {
|
|
|
|
|
VR_ERROR(vr, "read returned 0 bytes for '%s' (fd = %i): unexpected end of file?",
|
|
|
|
|
VR_ERROR(vr, "pread returned 0 bytes for '%s' (fd = %i): unexpected end of file?",
|
|
|
|
|
GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd);
|
|
|
|
|
g_byte_array_free(c->mem, TRUE);
|
|
|
|
|
c->mem = NULL;
|
|
|
|
@ -159,7 +151,7 @@ read_chunk:
|
|
|
|
|
return LI_HANDLER_GO_ON;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* same as li_chunkiter_read, but tries mmap() first and falls back to read();
|
|
|
|
|
/* same as li_chunkiter_read, but tries mmap() first and falls back to pread();
|
|
|
|
|
* as accessing mmap()-ed areas may result in SIGBUS, you have to handle that signal somehow.
|
|
|
|
|
*/
|
|
|
|
|
liHandlerResult li_chunkiter_read_mmap(liVRequest *vr, liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len) {
|
|
|
|
@ -214,29 +206,14 @@ liHandlerResult li_chunkiter_read_mmap(liVRequest *vr, liChunkIter iter, off_t s
|
|
|
|
|
mmap_errno = errno;
|
|
|
|
|
}
|
|
|
|
|
if (MAP_FAILED == c->data.file.mmap.data) {
|
|
|
|
|
/* fallback to read(...) */
|
|
|
|
|
/* fallback to pread(...) */
|
|
|
|
|
if (!c->mem) {
|
|
|
|
|
c->mem = g_byte_array_sized_new(we_want);
|
|
|
|
|
} else {
|
|
|
|
|
g_byte_array_set_size(c->mem, we_want);
|
|
|
|
|
}
|
|
|
|
|
if (-1 == lseek(c->data.file.file->fd, our_start, SEEK_SET)) {
|
|
|
|
|
/* prefer the error of the first syscall */
|
|
|
|
|
if (0 != mmap_errno) {
|
|
|
|
|
VR_ERROR(vr, "mmap failed for '%s' (fd = %i): %s",
|
|
|
|
|
GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
|
|
|
|
|
g_strerror(mmap_errno));
|
|
|
|
|
} else {
|
|
|
|
|
VR_ERROR(vr, "lseek failed for '%s' (fd = %i): %s",
|
|
|
|
|
GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
|
|
|
|
|
g_strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
g_byte_array_free(c->mem, TRUE);
|
|
|
|
|
c->mem = NULL;
|
|
|
|
|
return LI_HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
read_chunk:
|
|
|
|
|
if (-1 == (we_have = read(c->data.file.file->fd, c->mem->data, we_want))) {
|
|
|
|
|
if (-1 == (we_have = pread(c->data.file.file->fd, c->mem->data, we_want, our_start))) {
|
|
|
|
|
if (EINTR == errno) goto read_chunk;
|
|
|
|
|
/* prefer the error of the first syscall */
|
|
|
|
|
if (0 != mmap_errno) {
|
|
|
|
@ -244,7 +221,7 @@ read_chunk:
|
|
|
|
|
GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
|
|
|
|
|
g_strerror(mmap_errno));
|
|
|
|
|
} else {
|
|
|
|
|
VR_ERROR(vr, "read failed for '%s' (fd = %i): %s",
|
|
|
|
|
VR_ERROR(vr, "pread failed for '%s' (fd = %i): %s",
|
|
|
|
|
GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
|
|
|
|
|
g_strerror(errno));
|
|
|
|
|
}
|
|
|
|
|