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>. */
|
||||
#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. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
|
11
libstdc++-v3/configure
vendored
11
libstdc++-v3/configure
vendored
@ -28225,6 +28225,17 @@ if test "x$ac_cv_func__wfopen" = xyes; then :
|
||||
#define HAVE__WFOPEN 1
|
||||
_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
|
||||
done
|
||||
|
||||
|
@ -273,6 +273,7 @@ if $GLIBCXX_IS_NATIVE; then
|
||||
AC_CHECK_FUNCS(__cxa_thread_atexit_impl __cxa_thread_atexit)
|
||||
AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc)
|
||||
AC_CHECK_FUNCS(_wfopen)
|
||||
AC_CHECK_FUNCS(secure_getenv)
|
||||
|
||||
# C11 functions for C++17 library
|
||||
AC_CHECK_FUNCS(timespec_get)
|
||||
|
@ -1591,7 +1591,8 @@ fs::symlink_status(const fs::path& p)
|
||||
return result;
|
||||
}
|
||||
|
||||
fs::path fs::temp_directory_path()
|
||||
fs::path
|
||||
fs::temp_directory_path()
|
||||
{
|
||||
error_code ec;
|
||||
path tmp = temp_directory_path(ec);
|
||||
@ -1600,32 +1601,10 @@ fs::path fs::temp_directory_path()
|
||||
return tmp;
|
||||
}
|
||||
|
||||
fs::path fs::temp_directory_path(error_code& ec)
|
||||
fs::path
|
||||
fs::temp_directory_path(error_code& ec)
|
||||
{
|
||||
path p;
|
||||
#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
|
||||
path p = fs::get_temp_directory_from_env();
|
||||
auto st = status(p, ec);
|
||||
if (ec)
|
||||
p.clear();
|
||||
|
@ -568,6 +568,46 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
|
||||
|
||||
#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_VERSION
|
||||
|
@ -1289,7 +1289,8 @@ fs::system_complete(const path& p, error_code& ec)
|
||||
#endif
|
||||
}
|
||||
|
||||
fs::path fs::temp_directory_path()
|
||||
fs::path
|
||||
fs::temp_directory_path()
|
||||
{
|
||||
error_code ec;
|
||||
path tmp = temp_directory_path(ec);
|
||||
@ -1298,31 +1299,10 @@ fs::path fs::temp_directory_path()
|
||||
return tmp;
|
||||
}
|
||||
|
||||
fs::path fs::temp_directory_path(error_code& ec)
|
||||
fs::path
|
||||
fs::temp_directory_path(error_code& ec)
|
||||
{
|
||||
path p;
|
||||
#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";
|
||||
path p = fs::get_temp_directory_from_env();
|
||||
auto st = status(p, ec);
|
||||
if (ec)
|
||||
p.clear();
|
||||
@ -1331,7 +1311,5 @@ fs::path fs::temp_directory_path(error_code& ec)
|
||||
p.clear();
|
||||
ec = std::make_error_code(std::errc::not_a_directory);
|
||||
}
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_fs.h>
|
||||
|
||||
@ -58,7 +59,10 @@ test01()
|
||||
clean_env();
|
||||
|
||||
if (!fs::exists("/tmp"))
|
||||
{
|
||||
puts("/tmp doesn't exist, not testing it for temp_directory_path");
|
||||
return; // just give up
|
||||
}
|
||||
|
||||
std::error_code ec = make_error_code(std::errc::invalid_argument);
|
||||
fs::path p1 = fs::temp_directory_path(ec);
|
||||
@ -75,7 +79,10 @@ test02()
|
||||
clean_env();
|
||||
|
||||
if (!set_env("TMP", __gnu_test::nonexistent_path().string()))
|
||||
{
|
||||
puts("Cannot set environment variables, not testing temp_directory_path");
|
||||
return; // just give up
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
fs::path p = fs::temp_directory_path(ec);
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_fs.h>
|
||||
|
||||
@ -59,7 +60,10 @@ test01()
|
||||
clean_env();
|
||||
|
||||
if (!fs::exists("/tmp"))
|
||||
{
|
||||
puts("/tmp doesn't exist, not testing it for temp_directory_path");
|
||||
return; // just give up
|
||||
}
|
||||
|
||||
std::error_code ec = make_error_code(std::errc::invalid_argument);
|
||||
fs::path p1 = fs::temp_directory_path(ec);
|
||||
@ -75,8 +79,11 @@ test02()
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
fs::path p = fs::temp_directory_path(ec);
|
||||
|
Loading…
Reference in New Issue
Block a user