Letting lfs_read() retry if read(2) returns a short byte count.

This commit is contained in:
Thomas Schmitt 2014-11-20 13:15:35 +01:00
parent 2fe0bf511b
commit 210b5817cb
2 changed files with 19 additions and 13 deletions

View File

@ -1194,6 +1194,9 @@ int iso_patch_eltoritos(Ecma119Image *t)
ret = iso_stream_read(original, buf, size); ret = iso_stream_read(original, buf, size);
iso_stream_close(original); iso_stream_close(original);
if (ret != (int) size) { if (ret != (int) size) {
if (ret >= 0)
iso_msg_submit(t->image->id, ISO_FILE_READ_ERROR, 0,
"Cannot read all bytes from El Torito boot image for boot info table");
return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR; return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
} }

View File

@ -282,6 +282,9 @@ static
int lfs_read(IsoFileSource *src, void *buf, size_t count) int lfs_read(IsoFileSource *src, void *buf, size_t count)
{ {
_LocalFsFileSource *data; _LocalFsFileSource *data;
size_t to_read, done = 0;
int ret;
uint8_t *buf8;
if (src == NULL || buf == NULL) { if (src == NULL || buf == NULL) {
return ISO_NULL_POINTER; return ISO_NULL_POINTER;
@ -293,28 +296,28 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
data = src->data; data = src->data;
switch (data->openned) { switch (data->openned) {
case 1: /* not dir */ case 1: /* not dir */
{ buf8 = (uint8_t *) buf; /* for pointer arithmetic */
int ret; for (to_read = count; to_read > 0; to_read = count - done) {
ret = read(data->info.fd, buf, count); if (to_read > 1024 * 1024)
to_read = 1024 * 1024;
ret = read(data->info.fd, buf8 + done, to_read);
if (ret < 0) { if (ret < 0) {
/* error on read */ /* error on read */
switch (errno) { switch (errno) {
case EINTR: case EINTR:
ret = ISO_INTERRUPTED; return ISO_INTERRUPTED;
break;
case EFAULT: case EFAULT:
ret = ISO_OUT_OF_MEM; return ISO_OUT_OF_MEM;
break;
case EIO: case EIO:
ret = ISO_FILE_READ_ERROR; return ISO_FILE_READ_ERROR;
break;
default:
ret = ISO_FILE_ERROR;
break;
} }
return ISO_FILE_ERROR;
} }
return ret; if (ret == 0) /* EOF */
break;
done += ret;
} }
return done;
case 2: /* directory */ case 2: /* directory */
return ISO_FILE_IS_DIR; return ISO_FILE_IS_DIR;
default: default: