libstdc++: Use secure_getenv for filesystem::temp_directory_path() [PR65018]
This adds a configure check for the GNU extension secure_getenv and then uses it for looking up TMPDIR and similar variables. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: PR libstdc++/65018 * configure.ac: Check for secure_getenv. * config.h.in: Regenerate. * configure: Regenerate. * src/filesystem/ops-common.h (get_temp_directory_from_env): New helper function to obtain path from the environment. * src/c++17/fs_ops.cc (fs::temp_directory_path): Use new helper. * src/filesystem/ops.cc (fs::temp_directory_path): Likewise. * testsuite/27_io/filesystem/operations/temp_directory_path.cc: Print messages if test cannot be run. * testsuite/experimental/filesystem/operations/temp_directory_path.cc: Likewise. Fix incorrect condition. Use "TMP" to work with Windows as well as POSIX.
This commit is contained in:
parent
2065654435
commit
3dbd4d94bf
|
@ -301,6 +301,9 @@
|
||||||
/* Define if readlink is available in <unistd.h>. */
|
/* Define if readlink is available in <unistd.h>. */
|
||||||
#undef HAVE_READLINK
|
#undef HAVE_READLINK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `secure_getenv' function. */
|
||||||
|
#undef HAVE_SECURE_GETENV
|
||||||
|
|
||||||
/* Define to 1 if you have the `setenv' function. */
|
/* Define to 1 if you have the `setenv' function. */
|
||||||
#undef HAVE_SETENV
|
#undef HAVE_SETENV
|
||||||
|
|
||||||
|
|
|
@ -28225,6 +28225,17 @@ if test "x$ac_cv_func__wfopen" = xyes; then :
|
||||||
#define HAVE__WFOPEN 1
|
#define HAVE__WFOPEN 1
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for ac_func in secure_getenv
|
||||||
|
do :
|
||||||
|
ac_fn_c_check_func "$LINENO" "secure_getenv" "ac_cv_func_secure_getenv"
|
||||||
|
if test "x$ac_cv_func_secure_getenv" = xyes; then :
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_SECURE_GETENV 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,7 @@ if $GLIBCXX_IS_NATIVE; then
|
||||||
AC_CHECK_FUNCS(__cxa_thread_atexit_impl __cxa_thread_atexit)
|
AC_CHECK_FUNCS(__cxa_thread_atexit_impl __cxa_thread_atexit)
|
||||||
AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc)
|
AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc)
|
||||||
AC_CHECK_FUNCS(_wfopen)
|
AC_CHECK_FUNCS(_wfopen)
|
||||||
|
AC_CHECK_FUNCS(secure_getenv)
|
||||||
|
|
||||||
# C11 functions for C++17 library
|
# C11 functions for C++17 library
|
||||||
AC_CHECK_FUNCS(timespec_get)
|
AC_CHECK_FUNCS(timespec_get)
|
||||||
|
|
|
@ -1591,7 +1591,8 @@ fs::symlink_status(const fs::path& p)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path fs::temp_directory_path()
|
fs::path
|
||||||
|
fs::temp_directory_path()
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
path tmp = temp_directory_path(ec);
|
path tmp = temp_directory_path(ec);
|
||||||
|
@ -1600,32 +1601,10 @@ fs::path fs::temp_directory_path()
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path fs::temp_directory_path(error_code& ec)
|
fs::path
|
||||||
|
fs::temp_directory_path(error_code& ec)
|
||||||
{
|
{
|
||||||
path p;
|
path p = fs::get_temp_directory_from_env();
|
||||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
|
||||||
unsigned len = 1024;
|
|
||||||
std::wstring buf;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
buf.resize(len);
|
|
||||||
len = GetTempPathW(buf.size(), buf.data());
|
|
||||||
} while (len > buf.size());
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
ec.assign((int)GetLastError(), std::system_category());
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
buf.resize(len);
|
|
||||||
p = std::move(buf);
|
|
||||||
#else
|
|
||||||
const char* tmpdir = nullptr;
|
|
||||||
const char* env[] = { "TMPDIR", "TMP", "TEMP", "TEMPDIR", nullptr };
|
|
||||||
for (auto e = env; tmpdir == nullptr && *e != nullptr; ++e)
|
|
||||||
tmpdir = ::getenv(*e);
|
|
||||||
p = tmpdir ? tmpdir : "/tmp";
|
|
||||||
#endif
|
|
||||||
auto st = status(p, ec);
|
auto st = status(p, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
p.clear();
|
p.clear();
|
||||||
|
|
|
@ -568,6 +568,46 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
|
||||||
|
|
||||||
#endif // _GLIBCXX_HAVE_SYS_STAT_H
|
#endif // _GLIBCXX_HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
// Find OS-specific name of temporary directory from the environment,
|
||||||
|
// Caller must check that the path is an accessible directory.
|
||||||
|
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
||||||
|
inline wstring
|
||||||
|
get_temp_directory_from_env()
|
||||||
|
{
|
||||||
|
unsigned len = 1024;
|
||||||
|
std::wstring buf;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
buf.resize(len);
|
||||||
|
len = GetTempPathW(buf.size(), buf.data());
|
||||||
|
} while (len > buf.size());
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
ec.assign((int)GetLastError(), std::system_category());
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
buf.resize(len);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline const char*
|
||||||
|
get_temp_directory_from_env() noexcept
|
||||||
|
{
|
||||||
|
for (auto env : { "TMPDIR", "TMP", "TEMP", "TEMPDIR" })
|
||||||
|
{
|
||||||
|
#if _GLIBCXX_HAVE_SECURE_GETENV
|
||||||
|
auto tmpdir = ::secure_getenv(env);
|
||||||
|
#else
|
||||||
|
auto tmpdir = ::getenv(env);
|
||||||
|
#endif
|
||||||
|
if (tmpdir)
|
||||||
|
return tmpdir;
|
||||||
|
}
|
||||||
|
return "/tmp";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_FILESYSTEM
|
_GLIBCXX_END_NAMESPACE_FILESYSTEM
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_VERSION
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
|
|
@ -1289,7 +1289,8 @@ fs::system_complete(const path& p, error_code& ec)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path fs::temp_directory_path()
|
fs::path
|
||||||
|
fs::temp_directory_path()
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
path tmp = temp_directory_path(ec);
|
path tmp = temp_directory_path(ec);
|
||||||
|
@ -1298,31 +1299,10 @@ fs::path fs::temp_directory_path()
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path fs::temp_directory_path(error_code& ec)
|
fs::path
|
||||||
|
fs::temp_directory_path(error_code& ec)
|
||||||
{
|
{
|
||||||
path p;
|
path p = fs::get_temp_directory_from_env();
|
||||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
|
||||||
unsigned len = 1024;
|
|
||||||
std::wstring buf;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
buf.resize(len);
|
|
||||||
len = GetTempPathW(buf.size(), buf.data());
|
|
||||||
} while (len > buf.size());
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
ec.assign((int)GetLastError(), std::system_category());
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
buf.resize(len);
|
|
||||||
p = std::move(buf);
|
|
||||||
#else
|
|
||||||
const char* tmpdir = nullptr;
|
|
||||||
const char* env[] = { "TMPDIR", "TMP", "TEMP", "TEMPDIR", nullptr };
|
|
||||||
for (auto e = env; tmpdir == nullptr && *e != nullptr; ++e)
|
|
||||||
tmpdir = ::getenv(*e);
|
|
||||||
p = tmpdir ? tmpdir : "/tmp";
|
|
||||||
auto st = status(p, ec);
|
auto st = status(p, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
p.clear();
|
p.clear();
|
||||||
|
@ -1331,7 +1311,5 @@ fs::path fs::temp_directory_path(error_code& ec)
|
||||||
p.clear();
|
p.clear();
|
||||||
ec = std::make_error_code(std::errc::not_a_directory);
|
ec = std::make_error_code(std::errc::not_a_directory);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <testsuite_fs.h>
|
#include <testsuite_fs.h>
|
||||||
|
|
||||||
|
@ -58,7 +59,10 @@ test01()
|
||||||
clean_env();
|
clean_env();
|
||||||
|
|
||||||
if (!fs::exists("/tmp"))
|
if (!fs::exists("/tmp"))
|
||||||
|
{
|
||||||
|
puts("/tmp doesn't exist, not testing it for temp_directory_path");
|
||||||
return; // just give up
|
return; // just give up
|
||||||
|
}
|
||||||
|
|
||||||
std::error_code ec = make_error_code(std::errc::invalid_argument);
|
std::error_code ec = make_error_code(std::errc::invalid_argument);
|
||||||
fs::path p1 = fs::temp_directory_path(ec);
|
fs::path p1 = fs::temp_directory_path(ec);
|
||||||
|
@ -75,7 +79,10 @@ test02()
|
||||||
clean_env();
|
clean_env();
|
||||||
|
|
||||||
if (!set_env("TMP", __gnu_test::nonexistent_path().string()))
|
if (!set_env("TMP", __gnu_test::nonexistent_path().string()))
|
||||||
|
{
|
||||||
|
puts("Cannot set environment variables, not testing temp_directory_path");
|
||||||
return; // just give up
|
return; // just give up
|
||||||
|
}
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::path p = fs::temp_directory_path(ec);
|
fs::path p = fs::temp_directory_path(ec);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <experimental/filesystem>
|
#include <experimental/filesystem>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <testsuite_fs.h>
|
#include <testsuite_fs.h>
|
||||||
|
|
||||||
|
@ -59,7 +60,10 @@ test01()
|
||||||
clean_env();
|
clean_env();
|
||||||
|
|
||||||
if (!fs::exists("/tmp"))
|
if (!fs::exists("/tmp"))
|
||||||
|
{
|
||||||
|
puts("/tmp doesn't exist, not testing it for temp_directory_path");
|
||||||
return; // just give up
|
return; // just give up
|
||||||
|
}
|
||||||
|
|
||||||
std::error_code ec = make_error_code(std::errc::invalid_argument);
|
std::error_code ec = make_error_code(std::errc::invalid_argument);
|
||||||
fs::path p1 = fs::temp_directory_path(ec);
|
fs::path p1 = fs::temp_directory_path(ec);
|
||||||
|
@ -75,8 +79,11 @@ test02()
|
||||||
{
|
{
|
||||||
clean_env();
|
clean_env();
|
||||||
|
|
||||||
if (set_env("TMPDIR", __gnu_test::nonexistent_path().string()))
|
if (!set_env("TMP", __gnu_test::nonexistent_path().string()))
|
||||||
|
{
|
||||||
|
puts("Cannot set environment variables, not testing temp_directory_path");
|
||||||
return; // just give up
|
return; // just give up
|
||||||
|
}
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::path p = fs::temp_directory_path(ec);
|
fs::path p = fs::temp_directory_path(ec);
|
||||||
|
|
Loading…
Reference in New Issue