The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=d20c82507278e003f391c3fb04f4e49afd1537ab

commit d20c82507278e003f391c3fb04f4e49afd1537ab
Author:     Dag-Erling Smørgrav <d...@freebsd.org>
AuthorDate: 2025-09-11 15:12:22 +0000
Commit:     Dag-Erling Smørgrav <d...@freebsd.org>
CommitDate: 2025-09-11 15:12:22 +0000

    Revert "libc: Remove readdir_r(3)"
    
    This reverts commit d549de769055ae6116601e54e4c86dfb3e17f4c4.
---
 ObsoleteFiles.inc               |  3 ---
 include/dirent.h                |  4 ++++
 lib/libc/gen/Makefile.inc       |  1 +
 lib/libc/gen/Symbol.map         |  1 +
 lib/libc/gen/directory.3        | 51 +++++++++++++++++++++++++++++++++++++----
 lib/libc/gen/gen-compat.h       |  1 -
 lib/libc/gen/gen-private.h      |  3 +++
 lib/libc/gen/readdir-compat11.c |  2 +-
 lib/libc/gen/readdir.c          |  8 +++----
 9 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 5fe01af2eea7..02a727d631bd 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -51,9 +51,6 @@
 #   xargs -n1 | sort | uniq -d;
 # done
 
-# 20250910: readdir_r(3) removed
-OLD_FILES+=usr/share/man/man3/readdir_r.3.gz
-
 # 20250826: Remove a misspelled manual
 OLD_FILES+=usr/share/man/man3/sysdecode_syscallnames.3.gz
 
diff --git a/include/dirent.h b/include/dirent.h
index 8df38a707856..7fcdceb10b23 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -115,6 +115,10 @@ DIR        *opendir(const char *);
 DIR    *fdopendir(int);
 struct dirent *
         readdir(DIR *);
+#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500
+int     readdir_r(DIR *, struct dirent *, struct dirent **)
+       __deprecated1("Does not take variable {NAME_MAX} into account");
+#endif
 void    rewinddir(DIR *);
 #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700
 int     scandir(const char *, struct dirent ***,
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index c32f514d7176..4d064d18d36e 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -342,6 +342,7 @@ MLINKS+=directory.3 closedir.3 \
        directory.3 fdopendir.3 \
        directory.3 opendir.3 \
        directory.3 readdir.3 \
+       directory.3 readdir_r.3 \
        directory.3 rewinddir.3 \
        directory.3 seekdir.3 \
        directory.3 telldir.3
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 86a8712ef12f..26f638568efc 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -418,6 +418,7 @@ FBSD_1.5 {
        globfree;
        nftw;
        readdir;
+       readdir_r;
        scandir;
        sem_clockwait_np;
        setproctitle_fast;
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3
index a92d51980aab..263dfdd6eb95 100644
--- a/lib/libc/gen/directory.3
+++ b/lib/libc/gen/directory.3
@@ -25,13 +25,14 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd September 5, 2025
+.Dd August 1, 2020
 .Dt DIRECTORY 3
 .Os
 .Sh NAME
 .Nm opendir ,
 .Nm fdopendir ,
 .Nm readdir ,
+.Nm readdir_r ,
 .Nm telldir ,
 .Nm seekdir ,
 .Nm rewinddir ,
@@ -49,6 +50,8 @@
 .Fn fdopendir "int fd"
 .Ft struct dirent *
 .Fn readdir "DIR *dirp"
+.Ft int
+.Fn readdir_r "DIR *dirp" "struct dirent *entry" "struct dirent **result"
 .Ft long
 .Fn telldir "DIR *dirp"
 .Ft void
@@ -62,6 +65,15 @@
 .Ft int
 .Fn dirfd "DIR *dirp"
 .Sh DESCRIPTION
+.Bf -symbolic
+The
+.Fn readdir_r
+interface is deprecated
+because it cannot be used correctly unless
+.Brq Va NAME_MAX
+is a fixed value.
+.Ef
+.Pp
 The
 .Fn opendir
 function
@@ -100,6 +112,7 @@ or to modify the state of the associated description other 
than by means
 of
 .Fn closedir ,
 .Fn readdir ,
+.Fn readdir_r ,
 or
 .Fn rewinddir ,
 the behavior is undefined.
@@ -131,6 +144,34 @@ may be set to any of the values documented for the
 system call.
 .Pp
 The
+.Fn readdir_r
+function
+provides the same functionality as
+.Fn readdir ,
+but the caller must provide a directory
+.Fa entry
+buffer to store the results in.
+The buffer must be large enough for a
+.Vt struct dirent
+with a
+.Va d_name
+array with
+.Brq Va NAME_MAX
++ 1 elements.
+If the read succeeds,
+.Fa result
+is pointed at the
+.Fa entry ;
+upon reaching the end of the directory
+.Fa result
+is set to
+.Dv NULL .
+The
+.Fn readdir_r
+function
+returns 0 on success or an error number to indicate failure.
+.Pp
+The
 .Fn telldir
 function
 returns a token representing the current location associated with the named
@@ -264,7 +305,9 @@ is not associated with a directory.
 .Pp
 The
 .Fn readdir
-function may also fail and set
+and
+.Fn readdir_r
+functions may also fail and set
 .Va errno
 for any of the errors specified for the routine
 .Xr getdents 2 .
@@ -295,6 +338,7 @@ The
 .Fn fdopendir ,
 .Fn opendir ,
 .Fn readdir ,
+.Fn readdir_r ,
 .Fn rewinddir ,
 .Fn seekdir
 and
@@ -347,8 +391,7 @@ will always set the correct location to return the same 
value as that last
 .Fn readdir
 performed.
 This is enough for some applications which want to
-.Dq push back the last entry read ,
-e.g. Samba.
+"push back the last entry read", e.g., Samba.
 Seeks back to any other location,
 other than the beginning of the directory,
 may result in unexpected behaviour if deletes are present.
diff --git a/lib/libc/gen/gen-compat.h b/lib/libc/gen/gen-compat.h
index 4518c3f130d1..08e80ede6b6e 100644
--- a/lib/libc/gen/gen-compat.h
+++ b/lib/libc/gen/gen-compat.h
@@ -37,7 +37,6 @@ struct freebsd11_dirent;
 struct freebsd11_stat;
 struct freebsd11_statfs;
 
-int    freebsd15_readdir_r(DIR *, struct dirent *, struct dirent **);
 struct freebsd11_dirent *freebsd11_readdir(DIR *);
 int    freebsd11_readdir_r(DIR *, struct freebsd11_dirent *,
            struct freebsd11_dirent **);
diff --git a/lib/libc/gen/gen-private.h b/lib/libc/gen/gen-private.h
index 97dd41ffbdfc..b6749b3435cd 100644
--- a/lib/libc/gen/gen-private.h
+++ b/lib/libc/gen/gen-private.h
@@ -60,4 +60,7 @@ struct _dirdesc {
 
 #define        _dirfd(dirp)    ((dirp)->dd_fd)
 
+struct dirent;
+int __readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
+
 #endif /* !_GEN_PRIVATE_H_ */
diff --git a/lib/libc/gen/readdir-compat11.c b/lib/libc/gen/readdir-compat11.c
index 71c223f00b5a..606e15bd7b36 100644
--- a/lib/libc/gen/readdir-compat11.c
+++ b/lib/libc/gen/readdir-compat11.c
@@ -95,7 +95,7 @@ freebsd11_readdir_r(DIR *dirp, struct freebsd11_dirent *entry,
        struct dirent xentry, *xresult;
        int error;
 
-       error = freebsd15_readdir_r(dirp, &xentry, &xresult);
+       error = __readdir_r(dirp, &xentry, &xresult);
        if (error != 0)
                return (error);
        if (xresult != NULL) {
diff --git a/lib/libc/gen/readdir.c b/lib/libc/gen/readdir.c
index d0bbe72237e1..94d2b2e8d877 100644
--- a/lib/libc/gen/readdir.c
+++ b/lib/libc/gen/readdir.c
@@ -41,8 +41,6 @@
 #include "gen-private.h"
 #include "telldir.h"
 
-#include "gen-compat.h"
-
 /*
  * get next entry in a directory.
  */
@@ -106,7 +104,7 @@ readdir(DIR *dirp)
 }
 
 int
-freebsd15_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
+__readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
 {
        struct dirent *dp;
        int saved_errno;
@@ -135,4 +133,6 @@ freebsd15_readdir_r(DIR *dirp, struct dirent *entry, struct 
dirent **result)
        return (0);
 }
 
-__sym_compat(readdir_r, freebsd15_readdir_r, FBSD_1.5);
+__strong_reference(__readdir_r, readdir_r);
+__warn_references(readdir_r,
+    "warning: this program uses readdir_r(), which is unsafe.");

Reply via email to