"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "googletest/src/gtest-port.cc" between
googletest-release-1.10.0.tar.gz and googletest-release-1.11.0.tar.gz

About: GoogleTest is Google's (unit) testing and mocking framework for C++ tests.

gtest-port.cc  (googletest-release-1.10.0):gtest-port.cc  (googletest-release-1.11.0)
skipping to change at line 36 skipping to change at line 36
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <cstdint>
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# include <windows.h> # include <windows.h>
# include <io.h> # include <io.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <map> // Used in ThreadLocal. # include <map> // Used in ThreadLocal.
# ifdef _MSC_VER # ifdef _MSC_VER
# include <crtdbg.h> # include <crtdbg.h>
skipping to change at line 199 skipping to change at line 200
sizeof(struct kinfo_proc), sizeof(struct kinfo_proc),
0, 0,
}; };
u_int miblen = sizeof(mib) / sizeof(mib[0]); u_int miblen = sizeof(mib) / sizeof(mib[0]);
// get number of structs // get number of structs
size_t size; size_t size;
if (sysctl(mib, miblen, NULL, &size, NULL, 0)) { if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {
return 0; return 0;
} }
mib[5] = size / mib[4];
mib[5] = static_cast<int>(size / static_cast<size_t>(mib[4]));
// populate array of structs // populate array of structs
struct kinfo_proc info[mib[5]]; struct kinfo_proc info[mib[5]];
if (sysctl(mib, miblen, &info, &size, NULL, 0)) { if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
return 0; return 0;
} }
// exclude empty members // exclude empty members
int nthreads = 0; size_t nthreads = 0;
for (int i = 0; i < size / mib[4]; i++) { for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) {
if (info[i].p_tid != -1) if (info[i].p_tid != -1)
nthreads++; nthreads++;
} }
return nthreads; return nthreads;
} }
#elif GTEST_OS_QNX #elif GTEST_OS_QNX
// Returns the number of threads running in the process, or 0 to indicate that // Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it. // we cannot detect it.
skipping to change at line 538 skipping to change at line 540
// Maps a thread to a set of ThreadIdToThreadLocals that have values // Maps a thread to a set of ThreadIdToThreadLocals that have values
// instantiated on that thread and notifies them when the thread exits. A // instantiated on that thread and notifies them when the thread exits. A
// ThreadLocal instance is expected to persist until all threads it has // ThreadLocal instance is expected to persist until all threads it has
// values on have terminated. // values on have terminated.
class ThreadLocalRegistryImpl { class ThreadLocalRegistryImpl {
public: public:
// Registers thread_local_instance as having value on the current thread. // Registers thread_local_instance as having value on the current thread.
// Returns a value that can be used to identify the thread from other threads. // Returns a value that can be used to identify the thread from other threads.
static ThreadLocalValueHolderBase* GetValueOnCurrentThread( static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) { const ThreadLocalBase* thread_local_instance) {
#ifdef _MSC_VER
MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER
DWORD current_thread = ::GetCurrentThreadId(); DWORD current_thread = ::GetCurrentThreadId();
MutexLock lock(&mutex_); MutexLock lock(&mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals = ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked(); GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos = ThreadIdToThreadLocals::iterator thread_local_pos =
thread_to_thread_locals->find(current_thread); thread_to_thread_locals->find(current_thread);
if (thread_local_pos == thread_to_thread_locals->end()) { if (thread_local_pos == thread_to_thread_locals->end()) {
thread_local_pos = thread_to_thread_locals->insert( thread_local_pos = thread_to_thread_locals->insert(
std::make_pair(current_thread, ThreadLocalValues())).first; std::make_pair(current_thread, ThreadLocalValues())).first;
StartWatcherThreadFor(current_thread); StartWatcherThreadFor(current_thread);
skipping to change at line 685 skipping to change at line 690
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals(); static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
return map; return map;
} }
// Protects access to GetThreadLocalsMapLocked() and its return value. // Protects access to GetThreadLocalsMapLocked() and its return value.
static Mutex mutex_; static Mutex mutex_;
// Protects access to GetThreadMapLocked() and its return value. // Protects access to GetThreadMapLocked() and its return value.
static Mutex thread_map_mutex_; static Mutex thread_map_mutex_;
}; };
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); // NOLIN
T
ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) { const ThreadLocalBase* thread_local_instance) {
return ThreadLocalRegistryImpl::GetValueOnCurrentThread( return ThreadLocalRegistryImpl::GetValueOnCurrentThread(
thread_local_instance); thread_local_instance);
} }
void ThreadLocalRegistry::OnThreadLocalDestroyed( void ThreadLocalRegistry::OnThreadLocalDestroyed(
const ThreadLocalBase* thread_local_instance) { const ThreadLocalBase* thread_local_instance) {
ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);
skipping to change at line 1092 skipping to change at line 1097
0, // Generate unique file name. 0, // Generate unique file name.
temp_file_path); temp_file_path);
GTEST_CHECK_(success != 0) GTEST_CHECK_(success != 0)
<< "Unable to create a temporary file in " << temp_dir_path; << "Unable to create a temporary file in " << temp_dir_path;
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
<< temp_file_path; << temp_file_path;
filename_ = temp_file_path; filename_ = temp_file_path;
# else # else
// There's no guarantee that a test has write access to the current // There's no guarantee that a test has write access to the current
// directory, so we create the temporary file in the /tmp directory // directory, so we create the temporary file in a temporary directory.
// instead. We use /tmp on most systems, and /sdcard on Android. std::string name_template;
// That's because Android doesn't have /tmp.
# if GTEST_OS_LINUX_ANDROID # if GTEST_OS_LINUX_ANDROID
// Note: Android applications are expected to call the framework's // Note: Android applications are expected to call the framework's
// Context.getExternalStorageDirectory() method through JNI to get // Context.getExternalStorageDirectory() method through JNI to get
// the location of the world-writable SD Card directory. However, // the location of the world-writable SD Card directory. However,
// this requires a Context handle, which cannot be retrieved // this requires a Context handle, which cannot be retrieved
// globally from native code. Doing so also precludes running the // globally from native code. Doing so also precludes running the
// code as part of a regular standalone executable, which doesn't // code as part of a regular standalone executable, which doesn't
// run in a Dalvik process (e.g. when running it through 'adb shell'). // run in a Dalvik process (e.g. when running it through 'adb shell').
// //
// The location /data/local/tmp is directly accessible from native code. // The location /data/local/tmp is directly accessible from native code.
// '/sdcard' and other variants cannot be relied on, as they are not // '/sdcard' and other variants cannot be relied on, as they are not
// guaranteed to be mounted, or may have a delay in mounting. // guaranteed to be mounted, or may have a delay in mounting.
char name_template[] = "/data/local/tmp/gtest_captured_stream.XXXXXX"; name_template = "/data/local/tmp/";
# elif GTEST_OS_IOS
char user_temp_dir[PATH_MAX + 1];
// Documented alternative to NSTemporaryDirectory() (for obtaining creating
// a temporary directory) at
// https://developer.apple.com/library/archive/documentation/Security/Concep
tual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP400025
85-SW10
//
// _CS_DARWIN_USER_TEMP_DIR (as well as _CS_DARWIN_USER_CACHE_DIR) is not
// documented in the confstr() man page at
// https://developer.apple.com/library/archive/documentation/System/Conceptu
al/ManPages_iPhoneOS/man3/confstr.3.html#//apple_ref/doc/man/3/confstr
// but are still available, according to the WebKit patches at
// https://trac.webkit.org/changeset/262004/webkit
// https://trac.webkit.org/changeset/263705/webkit
//
// The confstr() implementation falls back to getenv("TMPDIR"). See
// https://opensource.apple.com/source/Libc/Libc-1439.100.3/gen/confstr.c.au
to.html
::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));
name_template = user_temp_dir;
if (name_template.back() != GTEST_PATH_SEP_[0])
name_template.push_back(GTEST_PATH_SEP_[0]);
# else # else
char name_template[] = "/tmp/captured_stream.XXXXXX"; name_template = "/tmp/";
# endif // GTEST_OS_LINUX_ANDROID # endif
const int captured_fd = mkstemp(name_template); name_template.append("gtest_captured_stream.XXXXXX");
// mkstemp() modifies the string bytes in place, and does not go beyond the
// string's length. This results in well-defined behavior in C++17.
//
// The const_cast is needed below C++17. The constraints on std::string
// implementations in C++11 and above make assumption behind the const_cast
// fairly safe.
const int captured_fd = ::mkstemp(const_cast<char*>(name_template.data()));
if (captured_fd == -1) { if (captured_fd == -1) {
GTEST_LOG_(WARNING) GTEST_LOG_(WARNING)
<< "Failed to create tmp file " << name_template << "Failed to create tmp file " << name_template
<< " for test; does the test have access to the /tmp directory?"; << " for test; does the test have access to the /tmp directory?";
} }
filename_ = name_template; filename_ = std::move(name_template);
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
fflush(nullptr); fflush(nullptr);
dup2(captured_fd, fd_); dup2(captured_fd, fd_);
close(captured_fd); close(captured_fd);
} }
~CapturedStream() { ~CapturedStream() {
remove(filename_.c_str()); remove(filename_.c_str());
} }
skipping to change at line 1284 skipping to change at line 1318
for (size_t i = 0; i != full_flag.length(); i++) { for (size_t i = 0; i != full_flag.length(); i++) {
env_var << ToUpper(full_flag.c_str()[i]); env_var << ToUpper(full_flag.c_str()[i]);
} }
return env_var.GetString(); return env_var.GetString();
} }
// Parses 'str' for a 32-bit signed integer. If successful, writes // Parses 'str' for a 32-bit signed integer. If successful, writes
// the result to *value and returns true; otherwise leaves *value // the result to *value and returns true; otherwise leaves *value
// unchanged and returns false. // unchanged and returns false.
bool ParseInt32(const Message& src_text, const char* str, Int32* value) { bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
// Parses the environment variable as a decimal integer. // Parses the environment variable as a decimal integer.
char* end = nullptr; char* end = nullptr;
const long long_value = strtol(str, &end, 10); // NOLINT const long long_value = strtol(str, &end, 10); // NOLINT
// Has strtol() consumed all characters in the string? // Has strtol() consumed all characters in the string?
if (*end != '\0') { if (*end != '\0') {
// No - an invalid character was encountered. // No - an invalid character was encountered.
Message msg; Message msg;
msg << "WARNING: " << src_text msg << "WARNING: " << src_text
<< " is expected to be a 32-bit integer, but actually" << " is expected to be a 32-bit integer, but actually"
<< " has value \"" << str << "\".\n"; << " has value \"" << str << "\".\n";
printf("%s", msg.GetString().c_str()); printf("%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
return false; return false;
} }
// Is the parsed value in the range of an Int32? // Is the parsed value in the range of an int32_t?
const Int32 result = static_cast<Int32>(long_value); const auto result = static_cast<int32_t>(long_value);
if (long_value == LONG_MAX || long_value == LONG_MIN || if (long_value == LONG_MAX || long_value == LONG_MIN ||
// The parsed value overflows as a long. (strtol() returns // The parsed value overflows as a long. (strtol() returns
// LONG_MAX or LONG_MIN when the input overflows.) // LONG_MAX or LONG_MIN when the input overflows.)
result != long_value result != long_value
// The parsed value overflows as an Int32. // The parsed value overflows as an int32_t.
) { ) {
Message msg; Message msg;
msg << "WARNING: " << src_text msg << "WARNING: " << src_text
<< " is expected to be a 32-bit integer, but actually" << " is expected to be a 32-bit integer, but actually"
<< " has value " << str << ", which overflows.\n"; << " has value " << str << ", which overflows.\n";
printf("%s", msg.GetString().c_str()); printf("%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
return false; return false;
} }
skipping to change at line 1340 skipping to change at line 1374
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
return string_value == nullptr ? default_value return string_value == nullptr ? default_value
: strcmp(string_value, "0") != 0; : strcmp(string_value, "0") != 0;
#endif // defined(GTEST_GET_BOOL_FROM_ENV_) #endif // defined(GTEST_GET_BOOL_FROM_ENV_)
} }
// Reads and returns a 32-bit integer stored in the environment // Reads and returns a 32-bit integer stored in the environment
// variable corresponding to the given flag; if it isn't set or // variable corresponding to the given flag; if it isn't set or
// doesn't represent a valid 32-bit integer, returns default_value. // doesn't represent a valid 32-bit integer, returns default_value.
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) {
#if defined(GTEST_GET_INT32_FROM_ENV_) #if defined(GTEST_GET_INT32_FROM_ENV_)
return GTEST_GET_INT32_FROM_ENV_(flag, default_value); return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
#else #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
if (string_value == nullptr) { if (string_value == nullptr) {
// The environment variable is not set. // The environment variable is not set.
return default_value; return default_value;
} }
Int32 result = default_value; int32_t result = default_value;
if (!ParseInt32(Message() << "Environment variable " << env_var, if (!ParseInt32(Message() << "Environment variable " << env_var,
string_value, &result)) { string_value, &result)) {
printf("The default value %s is used.\n", printf("The default value %s is used.\n",
(Message() << default_value).GetString().c_str()); (Message() << default_value).GetString().c_str());
fflush(stdout); fflush(stdout);
return default_value; return default_value;
} }
return result; return result;
#endif // defined(GTEST_GET_INT32_FROM_ENV_) #endif // defined(GTEST_GET_INT32_FROM_ENV_)
 End of changes. 14 change blocks. 
19 lines changed or deleted 58 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)