posix: implement missing directory functions#433
Conversation
There was a problem hiding this comment.
Summary of Changes
Hello @R4ken, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces three essential POSIX directory functions: fdopendir, seekdir, and telldir. These additions are crucial for improving the system's compatibility with POSIX standards, thereby simplifying the porting of various applications that rely on these common directory operations. The changes enhance the system's file system interaction capabilities without altering existing functionality.
Highlights
- New POSIX Directory Functions: Implemented
fdopendir,seekdir, andtelldirfunctions to provide more comprehensive POSIX-compliant directory manipulation capabilities. - Header Updates: Added declarations for the new directory functions in
include/dirent.h. - Core Logic Implementation: Provided the full implementation for
fdopendir,seekdir, andtelldirwithinunistd/dir.c, including necessary error handling and file descriptor management.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request implements the missing POSIX directory functions fdopendir, seekdir, and telldir. The implementations are a good start, but I've identified a few high-severity issues related to null pointer dereferences and error handling that could lead to crashes or undefined behavior. I've provided detailed comments and code suggestions to address these points, which also include a small efficiency improvement in fdopendir.
Unit Test Results10 553 tests 9 891 ✅ 52m 49s ⏱️ Results for commit 2aaa8f4. ♻️ This comment has been updated with latest results. |
| free(s); | ||
| return NULL; | ||
| } | ||
| if ((fd_flags & O_RDONLY) == 0) { |
There was a problem hiding this comment.
What if O_RDWR is set, so O_RDONLY is not? I think a file descriptor open for reading can be as well open for writing, as long as it is still readable
There was a problem hiding this comment.
open from libphoenix sets EISDIR on errno while opening directory with either O_WRONLY or O_RDWR flag.
Thus opening directory with O_RDWR is not possible
Fragment of open function from libphoenix
if (oflag & (O_WRONLY | O_RDWR)) {
if ((err = stat(filename, &st)) < 0) {
if (errno != ENOENT)
return err;
}
else if (S_ISDIR(st.st_mode)) {
return SET_ERRNO(-EISDIR);
}
}There was a problem hiding this comment.
This behaviour seems common, I can replicate it on both Linux and one of the BSD's, I think we can keep it like that for the sake of compatibility.
There was a problem hiding this comment.
Is fd_flags & O_RDONLY) == 0 idiomatic? WHat about use of O_ACCMODE? Should we assume that O_RDONLY, O_WRONLY, and O_RDWR are bitmasks (0x1, 0x2, 0x4)? Or they are an enumeration (0x0, 0x1, 0x2) to be checked with O_ACCMODE == 0x3? (I'm not asking about how we or Linux implement it, but what is the most portable way.)
There was a problem hiding this comment.
Addressed. Will create a new, linked PR in p-r-k.
There was a problem hiding this comment.
Also, this check would be a no-op in enum-like access modes. It seems that it is here in this version to check if any mode is set (as rdonly is the default), on most systems O_RDONLY is defined as 0, so it is implicitly a default and there is no need to check it here.
oI0ck
left a comment
There was a problem hiding this comment.
I'd be good to introduce NULL checks while we are at it.
| free(s); | ||
| return NULL; | ||
| } | ||
| if ((fd_flags & O_RDONLY) == 0) { |
There was a problem hiding this comment.
This behaviour seems common, I can replicate it on both Linux and one of the BSD's, I think we can keep it like that for the sake of compatibility.
| free(s); | ||
| return NULL; | ||
| } | ||
| if ((fd_flags & O_RDONLY) == 0) { |
There was a problem hiding this comment.
Is fd_flags & O_RDONLY) == 0 idiomatic? WHat about use of O_ACCMODE? Should we assume that O_RDONLY, O_WRONLY, and O_RDWR are bitmasks (0x1, 0x2, 0x4)? Or they are an enumeration (0x0, 0x1, 0x2) to be checked with O_ACCMODE == 0x3? (I'm not asking about how we or Linux implement it, but what is the most portable way.)
Most POSIX conformant/compilant operating systems seem to treat those values as enums, not bitfields. |
|
I removed the bitfield commit as it required further changes. The dependency graph on the WAMR PR grows too deep and if we make every issue which has come up a hard dependency, we won't merge it ever. |
|
|
|
Yes, it does but this is not the problem, and it is not related to tests, just a problem I noticed. We don't really need file descriptors here, My point is, with the way that we currently implement walking directory trees, In order for |
|
So my question here is, do we want to add a new syscall here or shall we leave this functionality as-is and correct it later, possibly after the release. |
|
Actually, this is a bit related to tests as it came out as an issue after I implemented a test for it :D |
|
POSIX states: “The file offset associated with the file descriptor at the time of the call determines which entries are returned.” So, the initial position of DIR should be set based on the file offset at the time of the My understanding is that subsequent |
|
You could also check how glibc implements this, but in my opinion updating the file descriptor’s offset is not required by POSIX. |
|
It is not required by POSIX, my point is that the state of the file descriptor for a directory will always be 0, so there is no need really to do an |
|
We can probably regard this as a quirk of our implementation right now, I'm preparing a p-r-docs PR for this change so I'll mention it there. |
|
If you mean calling Please check how glibc handles this case (passing descriptor with a non-zero offset to |
|
I checked OpenBSD sources, they do set the
Is performing a We also have an inconsistency here, because |
|
In this case, I think we might want to make |
|
Directories are files, so reading them is fine. I assume the difference between how
|
|
For |
|
Yep, I do have such test and it fails on RTOS, because we lack a way to report reading directories back to kernel. I'm almost sure it would work on Linux though, we'd have to move it by using I've looked through our filesystems source code and you are in fact right, I just think this behavour is confusing, semantically In the end, we can leave it as-is for now, maybe implementing |
|
@ziemleszcz I see that while I had compiled some tests of my own, there is already a larger PR for In the mean time, is this PR by itself clear to go in your opinion? |
add996d to
120dc42
Compare
Implement missing POSIX functions (fdopendir,seekdir, telldir) working on DIR structs JIRA: RTOS-1088 Co-developed-by: Michal Lach <michal.lach@phoenix-rtos.com>
Implement missing POSIX functions (fdopendir,seekdir, telldir) working on DIR structs
JIRA: RTOS-1088
Description
Implemented fdopendir,seekdir and telldir functions.
Motivation and Context
Missing POSIX functions useful in porting applications
Types of changes
How Has This Been Tested?
Checklist:
Special treatment