Просмотр исходного кода

readdir{,_r}: remove loop to skip files with d_ino == 0

It is not prohibited to use inode zero according to SUS/POSIX and you can
really do it in practice on a filesystem in linux (even if doing so is
inadvisable). All of the linux libcs I checked (musl, glibc, picolibc,
dietlibc) have no such check.

Fixes: a4f075815 ("Implement readdir_r.  Audit for proper thread safety and locking.  -Erik")
Signed-off-by: Charles Mirabile <cmirabil@redhat.com>
Charles Mirabile 1 месяц назад
Родитель
Сommit
ca17f8dc2f
2 измененных файлов с 30 добавлено и 37 удалено
  1. 14 18
      libc/misc/dirent/readdir.c
  2. 16 19
      libc/misc/dirent/readdir_r.c

+ 14 - 18
libc/misc/dirent/readdir.c

@@ -28,28 +28,24 @@ __DIRENT_TYPE *__READDIR(DIR * dir)
 
 	__UCLIBC_MUTEX_LOCK(dir->dd_lock);
 
-	do {
-	    if (dir->dd_size <= dir->dd_nextloc) {
-		/* read dir->dd_max bytes of directory entries. */
-		bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max);
-		if (bytes <= 0) {
-		    de = NULL;
-		    goto all_done;
-		}
-		dir->dd_size = bytes;
-		dir->dd_nextloc = 0;
+	if (dir->dd_size <= dir->dd_nextloc) {
+	    /* read dir->dd_max bytes of directory entries. */
+	    bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max);
+	    if (bytes <= 0) {
+		de = NULL;
+		goto all_done;
 	    }
+	    dir->dd_size = bytes;
+	    dir->dd_nextloc = 0;
+	}
 
-	    de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc);
-
-	    /* Am I right? H.J. */
-	    dir->dd_nextloc += de->d_reclen;
+	de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc);
 
-	    /* We have to save the next offset here. */
-	    dir->dd_nextoff = de->d_off;
+	/* Am I right? H.J. */
+	dir->dd_nextloc += de->d_reclen;
 
-	    /* Skip deleted files.  */
-	} while (de->d_ino == 0);
+	/* We have to save the next offset here. */
+	dir->dd_nextoff = de->d_off;
 
 all_done:
 	__UCLIBC_MUTEX_UNLOCK(dir->dd_lock);

+ 16 - 19
libc/misc/dirent/readdir_r.c

@@ -30,29 +30,26 @@ int __READDIR_R(DIR *dir, __DIRENT_TYPE *entry, __DIRENT_TYPE **result)
 
 	__UCLIBC_MUTEX_LOCK(dir->dd_lock);
 
-	do {
-	    if (dir->dd_size <= dir->dd_nextloc) {
-		/* read dir->dd_max bytes of directory entries. */
-		bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max);
-		if (bytes <= 0) {
-		    de = NULL;
-		    *result = NULL;
-		    ret = (bytes==0)? 0 : errno;
-		    goto all_done;
-		}
-		dir->dd_size = bytes;
-		dir->dd_nextloc = 0;
+	if (dir->dd_size <= dir->dd_nextloc) {
+	    /* read dir->dd_max bytes of directory entries. */
+	    bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max);
+	    if (bytes <= 0) {
+		de = NULL;
+		*result = NULL;
+		ret = (bytes==0)? 0 : errno;
+		goto all_done;
 	    }
+	    dir->dd_size = bytes;
+	    dir->dd_nextloc = 0;
+	}
 
-	    de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc);
+	de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc);
 
-	    /* Am I right? H.J. */
-	    dir->dd_nextloc += de->d_reclen;
+	/* Am I right? H.J. */
+	dir->dd_nextloc += de->d_reclen;
 
-	    /* We have to save the next offset here. */
-	    dir->dd_nextoff = de->d_off;
-	    /* Skip deleted files.  */
-	} while (de->d_ino == 0);
+	/* We have to save the next offset here. */
+	dir->dd_nextoff = de->d_off;
 
 	if (de == NULL) {
 	    *result = NULL;