On Thu, 23 Jun 2022 at 12:08, Alexandre Oliva <ol...@adacore.com> wrote: > > On Jun 22, 2022, Jonathan Wakely <jwak...@redhat.com> wrote: > > > There are other interactions between AT_CDCWD and ::openat not covered > > by this patch. I this this also needs to check HAVE_OPENAT: > > Here's an updated version, tested with this additional change.
Did this improve your test results for directory iterators? In the unlikely even that the target has ::unlinkat but not ::openat this will cause a behaviour regression, because now _Dir::do_unlink will use {AT_FDCWD, "full/path/to/file"} instead of {dirfd(dirp),"file"} but I doubt there are targets that have unlinkat without openat. I'll try to improve this code later as discussed anyway, so this is fine for now. OK for trunk, thanks. > > > libstdc++: check for openat > > From: Alexandre Oliva <ol...@adacore.com> > > rtems6.0 has fdopendir, and fcntl.h defines AT_FDCWD and declares > openat, but there's no openat in libc. Adjust dir-common.h to not > assume ::openat just because of AT_FDCWD. > > > for libstdc++-v3/ChangeLog > > * acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for > openat. > * aclocal.m4, configure, config.h.in: Rebuilt. > * src/filesystem/dir-common.h (openat): Use ::openat if > _GLIBCXX_HAVE_OPENAT. > * src/filesystem/dir.cc (dir_and_pathname): Use dirfd if > _GLIBCXX_HAVE_OPENAT. > --- > libstdc++-v3/acinclude.m4 | 12 +++++++ > libstdc++-v3/config.h.in | 3 ++ > libstdc++-v3/configure | 55 > ++++++++++++++++++++++++++++++ > libstdc++-v3/src/filesystem/dir-common.h | 2 + > libstdc++-v3/src/filesystem/dir.cc | 2 + > 5 files changed, 72 insertions(+), 2 deletions(-) > > diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 > index 138bd58d86cb9..e3cc3a8e867d3 100644 > --- a/libstdc++-v3/acinclude.m4 > +++ b/libstdc++-v3/acinclude.m4 > @@ -4772,6 +4772,18 @@ dnl > if test $glibcxx_cv_dirfd = yes; then > AC_DEFINE(HAVE_DIRFD, 1, [Define if dirfd is available in <dirent.h>.]) > fi > +dnl > + AC_CACHE_CHECK([for openat], > + glibcxx_cv_openat, [dnl > + GCC_TRY_COMPILE_OR_LINK( > + [#include <fcntl.h>], > + [int fd = ::openat(AT_FDCWD, "", 0);], > + [glibcxx_cv_openat=yes], > + [glibcxx_cv_openat=no]) > + ]) > + if test $glibcxx_cv_openat = yes; then > + AC_DEFINE(HAVE_OPENAT, 1, [Define if openat is available in <fcntl.h>.]) > + fi > dnl > AC_CACHE_CHECK([for unlinkat], > glibcxx_cv_unlinkat, [dnl > diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in > index f30a8c51c458c..2a3972eef5412 100644 > --- a/libstdc++-v3/config.h.in > +++ b/libstdc++-v3/config.h.in > @@ -292,6 +292,9 @@ > /* Define if <math.h> defines obsolete isnan function. */ > #undef HAVE_OBSOLETE_ISNAN > > +/* Define if openat is available in <fcntl.h>. */ > +#undef HAVE_OPENAT > + > /* Define if poll is available in <poll.h>. */ > #undef HAVE_POLL > > diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure > index 9b94fd71e4248..eac6039212168 100755 > --- a/libstdc++-v3/configure > +++ b/libstdc++-v3/configure > @@ -77177,6 +77177,61 @@ $as_echo "$glibcxx_cv_dirfd" >&6; } > > $as_echo "#define HAVE_DIRFD 1" >>confdefs.h > > + fi > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openat" >&5 > +$as_echo_n "checking for openat... " >&6; } > +if ${glibcxx_cv_openat+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + if test x$gcc_no_link = xyes; then > + cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > +#include <fcntl.h> > +int > +main () > +{ > +int fd = ::openat(AT_FDCWD, "", 0); > + ; > + return 0; > +} > +_ACEOF > +if ac_fn_cxx_try_compile "$LINENO"; then : > + glibcxx_cv_openat=yes > +else > + glibcxx_cv_openat=no > +fi > +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext > +else > + if test x$gcc_no_link = xyes; then > + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." > "$LINENO" 5 > +fi > +cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > +#include <fcntl.h> > +int > +main () > +{ > +int fd = ::openat(AT_FDCWD, "", 0); > + ; > + return 0; > +} > +_ACEOF > +if ac_fn_cxx_try_link "$LINENO"; then : > + glibcxx_cv_openat=yes > +else > + glibcxx_cv_openat=no > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext conftest.$ac_ext > +fi > + > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_openat" >&5 > +$as_echo "$glibcxx_cv_openat" >&6; } > + if test $glibcxx_cv_openat = yes; then > + > +$as_echo "#define HAVE_OPENAT 1" >>confdefs.h > + > fi > { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unlinkat" >&5 > $as_echo_n "checking for unlinkat... " >&6; } > diff --git a/libstdc++-v3/src/filesystem/dir-common.h > b/libstdc++-v3/src/filesystem/dir-common.h > index 365fd527f4d68..669780ea23fe5 100644 > --- a/libstdc++-v3/src/filesystem/dir-common.h > +++ b/libstdc++-v3/src/filesystem/dir-common.h > @@ -199,7 +199,7 @@ struct _Dir_base > #endif > > > -#ifdef AT_FDCWD > +#if _GLIBCXX_HAVE_OPENAT && defined AT_FDCWD > fd = ::openat(fd, pathname, flags); > #else > // If we cannot use openat, there's no benefit to using posix::open > unless > diff --git a/libstdc++-v3/src/filesystem/dir.cc > b/libstdc++-v3/src/filesystem/dir.cc > index b451902c4a1b1..e64489162e5ff 100644 > --- a/libstdc++-v3/src/filesystem/dir.cc > +++ b/libstdc++-v3/src/filesystem/dir.cc > @@ -120,7 +120,7 @@ struct fs::_Dir : std::filesystem::_Dir_base > dir_and_pathname() const noexcept > { > const fs::path& p = entry.path(); > -#if _GLIBCXX_HAVE_DIRFD > +#if _GLIBCXX_HAVE_DIRFD && _GLIBCXX_HAVE_OPENAT > return {::dirfd(this->dirp), std::prev(p.end())->c_str()}; > #endif > return {this->fdcwd(), p.c_str()}; > > > -- > Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ > Free Software Activist GNU Toolchain Engineer > Disinformation flourishes because many people care deeply about injustice > but very few check the facts. Ask me about <https://stallmansupport.org> >