Hi Monty,
The VM has a primitive failure that allows the OS error to be returned: #primitiveFailForOSError:
Why not simply return the OS error and allow the image to deal with it?
Cheers, Alistair
On 21 March 2018 at 07:52, monty monty2@programmer.net wrote:
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 */
2.11.0