From: <ik...@us...> - 2008-03-28 04:55:30
|
Revision: 1358 http://cutter.svn.sourceforge.net/cutter/?rev=1358&view=rev Author: ikezoe Date: 2008-03-27 21:55:26 -0700 (Thu, 27 Mar 2008) Log Message: ----------- * cutter/cut-test-context.c: Just fork. Modified Paths: -------------- trunk/ChangeLog trunk/cutter/cut-test-context.c Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-03-28 03:27:35 UTC (rev 1357) +++ trunk/ChangeLog 2008-03-28 04:55:26 UTC (rev 1358) @@ -3,6 +3,7 @@ * test/test-cut-fork.c: Added sample test. * cutter/cut-experimental.h, cutter/cut-public.h: Declare fork function. + * cutter/cut-test-context.c: Just fork. 2008-03-27 Hiroyuki Ikezoe <poi...@ik...> Modified: trunk/cutter/cut-test-context.c =================================================================== --- trunk/cutter/cut-test-context.c 2008-03-28 03:27:35 UTC (rev 1357) +++ trunk/cutter/cut-test-context.c 2008-03-28 04:55:26 UTC (rev 1358) @@ -26,6 +26,10 @@ #include <stdlib.h> #include <string.h> #include <setjmp.h> +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> +#include <errno.h> #include <glib.h> #include "cut-test-context.h" @@ -45,6 +49,7 @@ GList *taken_strings; gpointer user_data; GDestroyNotify user_data_destroy_notify; + GArray *forks; }; enum @@ -118,9 +123,21 @@ priv->user_data = NULL; priv->user_data_destroy_notify = NULL; + + priv->forks = g_array_new(FALSE, FALSE, sizeof(gint)); } static void +close_all_pids (GArray *forks) +{ + gint i; + + for (i = 0; i < forks->len; i++) { + kill(g_array_index(forks, gint, i), SIGKILL); + } +} + +static void dispose (GObject *object) { CutTestContextPrivate *priv = CUT_TEST_CONTEXT_GET_PRIVATE(object); @@ -140,6 +157,12 @@ priv->test = NULL; } + if (priv->forks) { + close_all_pids(priv->forks); + g_array_free(priv->forks, TRUE); + priv->forks = NULL; + } + g_list_foreach(priv->taken_strings, (GFunc)g_free, NULL); g_list_free(priv->taken_strings); priv->taken_strings = NULL; @@ -418,6 +441,66 @@ g_string_free(inspected, FALSE)); } + +static int +sane_dup2 (int fd1, int fd2) +{ + int ret; + do + ret = dup2 (fd1, fd2); + while (ret < 0 && errno == EINTR); + return ret; +} + +int +cut_test_context_trap_fork (CutTestContext *context, + unsigned int time_out) +{ + CutTestContextPrivate *priv = CUT_TEST_CONTEXT_GET_PRIVATE(context); + pid_t pid; + + int stdout_pipe[2] = { -1, -1 }; + int stderr_pipe[2] = { -1, -1 }; + int stdtst_pipe[2] = { -1, -1 }; + + if (pipe(stdout_pipe) < 0 || + pipe(stderr_pipe) < 0 || + pipe(stdtst_pipe) < 0) { + return -1; + } + + pid = fork(); + if (pid < 0) + return -1; + + if (pid == 0) { + int fd0 = -1; + close(stdout_pipe[0]); + close(stderr_pipe[0]); + close(stdtst_pipe[0]); + + if (sane_dup2(stdout_pipe[1], 1) < 0 || + sane_dup2(stderr_pipe[1], 2) < 0 || + (fd0 >= 0 && sane_dup2(fd0, 0) < 0)) { + } + + if (fd0 >= 3) + close(fd0); + if (stdout_pipe[1] >= 3) + close(stdout_pipe[1]); + if (stderr_pipe[1] >= 3) + close(stderr_pipe[1]); + return 0; + } else { + g_array_append_val(priv->forks, pid); + + close(stdout_pipe[1]); + close(stderr_pipe[1]); + close(stdtst_pipe[1]); + return pid; + } +} + /* -vi:nowrap:ai:expandtab:sw=4 +vi:ts=4:nowrap:ai:expandtab:sw=4 */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |