diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-05-14 14:23:14 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-05-14 14:23:14 +0100 |
commit | a0c4531ccf06e9381083421e9e7c2bdf89aa7f13 (patch) | |
tree | 94fd318f3f4f43eec83cd1a869249e3a989e1762 /libstdc++-v3 | |
parent | 0b9fc9fee84ec9de6de8d95ee670bc121b298331 (diff) | |
download | gcc-a0c4531ccf06e9381083421e9e7c2bdf89aa7f13.zip gcc-a0c4531ccf06e9381083421e9e7c2bdf89aa7f13.tar.gz gcc-a0c4531ccf06e9381083421e9e7c2bdf89aa7f13.tar.bz2 |
re PR libstdc++/66011 (call to '__open_missing_mode' declared with attribute error)
PR libstdc++/66011
* acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for fchmod and
sendfile.
* config.h.in: Regenerate.
* configure: Regenerate.
* src/filesystem/ops.cc (do_copy_file): Fix arguments to open(). Do
not return after copying contents. Use fchmod, fchmodat, and sendfile
when available.
(current_path, permissions, space): Use errno not return value.
From-SVN: r223196
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/acinclude.m4 | 33 | ||||
-rw-r--r-- | libstdc++-v3/config.h.in | 6 | ||||
-rwxr-xr-x | libstdc++-v3/configure | 119 | ||||
-rw-r--r-- | libstdc++-v3/src/filesystem/ops.cc | 50 |
5 files changed, 197 insertions, 21 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 000bcd5..4e38fbf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2015-05-14 Jonathan Wakely <jwakely@redhat.com> + PR libstdc++/66011 + * acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for fchmod and + sendfile. + * config.h.in: Regenerate. + * configure: Regenerate. + * src/filesystem/ops.cc (do_copy_file): Fix arguments to open(). Do + not return after copying contents. Use fchmod, fchmodat, and sendfile + when available. + (current_path, permissions, space): Use errno not return value. + PR libstdc++/66018 * acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for struct dirent.d_type. diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index b2b48cc..8340572 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3939,6 +3939,19 @@ dnl fi AC_MSG_RESULT($glibcxx_cv_st_mtim) dnl + AC_MSG_CHECKING([for fchmod]) + AC_CACHE_VAL(glibcxx_cv_fchmod, [dnl + GCC_TRY_COMPILE_OR_LINK( + [#include <sys/stat.h>], + [fchmod(1, S_IWUSR);], + [glibcxx_cv_fchmod=yes], + [glibcxx_cv_fchmod=no]) + ]) + if test $glibcxx_cv_fchmod = yes; then + AC_DEFINE(_GLIBCXX_USE_FCHMOD, 1, [Define if fchmod is available in <sys/stat.h>.]) + fi + AC_MSG_RESULT($glibcxx_cv_fchmod) +dnl AC_MSG_CHECKING([for fchmodat]) AC_CACHE_VAL(glibcxx_cv_fchmodat, [dnl GCC_TRY_COMPILE_OR_LINK( @@ -3955,6 +3968,26 @@ dnl fi AC_MSG_RESULT($glibcxx_cv_fchmodat) dnl + AC_MSG_CHECKING([for sendfile that can copy files]) + AC_CACHE_VAL(glibcxx_cv_sendfile, [dnl + case "${target_os}" in + gnu* | linux* | solaris*) + GCC_TRY_COMPILE_OR_LINK( + [#include <sys/sendfile.h>], + [sendfile(1, 2, (off_t*)NULL, sizeof 1);], + [glibcxx_cv_sendfile=yes], + [glibcxx_cv_sendfile=no]) + ;; + *) + glibcxx_cv_sendfile=no + ;; + esac + ]) + if test $glibcxx_cv_sendfile = yes; then + AC_DEFINE(_GLIBCXX_USE_SENDFILE, 1, [Define if sendfile is available in <sys/stat.h>.]) + fi + AC_MSG_RESULT($glibcxx_cv_sendfile) +dnl CXXFLAGS="$ac_save_CXXFLAGS" AC_LANG_RESTORE ]) diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index b833c81..337f614 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -836,6 +836,9 @@ this host. */ #undef _GLIBCXX_USE_DECIMAL_FLOAT +/* Define if fchmod is available in <sys/stat.h>. */ +#undef _GLIBCXX_USE_FCHMOD + /* Define if fchmodat is available in <sys/stat.h>. */ #undef _GLIBCXX_USE_FCHMODAT @@ -885,6 +888,9 @@ /* Define if _SC_NPROC_ONLN is available in <unistd.h>. */ #undef _GLIBCXX_USE_SC_NPROC_ONLN +/* Define if sendfile is available in <sys/stat.h>. */ +#undef _GLIBCXX_USE_SENDFILE + /* Define if struct stat has timespec members. */ #undef _GLIBCXX_USE_ST_MTIM diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index d30cd18..3654b68 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -79092,6 +79092,62 @@ $as_echo "#define _GLIBCXX_USE_ST_MTIM 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_st_mtim" >&5 $as_echo "$glibcxx_cv_st_mtim" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fchmod" >&5 +$as_echo_n "checking for fchmod... " >&6; } + if test "${glibcxx_cv_fchmod+set}" = set; 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 <sys/stat.h> +int +main () +{ +fchmod(1, S_IWUSR); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + glibcxx_cv_fchmod=yes +else + glibcxx_cv_fchmod=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 <sys/stat.h> +int +main () +{ +fchmod(1, S_IWUSR); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + glibcxx_cv_fchmod=yes +else + glibcxx_cv_fchmod=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +fi + + if test $glibcxx_cv_fchmod = yes; then + +$as_echo "#define _GLIBCXX_USE_FCHMOD 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_fchmod" >&5 +$as_echo "$glibcxx_cv_fchmod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fchmodat" >&5 $as_echo_n "checking for fchmodat... " >&6; } if test "${glibcxx_cv_fchmodat+set}" = set; then : @@ -79154,6 +79210,69 @@ $as_echo "#define _GLIBCXX_USE_FCHMODAT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_fchmodat" >&5 $as_echo "$glibcxx_cv_fchmodat" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendfile that can copy files" >&5 +$as_echo_n "checking for sendfile that can copy files... " >&6; } + if test "${glibcxx_cv_sendfile+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case "${target_os}" in + gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu | solaris*) + if test x$gcc_no_link = xyes; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/sendfile.h> +int +main () +{ +sendfile(1, 2, (off_t*)NULL, sizeof 1); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + glibcxx_cv_sendfile=yes +else + glibcxx_cv_sendfile=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 <sys/sendfile.h> +int +main () +{ +sendfile(1, 2, (off_t*)NULL, sizeof 1); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + glibcxx_cv_sendfile=yes +else + glibcxx_cv_sendfile=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + ;; + *) + glibcxx_cv_sendfile=no + ;; + esac + +fi + + if test $glibcxx_cv_sendfile = yes; then + +$as_echo "#define _GLIBCXX_USE_SENDFILE 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_sendfile" >&5 +$as_echo "$glibcxx_cv_sendfile" >&6; } CXXFLAGS="$ac_save_CXXFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index aa1ab04..f24cc19 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -41,7 +41,7 @@ #ifdef _GLIBCXX_HAVE_SYS_STATVFS_H # include <sys/statvfs.h> #endif -#ifdef _GLIBCXX_HAVE_GNU_SENDFILE +#ifdef _GLIBCXX_USE_SENDFILE # include <sys/sendfile.h> #else # include <ext/stdio_filebuf.h> @@ -241,6 +241,8 @@ namespace } f = make_file_status(*from_st); + using opts = fs::copy_options; + if (exists(t)) { if (!is_other(t) && !is_other(f) @@ -251,12 +253,12 @@ namespace return false; } - if (is_set(option, fs::copy_options::skip_existing)) + if (is_set(option, opts::skip_existing)) { ec.clear(); return false; } - else if (is_set(option, fs::copy_options::update_existing)) + else if (is_set(option, opts::update_existing)) { if (file_time(*from_st) <= file_time(*to_st)) { @@ -264,7 +266,7 @@ namespace return false; } } - else if (!is_set(option, fs::copy_options::overwrite_existing)) + else if (!is_set(option, opts::overwrite_existing)) { ec = std::make_error_code(std::errc::file_exists); return false; @@ -282,14 +284,22 @@ namespace ec.assign(errno, std::generic_category()); return false; } - CloseFD out = { ::open(to.c_str(), O_WRONLY|O_CREAT) }; + int oflag = O_WRONLY|O_CREAT; + if (is_set(option, opts::overwrite_existing|opts::update_existing)) + oflag |= O_TRUNC; + else + oflag |= O_EXCL; + CloseFD out = { ::open(to.c_str(), oflag, S_IWUSR) }; if (out.fd == -1) { - ec.assign(errno, std::generic_category()); + if (errno == EEXIST && is_set(option, opts::skip_existing)) + ec.clear(); + else + ec.assign(errno, std::generic_category()); return false; } -#ifdef _GLIBCXX_HAVE_GNU_SENDFILE +#ifdef _GLIBCXX_USE_SENDFILE auto n = ::sendfile(out.fd, in.fd, nullptr, from_st->st_size); if (n != from_st->st_size) { @@ -299,20 +309,17 @@ namespace #else __gnu_cxx::stdio_filebuf<char> sbin(in.fd, std::ios::in); __gnu_cxx::stdio_filebuf<char> sbout(out.fd, std::ios::out); - if (std::ostream(&sbout) << &sbin) - { - ec.clear(); - return true; - } - else + if ( !(std::ostream(&sbout) << &sbin) ) { ec = std::make_error_code(std::errc::io_error); return false; } #endif -#ifdef _GLIBCXX_HAVE_FCHMOD +#ifdef _GLIBCXX_USE_FCHMOD if (::fchmod(out.fd, from_st->st_mode)) +#elif _GLIBCXX_USE_FCHMODAT + if (::fchmodat(AT_FDCWD, to.c_str(), from_st->st_mode, 0)) #else if (::chmod(to.c_str(), from_st->st_mode)) #endif @@ -320,6 +327,7 @@ namespace ec.assign(errno, std::generic_category()); return false; } + ec.clear(); return true; } } @@ -715,8 +723,8 @@ void fs::current_path(const path& p, error_code& ec) noexcept { #ifdef _GLIBCXX_HAVE_UNISTD_H - if (int err = ::chdir(p.c_str())) - ec.assign(err, std::generic_category()); + if (::chdir(p.c_str())) + ec.assign(errno, std::generic_category()); else ec.clear(); #else @@ -908,11 +916,11 @@ fs::permissions(const path& p, perms prms) void fs::permissions(const path& p, perms prms, error_code& ec) noexcept { #if _GLIBCXX_USE_FCHMODAT - if (int err = ::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), 0)) + if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), 0)) #else - if (int err = ::chmod(p.c_str(), static_cast<mode_t>(prms))) + if (::chmod(p.c_str(), static_cast<mode_t>(prms))) #endif - ec.assign(err, std::generic_category()); + ec.assign(errno, std::generic_category()); else ec.clear(); } @@ -1064,8 +1072,8 @@ fs::space(const path& p, error_code& ec) noexcept }; #ifdef _GLIBCXX_HAVE_SYS_STATVFS_H struct ::statvfs f; - if (int err = ::statvfs(p.c_str(), &f)) - ec.assign(err, std::generic_category()); + if (::statvfs(p.c_str(), &f)) + ec.assign(errno, std::generic_category()); else { info = space_info{ |