52
52
# include < sys/wait.h>
53
53
# endif // GTEST_OS_WINDOWS
54
54
55
+ # if GTEST_OS_QNX
56
+ # include < spawn.h>
57
+ # endif // GTEST_OS_QNX
58
+
55
59
#endif // GTEST_HAS_DEATH_TEST
56
60
57
61
#include " gtest/gtest-message.h"
@@ -894,6 +898,7 @@ extern "C" char** environ;
894
898
inline char ** GetEnviron () { return environ; }
895
899
# endif // GTEST_OS_MAC
896
900
901
+ # if !GTEST_OS_QNX
897
902
// The main function for a threadsafe-style death test child process.
898
903
// This function is called in a clone()-ed process and thus must avoid
899
904
// any potentially unsafe operations like malloc or libc functions.
@@ -926,6 +931,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
926
931
GetLastErrnoDescription ().c_str ()));
927
932
return EXIT_FAILURE;
928
933
}
934
+ # endif // !GTEST_OS_QNX
929
935
930
936
// Two utility routines that together determine the direction the stack
931
937
// grows.
@@ -949,14 +955,51 @@ bool StackGrowsDown() {
949
955
return result;
950
956
}
951
957
952
- // A threadsafe implementation of fork(2) for threadsafe-style death tests
953
- // that uses clone(2). It dies with an error message if anything goes
954
- // wrong.
955
- static pid_t ExecDeathTestFork (char * const * argv, int close_fd) {
958
+ // Spawns a child process with the same executable as the current process in
959
+ // a thread-safe manner and instructs it to run the death test. The
960
+ // implementation uses fork(2) + exec. On systems where clone(2) is
961
+ // available, it is used instead, being slightly more thread-safe. On QNX,
962
+ // fork supports only single-threaded environments, so this function uses
963
+ // spawn(2) there instead. The function dies with an error message if
964
+ // anything goes wrong.
965
+ static pid_t ExecDeathTestSpawnChild (char * const * argv, int close_fd) {
956
966
ExecDeathTestArgs args = { argv, close_fd };
957
967
pid_t child_pid = -1 ;
958
968
959
- # if GTEST_HAS_CLONE
969
+ # if GTEST_OS_QNX
970
+ // Obtains the current directory and sets it to be closed in the child
971
+ // process.
972
+ const int cwd_fd = open (" ." , O_RDONLY);
973
+ GTEST_DEATH_TEST_CHECK_ (cwd_fd != -1 );
974
+ GTEST_DEATH_TEST_CHECK_SYSCALL_ (fcntl (cwd_fd, F_SETFD, FD_CLOEXEC));
975
+ // We need to execute the test program in the same environment where
976
+ // it was originally invoked. Therefore we change to the original
977
+ // working directory first.
978
+ const char * const original_dir =
979
+ UnitTest::GetInstance ()->original_working_dir ();
980
+ // We can safely call chdir() as it's a direct system call.
981
+ if (chdir (original_dir) != 0 ) {
982
+ DeathTestAbort (String::Format (" chdir(\" %s\" ) failed: %s" ,
983
+ original_dir,
984
+ GetLastErrnoDescription ().c_str ()));
985
+ return EXIT_FAILURE;
986
+ }
987
+
988
+ int fd_flags;
989
+ // Set close_fd to be closed after spawn.
990
+ GTEST_DEATH_TEST_CHECK_SYSCALL_ (fd_flags = fcntl (close_fd, F_GETFD));
991
+ GTEST_DEATH_TEST_CHECK_SYSCALL_ (fcntl (close_fd, F_SETFD,
992
+ fd_flags | FD_CLOEXEC));
993
+ struct inheritance inherit = {0 };
994
+ // spawn is a system call.
995
+ child_pid = spawn (args.argv [0 ], 0 , NULL , &inherit, args.argv , GetEnviron ());
996
+ // Restores the current working directory.
997
+ GTEST_DEATH_TEST_CHECK_ (fchdir (cwd_fd) != -1 );
998
+ GTEST_DEATH_TEST_CHECK_SYSCALL_ (close (cwd_fd));
999
+
1000
+ # else // GTEST_OS_QNX
1001
+
1002
+ # if GTEST_HAS_CLONE
960
1003
const bool use_fork = GTEST_FLAG (death_test_use_fork);
961
1004
962
1005
if (!use_fork) {
@@ -973,14 +1016,15 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
973
1016
974
1017
GTEST_DEATH_TEST_CHECK_ (munmap (stack, stack_size) != -1 );
975
1018
}
976
- # else
1019
+ # else
977
1020
const bool use_fork = true ;
978
- # endif // GTEST_HAS_CLONE
1021
+ # endif // GTEST_HAS_CLONE
979
1022
980
1023
if (use_fork && (child_pid = fork ()) == 0 ) {
981
1024
ExecDeathTestChildMain (&args);
982
1025
_exit (0 );
983
1026
}
1027
+ # endif // GTEST_OS_QNX
984
1028
985
1029
GTEST_DEATH_TEST_CHECK_ (child_pid != -1 );
986
1030
return child_pid;
@@ -1028,7 +1072,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
1028
1072
// is necessary.
1029
1073
FlushInfoLog ();
1030
1074
1031
- const pid_t child_pid = ExecDeathTestFork (args.Argv (), pipe_fd[0 ]);
1075
+ const pid_t child_pid = ExecDeathTestSpawnChild (args.Argv (), pipe_fd[0 ]);
1032
1076
GTEST_DEATH_TEST_CHECK_SYSCALL_ (close (pipe_fd[1 ]));
1033
1077
set_child_pid (child_pid);
1034
1078
set_read_fd (pipe_fd[0 ]);
0 commit comments