mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
libs/libc/dirent: preserve errno on readdir() end-of-directory
readdir() returned NULL at end-of-directory without ensuring errno was clean. POSIX requires errno to be unchanged at EOF, but the underlying read() path may leave a stale errno value. Callers that follow the POSIX idiom (set errno to 0 before the call, test it after a NULL return), such as readdir_r() and scandir(), then misread this as a readdir() failure. Save errno on entry and restore it on the end-of-directory return so that EOF no longer reports a spurious error, while genuine errors (read() returning a negative value) still propagate. Signed-off-by: yushuailong <yyyusl@qq.com>
This commit is contained in:
parent
e15672f7a4
commit
7e67d2d906
1 changed files with 13 additions and 1 deletions
|
|
@ -59,6 +59,7 @@
|
|||
|
||||
FAR struct dirent *readdir(DIR *dirp)
|
||||
{
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
if (!dirp)
|
||||
|
|
@ -67,11 +68,22 @@ FAR struct dirent *readdir(DIR *dirp)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Save errno so it can be restored on end-of-directory. POSIX requires
|
||||
* errno to be unchanged at EOF, but the read() path may not preserve it.
|
||||
*/
|
||||
|
||||
errcode = get_errno();
|
||||
|
||||
ret = read(dirp->fd, &dirp->entry, sizeof(struct dirent));
|
||||
if (ret <= 0)
|
||||
if (ret == 0)
|
||||
{
|
||||
set_errno(errcode); /* EOF: restore errno (not an error) */
|
||||
return NULL;
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
return NULL; /* error: read() already set errno */
|
||||
}
|
||||
|
||||
return &dirp->entry;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue