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.");