smuehlst / circle-stdlib

Standard C and C++ Library Support for Circle
GNU General Public License v3.0
90 stars 17 forks source link

There should be a concept of 'current directory' #28

Closed kevinboone closed 1 year ago

kevinboone commented 1 year ago

I don't think that circle-stdlib has any concept of 'current directory'. There is no implementation of chdir() for example. This is a problem for the same reason that the lack of dup/dup2 I reported earlier is a problem -- I want to use libraries that use these calls.

It probably wouldn't be hugely difficult to implement the missing support. Most functions in the standard C library that handle files ultimately end up in a call to open(). I think the relevant implementation is here:

llibs/circle-newlib/libgloss/arm/syscalls.c

However, there are plenty of other calls scattered throughout the library -- opendir(), rename(), etc., which would also have to be changed.

I suspect this is a lot of work, and I don't really understand the implementation of circle-stdlib well enough to do it myself :/

smuehlst commented 1 year ago

Like with dup() mentioned in #27 this is on of the known gaps in circle-stdlib, and you are the first to complain about it. To set expectations correctly, I can't spend much time on this project currently, and I haven't yet thought about how the concept of a current directory could be implemented.

I think the relevant implementation is here:

llibs/circle-newlib/libgloss/arm/syscalls.c

Not quite, it is in the subdirectory libgloss/circle in the circle-newlib repository:

https://github.com/smuehlst/circle-newlib/tree/circle-newlib/libgloss/circle

kevinboone commented 1 year ago

Thanks for the quick reply and, for the record, I'm not complaining at all :) Please don't feel pressured to do any work, if I'm the only person who has asked for this feature. If I have time, I'll try to implement it myself.

rsta2 commented 1 year ago

There is a solution for this issue here. It implements the functions chdir() and getcwd(). You have to call myinit() somewhere in your initialization. It requires this patch applied to the /libs/circle submodule to enable the relative path support in the underlying FatFs library. This patch has already been applied on the develop branch of the Circle project.

smuehlst commented 1 year ago

There is a solution for this issue here.

Oh, chdir() looks quite easy to implement. I had thought that it would be necessary to implement the current directory support in circle-newlib. If it is so easy, then I will include it in the upcoming release, which I now plan to do over the coming weekend.

kevinboone commented 1 year ago

It never occurred to me that FATFS had its own concept of directory. I guess it would be easiest to make use of that facility, so long as FAT is the only supported filesystem. Thanks -- I look forward to testing this in due course.

smuehlst commented 1 year ago

@kevinboone chdir() and getcwd() have been implemented on the develop branch as of commit 8911e764223cbcedba8da7c3ad13b9e82a2214fe. Please give it a try and let me know whether there are any problems. Before this can appear in a new release on the master branch, @rsta2 needs to make a new release of Circle itself, as there are depencies regarding FatFs for this implementation.

rsta2 commented 1 year ago

I have tested chdir() and getcwd() with SQLite. chdir() does work, but there is a problem with getcwd(). It returns something like "SD:/sqlite" and unfortunately SQLite cannot handle the drive prefix. That's why I removed this prefix in my own implementation of getcwd().

There will be a new hotfix release of Circle this week, which will include the necessary patch for enabling the relative path support in FatFs.

smuehlst commented 1 year ago

I have tested chdir() and getcwd() with SQLite. chdir() does work, but there is a problem with getcwd(). It returns something like "SD:/sqlite" and unfortunately SQLite cannot handle the drive prefix. That's why I removed this prefix in my own implementation of getcwd().

Ok, I can implement that as well. I had thought that this would be a restriction when multiple partitions are present, but I guess that is unlikely.

rsta2 commented 1 year ago

Yes, it is. I think getcwd() can be implemented in a way, that it checks, if the drive prefix exists. If so, it will be removed, otherwise the directory path remains unchanged. One can search for the first slash in the buffer for example and remove all characters in front of it.

rsta2 commented 1 year ago

Circle 45.1 is available. It includes the patch to enable the relative path support in the FatFs library.

smuehlst commented 1 year ago

circle-stdlib v16 has been released where chdir() and getcwd() are implemented.

rsta2 commented 1 year ago

I have updated and tested SQLite with circle-stdlib v16. It works well. :)

kevinboone commented 1 year ago

I've checked chdir() and getcwd() and they seem to work fine. I was pleased to find that constructions like 'chdir("..")' and 'opendir ("./foo")' work fine.

It would be nice -- but probably difficult -- if the concept of 'current directory' extended to multiple partitions on the same SD card. In fact, I don't know whether Circle itself supports multiple partitions. ChaN's FATFS driver does support multiple partitions -- I think they are identified by numbers. But mapping these onto POSIX-style filenames is rather awkward, as I've found out from other projects.

But if circle-stdlib supported mutliple partitions, then a separate partition could be used for the boot firmware and kernel, and a different partition for data.

This is not a show-stopper for me: I'm quite happy to use a single partition. But it might be nice.

Thanks, anyway.

smuehlst commented 1 year ago

I did not think about mounting multiple partitions, and I dont't know how complicated it would be with FatFs. I took a quick lock at the f_mount() documentation of FatFs:

http://elm-chan.org/fsw/ff/doc/mount.html

I guess that applications using circle-stdlib expect absolute pathnames to start with a '/'. FatFs prepends partition names with a ':' prefix before the absolute path name on the partition. Maybe a scheme would be possible to transform the partition names into directories under the root directory. This would require to modify all file-system-related functions that accept path names and add some kind of translation.

kevinboone commented 1 year ago

Yes, I know from experience that the way FatFS handles partitions is difficult to integrate into anything Unix-like. I recall that FatFs understands pathnames of the form "1:/foo"; that is, I think it uses numbers as partition labels. Perhaps it can use letters as well -- I can't remember.

In the past, I've just adapted my code so I can use "N:/foo" pathnames. But then any code that parses Unix-style pathnames has to be modified, which is a drag.

The elegant way to handle this would be for circle-stdlib to understand pathnames of the form

/partition1/foo

and convert the '/partition1' part to a number for FatFs. It would still be really tedious to implement, but at least the pathnames would look sensible. For now, I just create a directory on the SD card and put all my data in it, and accept that the 'root' directory is full of system stuff, and can't be used. This works well enough for my purposes.