dlbeer/ufat

More "traditional" API?

FreddieChopin opened this issue · 4 comments

Hi!

I was wondering whether it would be possible and easy to add a more traditional API to your project? Generally something to open a file/dir with just a path, instead of having to search the path to get dirent and then use this dirent to open the file. Something which easily maps to typical POSIX functions open()/close()/read()/write()/seek() and so on. For example something similar to littlefs?

I'm looking for a FAT library to integrate in my C++ RTOS (github repo) and FatFS seems like a logical, battle-tested candidate, but it has this inconvenience, that when multiple filesystems are opened you have to manipulate them via names (which uses global state) instead of using objects, so this does not map well to an object-oriented design. You also have to #define how many of them will you use. In mbed they integrated FatFS into their filesystem API, but using a lot of trickery and dynamic memory (see here), which I would like to avoid and here is where I noticed your project which avoids this problem (;

Thanks in advance for the answer!

Hi again!

First of all - thanks for a quick answer!

You could implement a small wrapper function in your application to call ufat_open_root() and then ufat_dir_find_path(). Would that suffice for opening a file by its full name?

I guess that it would be possible, but this gets trickier when you try to implement all the POSIX flags required for open(): creation, exclusive creation, opening for read-only, opening for write-only, writing in append mode, ... So I was hoping that internally the API is more traditional and it could be used directly, instead of adding this complex logic in wrappers.

See here:
http://pubs.opengroup.org/onlinepubs/9699919799/
Some of the flags are not meaningful for a "real" file system, but these should be supported (in all allowed combinations): O_RDONLY, O_RDWR, O_WRONLY, O_APPEND, O_CREAT, maybe also O_EXCL and O_TRUNC.

The main issue is that integrating your library with a framework which expects a stdio-like or POSIX-like interface (for example newlib or typical RTOS) is much harder than it could be (;

I did not study the internals of your code (yet), so I don't know whether the API you implemented comes from the design of FAT file system or maybe some other reason was deciding here (existing project, external API requirements, personal preference, ...). If the real design of FAT file system fits closely with stdio/POSIX then my main concern would be that your project's API adds some complexity on top of FAT's natural API and the wrappers would add another layer of complexity, when in reality neither one of them is required at all.

Thus I'm asking whether it would be possible and easy to modify your project to use stdio/POSIX API as the main API, directly and with no wrappers (or "as directly as possible"). It would just be a lot easier to integrate your project with other libraries.

Looking forward to your opinion (;

I've integrated uFAT into distortos using my own wrappers. There are a couple of things which could be improved and not everything was tested yet, but it generally seems to work fine.

In case anyone is interested:
https://github.com/DISTORTEC/distortos/blob/master/source/FileSystem/FAT/FatFileSystem.cpp
https://github.com/DISTORTEC/distortos/blob/master/source/FileSystem/FAT/FatFile.cpp
https://github.com/DISTORTEC/distortos/blob/master/source/FileSystem/FAT/FatDirectory.cpp