diff --git a/libs/libc/dirent/lib_readdir.c b/libs/libc/dirent/lib_readdir.c index 80c587ea8d6..3b2136bca70 100644 --- a/libs/libc/dirent/lib_readdir.c +++ b/libs/libc/dirent/lib_readdir.c @@ -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; }