[PATCH xorg-gtest 10/11] process: terminate the child if the parent dies
Chase Douglas
chase.douglas at canonical.com
Thu Aug 16 08:39:40 PDT 2012
On 08/15/2012 11:36 PM, Peter Hutterer wrote:
> It's annoying to have the forked X server linger around when the test
> segfaults, so make sure we take it down with us.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> src/process.cpp | 5 +++++
> test/process-test.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 50 insertions(+)
>
> diff --git a/src/process.cpp b/src/process.cpp
> index 4e903d6..d962a4c 100644
> --- a/src/process.cpp
> +++ b/src/process.cpp
> @@ -27,6 +27,7 @@
>
> #include "xorg/gtest/xorg-gtest-process.h"
>
> +#include <sys/prctl.h>
> #include <sys/types.h>
> #include <sys/wait.h>
> #include <unistd.h>
> @@ -81,6 +82,10 @@ void xorg::testing::Process::Start(const std::string &program, const std::vector
> close(2);
> }
>
> +#ifdef __linux
> + prctl(PR_SET_PDEATHSIG, SIGTERM);
> +#endif
I had been looking around for this ^^ for a while! It's just what we
need to fully clean things up. Good find :).
> +
> std::vector<char*> args;
> std::vector<std::string>::const_iterator it;
>
> diff --git a/test/process-test.cpp b/test/process-test.cpp
> index dc5402c..183b9f8 100644
> --- a/test/process-test.cpp
> +++ b/test/process-test.cpp
> @@ -1,3 +1,5 @@
> +#include <errno.h>
> +#include <unistd.h>
> #include <sys/types.h>
> #include <sys/wait.h>
>
> @@ -63,6 +65,49 @@ TEST(Process, TerminationFailure)
> ASSERT_EQ(p.GetState(), Process::FINISHED_FAILURE);
> }
>
> +TEST(Process, ChildTearDown)
> +{
> + SCOPED_TRACE("TESTCASE: ensure child process dies when parent does");
> +
> + int pipefd[2];
> + ASSERT_NE(pipe(pipefd), -1);
> +
> + /* Fork, the child will spawn a Process, write that Process's PID to a
> + pipe and then kill itself. The parent checks that the child was
> + terminated when the parent was killed.
> + */
> + pid_t pid = fork();
> + if (pid == 0) { /* child */
> + close(pipefd[0]);
> +
> + Process p;
> + p.Start("sleep", "1000", NULL); /* forks another child */
> + ASSERT_GT(p.Pid(), 0);
> +
> + char *buffer;
> + ASSERT_GT(asprintf(&buffer, "%d", p.Pid()), 0);
> + ASSERT_EQ(write(pipefd[1], buffer, strlen(buffer)), (int)strlen(buffer));
> + close(pipefd[1]);
> +
> + raise(SIGKILL);
> + } else { /* parent */
> + close(pipefd[1]);
> +
> + char buffer[20] = {0};
> + ASSERT_GT(read(pipefd[0], buffer, sizeof(buffer)), 0);
> + close(pipefd[0]);
> +
> + pid_t child_pid = atoi(buffer);
> + for (int i = 0; i < 10; i++) {
> + if (kill(child_pid, 0) != -1)
> + usleep(100);
> +
> + }
> + ASSERT_EQ(kill(child_pid, 0), -1);
> + ASSERT_EQ(errno, ESRCH);
> + }
> +}
> +
>
> int main(int argc, char *argv[]) {
> testing::InitGoogleTest(&argc, argv);
Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
More information about the xorg-devel
mailing list