[m-rev.] diff: Don't allow directories to be opened as files in C grades.

Julien Fischer jfischer at opturion.com
Tue Sep 6 16:20:03 AEST 2016


Hi,

On Tue, 6 Sep 2016, Paul Bone wrote:

> Don't allow directories to be opened as files in C grades.
>
> Some OSs allow you fopen a directory, which could cause confusion.  This
> doesn't make sense for Mercury file streams so test for and raise an error
> when this happens.

....

> diff --git a/library/io.m b/library/io.m
> index 9e662c7..c0c562c 100644
> --- a/library/io.m
> +++ b/library/io.m

...

> +#if defined(MR_HAVE_FSTAT) && \
> +        (defined(MR_HAVE_FILENO) || defined(fileno)) && defined(S_ISDIR)
> +    /*
> +    ** AFAIK this is only useful on Linux and FreeBSD.

And OS X, and Cygwin ...

> So if we don't have
> +    ** fstat or fileno then fall back to just opening the file without this
> +    ** check.
> +    */
> +    if (0 != fstat(fileno(f), &stat_info)) {
> +        fclose(f);
> +        return NULL;
> +    }
> +    if (S_ISDIR(stat_info.st_mode)) {
> +        *is_dir = MR_TRUE;
> +        fclose(f);
> +        return NULL;
> +    }
> +#endif
> +
>     MR_incr_hp_type_msg(mf, MercuryFile, alloc_id, ""MercuryFile"");
>     MR_mercuryfile_init(f, 1, mf);
>     return mf;
> @@ -9593,10 +9627,17 @@ set_binary_output_stream(binary_output_stream(NewStream),
>     %
>     % Attempts to open a file in the specified mode.
>     % The Mode is a string suitable for passing to fopen().
> -    % Result is 0 for success, -1 for failure.
> +    % Result is
> +    %   0 -- success,
> +    %  -1 -- general failure,
> +    %  -2 -- failed because the file is a directory (C backends on some OSs)

This kind of thing is precisely why `pragma foreign_export_enum' was
added to the language.

Julien.


More information about the reviews mailing list