devkitPro / libfat

FAT library for GBA, DS, Gamecube & Wii
http://devkitpro.org/viewforum.php?f=24
54 stars 36 forks source link

Pathname with or without trailing slashes for directories #7

Open FrankHB opened 8 years ago

FrankHB commented 8 years ago

Pathname resolution is not conforming to POSIX: Trailing slashes lead to problems. The function _FAT_directory_entryFromPath as well as _FAT_diropen_r does not always handle path "foo" as same as "foo/", which should be all the same to "foo/." according to the specification. In particular, this causes opendir("fat:") to fail accessing the root directory. There might be similar problems for other functions (not tested).

Since POSIX does not handle root name of paths, this should be work around separately, or at least provide documented behavior. It seems better to accept opendir("fat:") as other platforms, to save the portability work reasonably. Note that opendir("C:") should work with MinGW-w64.

WinterMute commented 8 years ago

what does opendir("C:") do on windows, do you know offhand. Does it open root or does it open current working directory.

FrankHB commented 8 years ago

As I tested with x86_64-w64-mingw32-gcc (from MSYS2) in Windows 10, opendir("C:") opens the root directory of drive "C:".

Note that using x86_64-pc-msys-gcc (also from MSYS2) it opens the root directory successfully with opendir("C:\\") but failed with opendir("C:"). This is expected because MSYS2 programs as well as Cygwin programs need POSIX-style paths except for several cases (including C:\ but not C:)where they can be recognized and converted by the MSYS/Cygwin runtime to the POSIX paths.

WinterMute commented 8 years ago

Did you try chdir before an opendir though?

WinterMute commented 8 years ago

Yeah, thought so. I just checked this and the behaviour is what I expected.

On windows opendir("c:") will open the current working directory on the drive, not the root directory. You get the same sort of behaviour with chdir too in that chdir("c:") will change working directory to the last working directory set on drive C. This isn't something I really considered supporting in libfat since, for most purposes, there's only a single storage device.

Being honest it was never intended that code using libfat should ever use the pseudo drive specifier explicitly in any path. That's obviously not portable.

I'll have a look at the trailing slash thing though.

FrankHB commented 8 years ago

Sorry, my mistake. The tests were run weeks ago, and I did not call chdir then. It indeed opens the current working directory.

Thank your for clarifying the support status.

Regarding the drive specifier, it is indeed not portable in hard-coded arguments. But it can still be portable in a limited form using string concatenation, provided routines to get different path prefix (maybe at runtime) for different platforms. Many Win32 APIs supports slashes as well as backslashes in paths, this makes backslashes conversion not required; though actually I have them, or even processing the paths in vectors of strings in high level APIs by default so they are without explicit separators. I hit the problem by translating the high level representation to a string (without trailing slash) and passing it to the low-level API, whose implementation calls opendir in DS (and several other POSIX-compliant platforms). Now it works because I had eventually reimplemented my own FAT routines, with hack for this specific situation. Perhaps I should change the the low-level implementation again...