Skip to content

Commit 9f8abfc

Browse files
committed
Add additional IOStatus codes for file I/O.
1 parent fae6fb3 commit 9f8abfc

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

source/eventcore/driver.d

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,11 +1167,17 @@ enum IOMode {
11671167
}
11681168

11691169
enum IOStatus {
1170-
ok, /// The data has been transferred normally
1171-
disconnected, /// The connection was closed before all data could be transterred
1172-
error, /// An error occured while transferring the data
1173-
wouldBlock, /// Returned for `IOMode.immediate` when no data is readily readable/writable
1174-
invalidHandle, /// The passed handle is not valid
1170+
ok, /// The data has been transferred normally
1171+
disconnected, /// The connection was closed before all data could be transterred
1172+
error, /// An error occured while transferring the data
1173+
wouldBlock, /// Returned for `IOMode.immediate` when no data is readily readable/writable
1174+
invalidHandle, /// The passed handle is not valid
1175+
readPastEOF, /// An attempt was made to read data past the end of the file
1176+
noSpaceLeft, /// Data could not be written, because the target volume is full
1177+
operationNotSupported, /// The underlying file system does not support the I/O operation
1178+
tooLarge, /// The size of the file written to is too large for the file system
1179+
ioError, /// An error occurred while physically writing data
1180+
notAllowed /// The operation failed due to insufficient permissions
11751181
}
11761182

11771183
enum DNSStatus {

source/eventcore/drivers/threadedfile.d

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -471,28 +471,46 @@ log("start processing");
471471
assert(false, "File slot not in initiated state when processor task is started.");
472472

473473
auto bytes = buffer;
474+
ulong seekret;
474475
version (Windows) {
475-
._lseeki64(cast(int)file, offset, SEEK_SET);
476+
seekret = ._lseeki64(cast(int)file, offset, SEEK_SET);
476477
} else version (linux) {
477-
.lseek64(cast(int)file, offset, SEEK_SET);
478+
seekret = .lseek64(cast(int)file, offset, SEEK_SET);
478479
} else version (OSX) {
479-
.lseek64(cast(int)file, offset, SEEK_SET);
480+
seekret = .lseek64(cast(int)file, offset, SEEK_SET);
480481
} else {
481-
.lseek(cast(int)file, offset, SEEK_SET);
482+
seekret = .lseek(cast(int)file, offset, SEEK_SET);
482483
}
483484

484485
scope (exit) {
485486
log("trigger event");
486487
files.m_events.trigger(files.m_readyEvent, true);
487488
}
488489

490+
if (seekret != offset) {
491+
safeAtomicStore(f.ioStatus, IOStatus.error);
492+
safeAtomicStore(f.bytesWritten, buffer.length - bytes.length);
493+
return;
494+
}
495+
489496
if (bytes.length == 0) safeAtomicStore(f.ioStatus, IOStatus.ok);
490497

491498
while (bytes.length > 0) {
492499
auto sz = min(bytes.length, 512*1024);
493500
auto ret = () @trusted { return mixin("."~op)(cast(int)file, bytes.ptr, cast(uint)sz); } ();
494501
if (ret != sz) {
495-
safeAtomicStore(f.ioStatus, IOStatus.error);
502+
IOStatus st;
503+
switch (errno) {
504+
default: st = ret < 0 ? IOStatus.error : IOStatus.readPastEOF; break;
505+
case EBADF, EINVAL: st = IOStatus.invalidHandle; break;
506+
case ENOSPC: st = IOStatus.noSpaceLeft; break;
507+
case EOPNOTSUPP: st = IOStatus.operationNotSupported; break;
508+
case EFBIG: st = IOStatus.tooLarge; break;
509+
case EIO: st = IOStatus.ioError; break;
510+
case EPERM: st = IOStatus.notAllowed; break;
511+
}
512+
513+
safeAtomicStore(f.ioStatus, st);
496514
log("error");
497515
break;
498516
}

source/eventcore/drivers/winapi/files.d

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
338338
return m_core.rawUserDataImpl(idToHandle(descriptor), size, initialize, destroy);
339339
}
340340

341+
import eventcore.internal.utils : print;
341342
private static void startIO(alias fun, bool RO)(HANDLE h, FileSlot.Direction!RO* slot)
342343
{
343344
import std.algorithm.comparison : min;
@@ -354,6 +355,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
354355
auto handler = &overlappedIOHandler!(onIOFinished!(fun, RO));
355356
if (!() @trusted { return fun(h, &slot.buffer[0], nbytes, &slot.overlapped.overlapped, handler); } ()) {
356357
slot.overlapped.driver.removeWaiter();
358+
print("ERR: %s", GetLastError());
357359
slot.invokeCallback(IOStatus.error, slot.bytesTransferred);
358360
}
359361
}
@@ -389,6 +391,7 @@ final class WinAPIEventDriverFiles : EventDriverFiles {
389391

390392
if (error != 0) {
391393
overlapped.driver.removeWaiter();
394+
print("AERR: %s", error);
392395
slot.invokeCallback(IOStatus.error, slot.bytesTransferred + bytes_transferred);
393396
return;
394397
}
@@ -423,3 +426,17 @@ private static struct CloseParams {
423426
CloseStatus status;
424427
WinAPIEventDriverCore core;
425428
}
429+
430+
private IOStatus toIOStatus(DWORD error)
431+
@safe pure nothrow @nogc {
432+
switch (error) {
433+
default: return IOStatus.error;
434+
case ERROR_INVALID_HANDLE: st = IOStatus.invalidHandle; break;
435+
case ERROR_HANDLE_DISK_FULL, ERROR_DISK_FULL: st = IOStatus.noSpaceLeft; break;
436+
case ERROR_NOT_SUPPORTED: st = IOStatus.operationNotSupported; break;
437+
case ERROR_FILE_TOO_LARGE: st = IOStatus.tooLarge; break;
438+
case ERROR_READ_FAULT, ERROR_WRITE_FAULT, ERROR_NET_WRITE_FAULT: st = IOStatus.ioError; break;
439+
case ERROR_WRITE_PROTECT, ERROR_SHARING_VIOLATION, ERROR_LOCK_VIOLATION: st = IOStatus.notAllowed; break;
440+
case ERROR_HANDLE_EOF: st = IOStatus.readPastEOF; break;
441+
}
442+
}

0 commit comments

Comments
 (0)