--- platforms/Cross/plugins/FilePlugin/FilePlugin.h | 17 ++++++ .../plugins/FilePlugin/sqFilePluginBasicPrims.c | 56 ++++++++++++++++++ .../win32/plugins/FilePlugin/sqWin32FilePrims.c | 69 ++++++++++++++++++++++ 3 files changed, 142 insertions(+)
diff --git a/platforms/Cross/plugins/FilePlugin/FilePlugin.h b/platforms/Cross/plugins/FilePlugin/FilePlugin.h index 13e7b7ce9..5d61733a0 100644 --- a/platforms/Cross/plugins/FilePlugin/FilePlugin.h +++ b/platforms/Cross/plugins/FilePlugin/FilePlugin.h @@ -44,6 +44,21 @@ typedef struct { #endif } SQFile;
+enum { + SQ_FILE_ERROR, + SQ_FILE_PERMISSION_ERROR, + SQ_FILE_ALREADY_EXISTS_ERROR, + SQ_FILE_DOES_NOT_EXIST_ERROR, + SQ_FILE_RESOURCE_LIMIT_ERROR, + SQ_FILE_INVALID_OPERATION_ERROR, + SQ_FILE_IO_ERROR, + SQ_FILE_BAD_HANDLE_ERROR, + SQ_FILE_IS_DIRECTORY_ERROR, + SQ_FILE_IS_NOT_DIRECTORY_ERROR, + SQ_FILE_INVALID_NAME_ERROR, + SQ_FILE_IN_PROGRESS_ERROR +}; + /* file i/o */
sqInt sqFileAtEnd(SQFile *f); @@ -67,6 +82,8 @@ sqInt sqFileSync(SQFile *f); sqInt sqFileTruncate(SQFile *f,squeakFileOffsetType offset); sqInt sqFileThisSession(void); sqInt sqFileStdioHandlesInto(SQFile files[3]); +sqInt sqFileErrorCodeFromSystemErrorCode(sqInt errorCode); +
/* directories */
diff --git a/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c b/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c index 48117181f..803ad5b8a 100755 --- a/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c +++ b/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c @@ -754,4 +754,60 @@ sqInt sqFileThisSession() { return thisSession; } + +sqInt +sqFileErrorCodeFromSystemErrorCode(sqInt errorCode) +{ + /* A switch statement is avoided, since some error codes, like EAGAIN/EWOULDBLOCK, can + overlap, and EINTR is not propagated as SQ_FILE_IN_PROGRESS_ERROR, since it should be + handled internally where possible and because only certain operations can be safely + reattempted after failing with EINTR + */ + if (errorCode == EACCES + || errorCode == EPERM + || errorCode == EROFS) + return SQ_FILE_PERMISSION_ERROR; + else if (errorCode == EEXIST) + return SQ_FILE_ALREADY_EXISTS_ERROR; + else if (errorCode == ENOENT + || errorCode == ENODEV + || errorCode == ENXIO) + return SQ_FILE_DOES_NOT_EXIST_ERROR; + else if (errorCode == EDQUOT + || errorCode == EFBIG + || errorCode == EMFILE + || errorCode == EMLINK + || errorCode == ENFILE + || errorCode == ENOLCK + || errorCode == ENOLINK + || errorCode == ENOMEM + || errorCode == ENOSPC) + return SQ_FILE_RESOURCE_LIMIT_ERROR; + else if (errorCode == EINVAL + || errorCode == ENOTTY + || errorCode == ENOSYS + || errorCode == ENOTEMPTY + || errorCode == EFAULT + || errorCode == ESPIPE + || errorCode == EXDEV) + return SQ_FILE_INVALID_OPERATION_ERROR; + else if (errorCode == EIO) + return SQ_FILE_IO_ERROR; + else if (errorCode == EBADF) + return SQ_FILE_BAD_HANDLE_ERROR; + else if (errorCode == EISDIR) + return SQ_FILE_IS_DIRECTORY_ERROR; + else if (errorCode == ENOTDIR) + return SQ_FILE_IS_NOT_DIRECTORY_ERROR; + else if (errorCode == ENAMETOOLONG + || errorCode == ELOOP) + return SQ_FILE_INVALID_NAME_ERROR; + else if (errorCode == EAGAIN + || errorCode == EWOULDBLOCK + || errorCode == EINPROGRESS) + return SQ_FILE_IN_PROGRESS_ERROR; + else + return SQ_FILE_ERROR; +} + #endif /* NO_STD_FILE_SUPPORT */ diff --git a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c index 39ae4ec15..1e7d80782 100644 --- a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c +++ b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c @@ -528,4 +528,73 @@ squeakFileOffsetType sqImageFileSize(sqImageFile h) return ofs.offset; }
+sqInt +sqFileErrorCodeFromSystemErrorCode(sqInt errorCode) +{ + /* Newer constants are avoided for backwards compatibility */ + if (errorCode == ERROR_ACCESS_DENIED + || errorCode == ERROR_FILE_READ_ONLY + || errorCode == ERROR_WRITE_PROTECT + || errorCode == 313) /* ERROR_NOT_ALLOWED_ON_SYSTEM_FILE */ + return SQ_FILE_PERMISSION_ERROR; + else if (errorCode == ERROR_FILE_EXISTS + || errorCode == ERROR_ALREADY_EXISTS) + return SQ_FILE_ALREADY_EXISTS_ERROR; + else if (errorCode == ERROR_FILE_NOT_FOUND + || errorCode == ERROR_PATH_NOT_FOUND + || errorCode == ERROR_DEV_NOT_EXIST) + return SQ_FILE_DOES_NOT_EXIST_ERROR; + else if (errorCode == ERROR_NO_MORE_FILES + || errorCode == ERROR_TOO_MANY_OPEN_FILES + || errorCode == ERROR_DISK_FULL + || errorCode == ERROR_HANDLE_DISK_FULL + || errorCode == ERROR_DISK_TOO_FRAGMENTED + || errorCode == ERROR_NO_MORE_SEARCH_HANDLES + || errorCode == ERROR_NOT_ENOUGH_QUOTA + || errorCode == 223 /* ERROR_FILE_TOO_LARGE */ + || errorCode == 314 /* ERROR_DISK_RESOURCES_EXHAUSTED */ + || errorCode == 322 /* ERROR_DEVICE_NO_RESOURCES */ + || errorCode == 331) /* ERROR_TOO_MANY_DESCRIPTORS */ + return SQ_FILE_RESOURCE_LIMIT_ERROR; + else if (errorCode == ERROR_WRITE_FAULT + || errorCode == ERROR_READ_FAULT + || errorCode == ERROR_OPERATION_ABORTED + || errorCode == ERROR_CANNOT_MAKE + || errorCode == ERROR_IO_DEVICE) + return SQ_FILE_IO_ERROR; + else if (errorCode == ERROR_INVALID_FUNCTION + || errorCode == ERROR_BAD_ARGUMENTS + || errorCode == ERROR_INVALID_PARAMETER + || errorCode == ERROR_NOT_SUPPORTED + || errorCode == ERROR_NEGATIVE_SEEK + || errorCode == ERROR_SEEK_ON_DEVICE + || errorCode == ERROR_CURRENT_DIRECTORY + || errorCode == ERROR_DIR_NOT_EMPTY) + return SQ_FILE_INVALID_OPERATION_ERROR; + else if (errorCode == ERROR_INVALID_HANDLE + || errorCode == ERROR_INVALID_TARGET_HANDLE + || errorCode == ERROR_DIRECT_ACCESS_HANDLE + || errorCode == ERROR_OPEN_FAILED + || errorCode == ERROR_DELETE_PENDING + || errorCode == 321) /* ERROR_DEVICE_UNREACHABLE */ + return SQ_FILE_BAD_HANDLE_ERROR; + else if (errorCode == 336) /* ERROR_DIRECTORY_NOT_SUPPORTED */ + return SQ_FILE_IS_DIRECTORY_ERROR; + else if (errorCode == 334 /* ERROR_RESIDENT_FILE_NOT_SUPPORTED */ + || errorCode == 335) /* ERROR_COMPRESSED_FILE_NOT_SUPPORTED */ + return SQ_FILE_IS_NOT_DIRECTORY_ERROR; + else if (errorCode == ERROR_INVALID_NAME + || errorCode == ERROR_DIRECTORY + || errorCode == ERROR_BAD_PATHNAME + || errorCode == ERROR_FILENAME_EXCED_RANGE + || errorCode == 305 /* ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME */ + || errorCode == 330) /* ERROR_BAD_DEVICE_PATH */ + return SQ_FILE_INVALID_NAME_ERROR; + else if (errorCode == ERROR_IO_PENDING + || errorCode == ERROR_IO_INCOMPLETE) + return SQ_FILE_IN_PROGRESS_ERROR; + else + return SQ_FILE_ERROR; +} + #endif /* WIN32_FILE_SUPPORT */