On 21 March 2018 at 22:28, monty <monty2@programmer.net> wrote:
>
>
> The SQ_FILE_*_ERROR codes can be mapped directly to an expanded file exception hierarchy, so an appropriate exception class can be thrown (and caught) on failure. #primitiveFailForOSError: can be used for this. Or it can be used with the raw errno/GetLastError() codes, and a sqFileErrorCodeFromSystemErrorCode()-based primitive can be used after to map it.
>
> The exact values of the errno.h E* defines are technically unspecified,

By "unspecified" do you just mean that they are different between platforms.
What about embedding  errno.h  in the compiled VM and let the Image side browse and parse it, so the error mapping/condensing can be done Image-side?
I'm not sure of the difficulty to do this since I haven't done it before,
but maybe something like...  https://stackoverflow.com/questions/410980/include-a-text-file-in-a-c-program-as-a-char


> We need some way in-image to portably, correctly distinguish certain failure modes (like a file not existing) from others. (Code in the current Squeak image just guesses.)

This should(?) portably provide the exact C label for a numeric error.  
The Image-side might need per-platform mapping/condensing, but still may be nicer to do it there.

cheers -ben

 
>
> and the perror()/strerror_r() messages are locale-specific: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_03
>
> I would like to hear more ideas.
>
> > Sent: Wednesday, March 21, 2018 at 7:08 AM
> > From: "Alistair Grant" <akgrant0710@gmail.com>
> > To: "Squeak Virtual Machine Development Discussion" <vm-dev@lists.squeakfoundation.org>
> > Subject: Re: [Vm-dev] [PATCH] added FilePlugin error code lookup function
> >
> >
> > 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:
> > >
> > >
> > > +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
> > > +};
> > > 
> > > +
> > > +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