[Ohrrpgce] rewriting isdir() function

Ralph Versteegen teeemcee at gmail.com
Thu Jul 30 22:24:15 PDT 2015


On 31 July 2015 at 03:38, James Paige <Bob at hamsterrepublic.com> wrote:

> While I was messing around trying to figure out what was going on during
> my kernel error crisis, I noticed the current implementation of the isdir()
> function:
>
> FUNCTION isdir (sDir as string) as integer
>   dim ret as bool
> #IFDEF __FB_ANDROID__
>   '[ does not work in Android 2.2. I don't know how reliable this is
>   ret = SHELL("ls " + escape_filename(sDir) + "/") = 0
> #ELSEIF DEFINED(__UNIX__)
>   'Special hack for broken Linux dir() behavior
>   '(FIXME: is DIR still broken? Should investigate)
>   ret = SHELL("[ -d " + escape_filename(sDir) + " ]") = 0
> #ELSE
>   'Windows just uses dir (ugh)
>   'Have to remove trailing slash, otherwise dir always returns nothing
>   dim temp as string = rtrim(sdir, any "\/")
>   ret = dir(temp, 55) <> "" AND dir(temp, 39) = ""
> #ENDIF
> #IFDEF DEBUG_FILE_IO
>   debuginfo "isdir(" & sDir & ") = " & ret
> #ENDIF
>   return ret
> END FUNCTION
>
> It has three different platform specific code-paths, and all of them seem
> pretty dang hacky.
>
> I realized that a C implementation of the same function would probably be
> relatively simple, and might even be the same across all four supported
> platforms.
>
> After googling around a bit, I came up with something, but my C legs are
> pretty shakey, so I was hoping somebody else could look at it before I go
> and further along this path, especially if this implementation does
> something dumb that I am missing or would not work on one of our platforms
>
> int isdir(const char *dirname)
> {
>        struct stat sb;
>
>        if (stat(dirname, &sb) == 0 && S_ISDIR(sb.st_mode)) {
>                return 1;
>        }
>        return 0;
> }
>
> I am also unsure which c source file is the right place to put this. Is
> miscc.c the right place?
>
> It requires:
>
> #include <sys/stat.h>
> #include <stdio.h>
>
> neither of which is currently included in miscc.c right now, and I have no
> idea if sys.stat.h is a unix-only thing or not.
>
> ---
> James
>

It's probably about time that that was replaced, especially since the C
equivalent is so simple.

That is unix-specific code, so should probably go in os_unix.c. Also, when
calling POSIX functions I prefer to take a look at Apple's man page for
them because there are always differences, however there wasn't anything
relevant in this case.

I suggest checking for and printing errors:

int isdir(const char *dirname)
{
    struct stat sb;

    if (stat(dirname, &sb)) {
        // Ignore "A component of pathname does not exist, or pathname is
an empty string."
        if (errno != ENOENT)
            debug(errError, "isdir(%s) error: %s", dirname,
strerror(errno));
        return 0;
    } else
        return S_ISDIR(sb.st_mode);
}

However Windows also tends to have versions of these sorts of POSIX
functions, though it seems it is called _stat on Windows:
https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx
Mingw also tends to define additional unix compatibility functions. In this
case it looks like stat() is defined as an alias for _stat(). So try it
out, if it works you can just use a single implementation and put it in
miscc.c.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.motherhamster.org/pipermail/ohrrpgce-motherhamster.org/attachments/20150731/c7bbfeb2/attachment.htm>


More information about the Ohrrpgce mailing list