Refactor : improved error handling of track write

This commit is contained in:
Aaron Culliney 2015-10-17 10:58:29 -07:00
parent 989a5ce7c1
commit 3ab75c6214

View File

@ -473,26 +473,50 @@ static bool load_track_data(void) {
static bool save_track_data(void) {
SCOPE_TRACE_DISK("save_track_data");
size_t expected = 0;
uint8_t *buf = NULL;
if (disk6.disk[disk6.drive].nibblized) {
// .nib image
int track_pos = NIB_TRACK_SIZE * (disk6.disk[disk6.drive].phase >> 1);
fseek(disk6.disk[disk6.drive].fp, track_pos, SEEK_SET);
if (fwrite(disk6.disk[disk6.drive].track_image, 1, NIB_TRACK_SIZE, disk6.disk[disk6.drive].fp) != NIB_TRACK_SIZE) {
ERRLOG("could not write nib data ...");
return false;
}
expected = NIB_TRACK_SIZE;
buf = disk6.disk[disk6.drive].track_image;
} else {
// .dsk, .do, .po images
uint8_t buf[DSK_TRACK_SIZE];
denibblize_track(disk6.disk[disk6.drive].track_image, disk6.drive, buf);
int track_pos = DSK_TRACK_SIZE * (disk6.disk[disk6.drive].phase >> 1);
fseek(disk6.disk[disk6.drive].fp, track_pos, SEEK_SET);
if (fwrite(buf, 1, DSK_TRACK_SIZE, disk6.disk[disk6.drive].fp) != DSK_TRACK_SIZE) {
ERRLOG("could not write dsk data ...");
return false;
}
uint8_t _buf[DSK_TRACK_SIZE] = { 0 };
denibblize_track(disk6.disk[disk6.drive].track_image, disk6.drive, _buf);
expected = DSK_TRACK_SIZE;
buf = _buf; // !!!
}
fflush(disk6.disk[disk6.drive].fp);
const long track_pos = expected * (disk6.disk[disk6.drive].phase >> 1);
TEMP_FAILURE_RETRY(fseek(disk6.disk[disk6.drive].fp, track_pos, SEEK_SET));
size_t idx = 0;
do {
size_t ct = fwrite(buf+idx, 1, expected-idx, disk6.disk[disk6.drive].fp);
if (UNLIKELY(ct == 0)) {
if (ferror(disk6.disk[disk6.drive].fp)) {
// hopefully a transient error ...
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
usleep(10);
continue;
} else {
ERRLOG("OOPS, fatal error reading disk image %s at phase %d", disk6.disk[disk6.drive].file_name, disk6.disk[disk6.drive].phase);
break;
}
} else {
ERRLOG("OOPS, EOF attemping to read disk image %s at phase %d", disk6.disk[disk6.drive].file_name, disk6.disk[disk6.drive].phase);
break;
}
}
idx += ct;
if (LIKELY(idx == expected)) {
break;
}
assert(idx < expected && "the world is not sane");
} while (1);
TEMP_FAILURE_RETRY(fflush(disk6.disk[disk6.drive].fp));
disk6.disk[disk6.drive].track_dirty = false;
return true;