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.
|
|
||
| long telldir(DIR *dirp) | ||
| { | ||
| return dirp->pos; |
There was a problem hiding this comment.
No, this behavior exists in Linux, POSIX does not specify it
There was a problem hiding this comment.
Please look carefully at the condition.
Also, I agree that POSIX does not specify how to report the error, but: should we deviate from the "common" errno setting, as is the case with other directory functions in this file? We don't even have this function documented in p-r-doc, so using an approach other than errno seems counter-intuitive. Please either use errno or make a PR to p-r-doc (which will eventually be needed, though).
Unit Test Results8 533 tests - 1 020 8 006 ✅ - 955 46m 59s ⏱️ - 5m 33s Results for commit 7647476. ± Comparison against base commit 74852cb. This pull request removes 1020 tests.♻️ This comment has been updated with latest results. |
unistd/dir.c
Outdated
| 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.
|
|
||
| long telldir(DIR *dirp) | ||
| { | ||
| return dirp->pos; |
unistd/dir.c
Outdated
| 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.
unistd/dir.c
Outdated
| int ret = 0; | ||
|
|
||
| if (dirp != NULL) { | ||
| return -EBADF; |
There was a problem hiding this comment.
So, only dirp == NULL is allowed to proceed?
The same case in telldir()
|
|
||
| extern void seekdir(DIR *dirp, long loc); | ||
|
|
||
| extern long telldir(DIR *dirp); |
There was a problem hiding this comment.
Keep two empty lines between function prototypes.
include/dirent.h
Outdated
There was a problem hiding this comment.
For some reason, s is used as a parameter name instead of dirp. Maybe make it consistent now, if you make changes to these functions already?
| if (msg.o.err < 0) { | ||
| free(s->dirent); | ||
| s->dirent = NULL; | ||
| return NULL; |
There was a problem hiding this comment.
As per POSIX:
Upon successful completion, readdir() shall return a pointer to an object of type struct dirent. When an error is encountered, a null pointer shall be returned and errno shall be set to indicate the error. When the end of the directory is encountered, a null pointer shall be returned and errno is not changed.
Discriminating between the end of the directory and errors seems to rely on checking the value of errno while readdir() returns NULL. If so, it makes sense to set errno in all cases when an error occurs - i.e. when:
calloc()above fails,msgSend()above fails - there is a comment aboutEIO, but it is not assigned toerrno!);msgSend()only returns error codes, it does not seterrno,msg.o.err < 0, soerrno = -msg.o.errhere? Orerrno = EIO, but I think returning an actual error code from the same abstraction layer (a filesystem server) is nice, especially for debugging.
If you already make changes to error reporting in this already-existing function, then please do so fully.
There was a problem hiding this comment.
I think we should differentiate between cases when we reach end of directory stream (with err set to -ENOENT) and cases when we return any other errors; errno should be only modified in latter case.
This imposes a requirement on our filesystem implementations to adhere to this behaviour (to return -ENOENT on end of dirstream), which is true for ext2 at least, not sure about other filesystems.
There was a problem hiding this comment.
Addressed.
As far as I checked, most of our filesystems return -ENOENT on reaching the end of dirstream, with the exception of JFFS2. I'll create and link a new pr in p-r-fs
|
|
||
| long telldir(DIR *dirp) | ||
| { | ||
| return dirp->pos; |
There was a problem hiding this comment.
Please look carefully at the condition.
Also, I agree that POSIX does not specify how to report the error, but: should we deviate from the "common" errno setting, as is the case with other directory functions in this file? We don't even have this function documented in p-r-doc, so using an approach other than errno seems counter-intuitive. Please either use errno or make a PR to p-r-doc (which will eventually be needed, though).
unistd/dir.c
Outdated
| 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. |
Implement missing POSIX functions (fdopendir,seekdir, telldir) working on DIR structs JIRA: RTOS-1088
JIRA: RTOS-1088
JIRA: RTOS-1088
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