1 Star 0 Fork 147

wanghongliang/glibc

forked from src-openEuler/glibc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Linux-Do-not-skip-d_ino-0-entries-in-readdir-readdir.patch 6.88 KB
一键复制 编辑 原始数据 按行查看 历史
From 766b73768b290b303f5b56268c6c0d588d5a9267 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 19 Sep 2022 08:10:41 +0200
Subject: [PATCH] Linux: Do not skip d_ino == 0 entries in readdir, readdir64
(bug 12165)
POSIX does not say this value is special. For example, old XFS file
systems may still use inode number zero.
Also update the comment regarding ENOENT. Linux may return ENOENT
for some file systems.
---
sysdeps/unix/sysv/linux/readdir.c | 57 +++++--------
sysdeps/unix/sysv/linux/readdir64.c | 120 +++++++++++-----------------
2 files changed, 69 insertions(+), 108 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c
index c31f349639..c9a04dc160 100644
--- a/sysdeps/unix/sysv/linux/readdir.c
+++ b/sysdeps/unix/sysv/linux/readdir.c
@@ -28,48 +28,33 @@ __readdir_unlocked (DIR *dirp)
struct dirent *dp;
int saved_errno = errno;
- do
+ if (dirp->offset >= dirp->size)
{
- size_t reclen;
+ /* We've emptied out our buffer. Refill it. */
- if (dirp->offset >= dirp->size)
+ size_t maxread = dirp->allocation;
+ ssize_t bytes;
+
+ bytes = __getdents (dirp->fd, dirp->data, maxread);
+ if (bytes <= 0)
{
- /* We've emptied out our buffer. Refill it. */
-
- size_t maxread = dirp->allocation;
- ssize_t bytes;
-
- bytes = __getdents (dirp->fd, dirp->data, maxread);
- if (bytes <= 0)
- {
- /* On some systems getdents fails with ENOENT when the
- open directory has been rmdir'd already. POSIX.1
- requires that we treat this condition like normal EOF. */
- if (bytes < 0 && errno == ENOENT)
- bytes = 0;
-
- /* Don't modifiy errno when reaching EOF. */
- if (bytes == 0)
- __set_errno (saved_errno);
- dp = NULL;
- break;
- }
- dirp->size = (size_t) bytes;
-
- /* Reset the offset into the buffer. */
- dirp->offset = 0;
+ /* Linux may fail with ENOENT on some file systems if the
+ directory inode is marked as dead (deleted). POSIX
+ treats this as a regular end-of-directory condition, so
+ do not set errno in that case, to indicate success. */
+ if (bytes == 0 || errno == ENOENT)
+ __set_errno (saved_errno);
+ return NULL;
}
+ dirp->size = (size_t) bytes;
- dp = (struct dirent *) &dirp->data[dirp->offset];
-
- reclen = dp->d_reclen;
-
- dirp->offset += reclen;
-
- dirp->filepos = dp->d_off;
+ /* Reset the offset into the buffer. */
+ dirp->offset = 0;
+ }
- /* Skip deleted files. */
- } while (dp->d_ino == 0);
+ dp = (struct dirent *) &dirp->data[dirp->offset];
+ dirp->offset += dp->d_reclen;
+ dirp->filepos = dp->d_off;
return dp;
}
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
index e876d84b02..7952da5c27 100644
--- a/sysdeps/unix/sysv/linux/readdir64.c
+++ b/sysdeps/unix/sysv/linux/readdir64.c
@@ -37,48 +37,36 @@ __readdir64 (DIR *dirp)
__libc_lock_lock (dirp->lock);
#endif
- do
+ if (dirp->offset >= dirp->size)
{
- size_t reclen;
+ /* We've emptied out our buffer. Refill it. */
- if (dirp->offset >= dirp->size)
+ size_t maxread = dirp->allocation;
+ ssize_t bytes;
+
+ bytes = __getdents64 (dirp->fd, dirp->data, maxread);
+ if (bytes <= 0)
{
- /* We've emptied out our buffer. Refill it. */
-
- size_t maxread = dirp->allocation;
- ssize_t bytes;
-
- bytes = __getdents64 (dirp->fd, dirp->data, maxread);
- if (bytes <= 0)
- {
- /* On some systems getdents fails with ENOENT when the
- open directory has been rmdir'd already. POSIX.1
- requires that we treat this condition like normal EOF. */
- if (bytes < 0 && errno == ENOENT)
- bytes = 0;
-
- /* Don't modifiy errno when reaching EOF. */
- if (bytes == 0)
- __set_errno (saved_errno);
- dp = NULL;
- break;
- }
- dirp->size = (size_t) bytes;
-
- /* Reset the offset into the buffer. */
- dirp->offset = 0;
+ /* Linux may fail with ENOENT on some file systems if the
+ directory inode is marked as dead (deleted). POSIX
+ treats this as a regular end-of-directory condition, so
+ do not set errno in that case, to indicate success. */
+ if (bytes == 0 || errno == ENOENT)
+ __set_errno (saved_errno);
+#if IS_IN (libc)
+ __libc_lock_unlock (dirp->lock);
+#endif
+ return NULL;
}
+ dirp->size = (size_t) bytes;
- dp = (struct dirent64 *) &dirp->data[dirp->offset];
-
- reclen = dp->d_reclen;
-
- dirp->offset += reclen;
-
- dirp->filepos = dp->d_off;
+ /* Reset the offset into the buffer. */
+ dirp->offset = 0;
+ }
- /* Skip deleted files. */
- } while (dp->d_ino == 0);
+ dp = (struct dirent64 *) &dirp->data[dirp->offset];
+ dirp->offset += dp->d_reclen;
+ dirp->filepos = dp->d_off;
#if IS_IN (libc)
__libc_lock_unlock (dirp->lock);
@@ -115,48 +103,36 @@ __old_readdir64 (DIR *dirp)
__libc_lock_lock (dirp->lock);
#endif
- do
+ if (dirp->offset >= dirp->size)
{
- size_t reclen;
+ /* We've emptied out our buffer. Refill it. */
- if (dirp->offset >= dirp->size)
+ size_t maxread = dirp->allocation;
+ ssize_t bytes;
+
+ bytes = __old_getdents64 (dirp->fd, dirp->data, maxread);
+ if (bytes <= 0)
{
- /* We've emptied out our buffer. Refill it. */
-
- size_t maxread = dirp->allocation;
- ssize_t bytes;
-
- bytes = __old_getdents64 (dirp->fd, dirp->data, maxread);
- if (bytes <= 0)
- {
- /* On some systems getdents fails with ENOENT when the
- open directory has been rmdir'd already. POSIX.1
- requires that we treat this condition like normal EOF. */
- if (bytes < 0 && errno == ENOENT)
- bytes = 0;
-
- /* Don't modifiy errno when reaching EOF. */
- if (bytes == 0)
- __set_errno (saved_errno);
- dp = NULL;
- break;
- }
- dirp->size = (size_t) bytes;
-
- /* Reset the offset into the buffer. */
- dirp->offset = 0;
+ /* Linux may fail with ENOENT on some file systems if the
+ directory inode is marked as dead (deleted). POSIX
+ treats this as a regular end-of-directory condition, so
+ do not set errno in that case, to indicate success. */
+ if (bytes == 0 || errno == ENOENT)
+ __set_errno (saved_errno);
+#if IS_IN (libc)
+ __libc_lock_unlock (dirp->lock);
+#endif
+ return NULL;
}
+ dirp->size = (size_t) bytes;
- dp = (struct __old_dirent64 *) &dirp->data[dirp->offset];
-
- reclen = dp->d_reclen;
-
- dirp->offset += reclen;
-
- dirp->filepos = dp->d_off;
+ /* Reset the offset into the buffer. */
+ dirp->offset = 0;
+ }
- /* Skip deleted files. */
- } while (dp->d_ino == 0);
+ dp = (struct __old_dirent64 *) &dirp->data[dirp->offset];
+ dirp->offset += dp->d_reclen;
+ dirp->filepos = dp->d_off;
#if IS_IN (libc)
__libc_lock_unlock (dirp->lock);
--
2.23.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wang-whl/glibc.git
git@gitee.com:wang-whl/glibc.git
wang-whl
glibc
glibc
master

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385