* Boston, MA 02111-1307, USA.
*/
-#include "config.h"
+#include "../lib/libcompat.h"
#include <string.h>
#include <stdio.h>
static void suite_free (Suite * s);
static void tcase_free (TCase * tc);
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#undef malloc
-#undef realloc
-#undef strsignal
-
-#include <sys/types.h>
-
-void *malloc (size_t n);
-void *realloc (void *p, size_t n);
-char *strsignal (int sig);
-
-void *rpl_malloc (size_t n);
-void *rpl_realloc (void *p, size_t n);
-static const char *rpl_strsignal (int sig);
-
-/* Allocate an N-byte block of memory from the heap. If N is zero,
- allocate a 1-byte block. */
-void *
-rpl_malloc (size_t n)
-{
- if (n == 0)
- n = 1;
- return malloc (n);
-}
-
-/* AC_FUNC_REALLOC in configure defines realloc to rpl_realloc if
- realloc(0,0) is NULL to make it GNU compatible and always return a
- valid pointer, same for AC_FUNC_MALLOC, malloc, and rpl_malloc.
- rpl means `replacement'.
-
- If this ever turns out to be a problem, it might be easiest to just
- kill the configure macro calls.
- */
-void *
-rpl_realloc (void *p, size_t n)
-{
- if (n == 0)
- n = 1;
- if (p == 0)
- return malloc (n);
- return realloc (p, n);
-}
-
-/* We simply don't have strsignal on some platforms. This function
- should get used if AC_REPLACE_FUNCS([strsignal]) cannot find
- something acceptable. Note that Gnulib has a much much much more
- advanced version of strsignal, but we don't really care.
-*/
-static const char *
-rpl_strsignal (int sig)
-{
- static char signame[40];
-
- sprintf (signame, "SIG #%d", sig);
- return signame;
-}
-
Suite *
suite_create (const char *name)
{
}
}
+ env = getenv ("CK_TIMEOUT_MULTIPLIER");
+ if (env != NULL) {
+ int tmp = atoi (env);
+ if (tmp >= 0) {
+ timeout = timeout * tmp;
+ }
+ }
+
tc->timeout = timeout;
tc->tflst = check_list_create ();
tc->unch_sflst = check_list_create ();
}
void
-_tcase_add_test (TCase * tc, TFun fn, const char *name, int _signal, int start,
- int end)
+_tcase_add_test (TCase * tc, TFun fn, const char *name, int _signal,
+ int allowed_exit_value, int start, int end)
{
TF *tf;
if (tc == NULL || fn == NULL || name == NULL)
tf->loop_start = start;
tf->loop_end = end;
tf->signal = _signal; /* 0 means no signal expected */
+ tf->allowed_exit_value = allowed_exit_value; /* 0 is default successful exit */
tf->name = name;
list_add_end (tc->tflst, tf);
}
void
tcase_set_timeout (TCase * tc, int timeout)
{
- if (timeout >= 0)
+ if (timeout >= 0) {
+ char *env = getenv ("CK_TIMEOUT_MULTIPLIER");
+ if (env != NULL) {
+ int tmp = atoi (env);
+ if (tmp >= 0) {
+ timeout = timeout * tmp;
+ }
+ }
tc->timeout = timeout;
+ }
}
void
-tcase_fn_start (const char *fname, const char *file, int line)
+tcase_fn_start (const char *fname CK_ATTRIBUTE_UNUSED, const char *file,
+ int line)
{
send_ctx_info (CK_CTX_TEST);
send_loc_info (file, line);
vsnprintf (buf, BUFSIZ, msg, ap);
va_end (ap);
send_failure_info (buf);
- if (cur_fork_status () == CK_FORK)
+ if (cur_fork_status () == CK_FORK) {
+#ifdef _POSIX_VERSION
exit (1);
+#endif /* _POSIX_VERSION */
+ }
}
}
/* Add a test function with signal handling to a test case (macro version) */
#define tcase_add_test_raise_signal(tc,tf,signal) \
- _tcase_add_test((tc),(tf),"" # tf "",(signal), 0, 1)
+ _tcase_add_test((tc),(tf),"" # tf "",(signal), 0, 0, 1)
+
+/* Add a test function with an expected exit value to a test case (macro version) */
+#define tcase_add_exit_test(tc, tf, expected_exit_value) \
+ _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),0,1)
/* Add a looping test function to a test case (macro version)
available in the test.
*/
#define tcase_add_loop_test(tc,tf,s,e) \
- _tcase_add_test((tc),(tf),"" # tf "",0,(s),(e))
+ _tcase_add_test((tc),(tf),"" # tf "",0,0,(s),(e))
/* Signal version of loop test.
FIXME: add a test case; this is untested as part of Check's tests.
*/
#define tcase_add_loop_test_raise_signal(tc,tf,signal,s,e) \
- _tcase_add_test((tc),(tf),"" # tf "",(signal),(s),(e))
+ _tcase_add_test((tc),(tf),"" # tf "",(signal),0,(s),(e))
+
+/* allowed exit value version of loop test. */
+#define tcase_add_loop_exit_test(tc,tf,expected_exit_value,s,e) \
+ _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),(s),(e))
/* Add a test function to a test case
(function version -- use this when the macro won't work
*/
-void CK_EXPORT _tcase_add_test (TCase *tc, TFun tf, const char *fname, int _signal, int start, int end);
+void CK_EXPORT _tcase_add_test (TCase *tc, TFun tf, const char *fname, int _signal, int allowed_exit_value, int start, int end);
/* Add unchecked fixture setup/teardown functions to a test case
One must use braces within a START_/END_ pair to declare new variables
*/
#define START_TEST(__testname)\
-static void __testname (int CK_ATTRIBUTE_UNUSED _i)\
+static void __testname (int _i CK_ATTRIBUTE_UNUSED)\
{\
tcase_fn_start (""# __testname, __FILE__, __LINE__);
CK_NORMAL, /* All failed tests */
CK_VERBOSE, /* All tests */
CK_ENV, /* Look at environment var */
+#if @ENABLE_SUBUNIT@
+ CK_SUBUNIT, /* Run as a subunit child process */
+#endif
CK_LAST
};
* Boston, MA 02111-1307, USA.
*/
-#include "config.h"
+#include "../lib/libcompat.h"
#include <stdlib.h>
#include <stdio.h>
-#include <sys/time.h>
-#include <time.h>
#include <check.h>
+#if HAVE_SUBUNIT_CHILD_H
+#include <subunit/child.h>
+#endif
#include "check_error.h"
#include "check_list.h"
#include "check_impl.h"
#include "check_log.h"
#include "check_print.h"
+#include "check_str.h"
static void srunner_send_evt (SRunner * sr, void *obj, enum cl_event evt);
srunner_send_evt (sr, s, CLEND_S);
}
+void
+log_test_start (SRunner * sr, TCase * tc, TF * tfun)
+{
+ char buffer[100];
+ snprintf (buffer, 99, "%s:%s", tc->name, tfun->name);
+ srunner_send_evt (sr, buffer, CLSTART_T);
+}
+
void
log_test_end (SRunner * sr, TestResult * tr)
{
stdout_lfun (SRunner * sr, FILE * file, enum print_output printmode,
void *obj, enum cl_event evt)
{
- TestResult *tr;
Suite *s;
if (printmode == CK_ENV) {
case CLEND_S:
s = obj;
break;
+ case CLSTART_T:
+ break;
case CLEND_T:
- tr = obj;
break;
default:
eprintf ("Bad event type received in stdout_lfun", __FILE__, __LINE__);
}
void
-lfile_lfun (SRunner * sr, FILE * file, enum print_output printmode,
- void *obj, enum cl_event evt)
+lfile_lfun (SRunner * sr, FILE * file,
+ enum print_output printmode CK_ATTRIBUTE_UNUSED, void *obj,
+ enum cl_event evt)
{
TestResult *tr;
Suite *s;
case CLEND_S:
s = obj;
break;
+ case CLSTART_T:
+ break;
case CLEND_T:
tr = obj;
tr_fprint (file, tr, CK_VERBOSE);
break;
default:
- eprintf ("Bad event type received in stdout_lfun", __FILE__, __LINE__);
+ eprintf ("Bad event type received in lfile_lfun", __FILE__, __LINE__);
}
}
void
-xml_lfun (SRunner * sr, FILE * file, enum print_output printmode,
- void *obj, enum cl_event evt)
+xml_lfun (SRunner * sr CK_ATTRIBUTE_UNUSED, FILE * file,
+ enum print_output printmode CK_ATTRIBUTE_UNUSED, void *obj,
+ enum cl_event evt)
{
TestResult *tr;
Suite *s;
fprintf (file, " </suite>\n");
s = obj;
break;
+ case CLSTART_T:
+ break;
case CLEND_T:
tr = obj;
tr_xmlprint (file, tr, CK_VERBOSE);
}
+#if ENABLE_SUBUNIT
+void
+subunit_lfun (SRunner * sr, FILE * file, enum print_output printmode,
+ void *obj, enum cl_event evt)
+{
+ TestResult *tr;
+ Suite *s;
+ char const *name;
+
+ /* assert(printmode == CK_SUBUNIT); */
+
+ switch (evt) {
+ case CLINITLOG_SR:
+ break;
+ case CLENDLOG_SR:
+ break;
+ case CLSTART_SR:
+ break;
+ case CLSTART_S:
+ s = obj;
+ break;
+ case CLEND_SR:
+ if (printmode > CK_SILENT) {
+ fprintf (file, "\n");
+ srunner_fprint (file, sr, printmode);
+ }
+ break;
+ case CLEND_S:
+ s = obj;
+ break;
+ case CLSTART_T:
+ name = obj;
+ subunit_test_start (name);
+ break;
+ case CLEND_T:
+ tr = obj;
+ {
+ char *name = ck_strdup_printf ("%s:%s", tr->tcname, tr->tname);
+ char *msg = tr_short_str (tr);
+ switch (tr->rtype) {
+ case CK_PASS:
+ subunit_test_pass (name);
+ break;
+ case CK_FAILURE:
+ subunit_test_fail (name, msg);
+ break;
+ case CK_ERROR:
+ subunit_test_error (name, msg);
+ break;
+ default:
+ eprintf ("Bad result type in subunit_lfun", __FILE__, __LINE__);
+ free (name);
+ free (msg);
+ }
+ }
+ break;
+ default:
+ eprintf ("Bad event type received in subunit_lfun", __FILE__, __LINE__);
+ }
+}
+#endif
FILE *
srunner_open_lfile (SRunner * sr)
{
FILE *f;
sr->loglst = check_list_create ();
- srunner_register_lfun (sr, stdout, 0, stdout_lfun, print_mode);
+#if ENABLE_SUBUNIT
+ if (print_mode != CK_SUBUNIT)
+#endif
+ srunner_register_lfun (sr, stdout, 0, stdout_lfun, print_mode);
+#if ENABLE_SUBUNIT
+ else
+ srunner_register_lfun (sr, stdout, 0, subunit_lfun, print_mode);
+#endif
f = srunner_open_lfile (sr);
if (f) {
srunner_register_lfun (sr, f, 1, lfile_lfun, print_mode);
* Boston, MA 02111-1307, USA.
*/
-#define _GNU_SOURCE
-#include "config.h"
+#include "../lib/libcompat.h"
#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
CK_NOFORK_FIXTURE
};
+/* all functions are defined in the same order they are declared.
+ functions that depend on forking are gathered all together.
+ non-static functions are at the end of the file. */
static void srunner_run_init (SRunner * sr, enum print_output print_mode);
static void srunner_run_end (SRunner * sr, enum print_output print_mode);
static void srunner_iterate_suites (SRunner * sr, enum print_output print_mode);
-static void srunner_run_tcase (SRunner * sr, TCase * tc);
+static void srunner_iterate_tcase_tfuns (SRunner * sr, TCase * tc);
+static void srunner_add_failure (SRunner * sr, TestResult * tf);
static int srunner_run_unchecked_setup (SRunner * sr, TCase * tc);
-static void srunner_run_unchecked_teardown (SRunner * sr, TCase * tc);
static TestResult *tcase_run_checked_setup (SRunner * sr, TCase * tc);
+static void srunner_run_teardown (List * l);
+static void srunner_run_unchecked_teardown (TCase * tc);
static void tcase_run_checked_teardown (TCase * tc);
-static void srunner_iterate_tcase_tfuns (SRunner * sr, TCase * tc);
-static void srunner_add_failure (SRunner * sr, TestResult * tf);
-static TestResult *tcase_run_tfun_fork (SRunner * sr, TCase * tc, TF * tf,
- int i);
+static void srunner_run_tcase (SRunner * sr, TCase * tc);
static TestResult *tcase_run_tfun_nofork (SRunner * sr, TCase * tc, TF * tf,
int i);
-static TestResult *receive_result_info_fork (const char *tcname,
- const char *tname, int iter, int status, int expected_signal);
static TestResult *receive_result_info_nofork (const char *tcname,
const char *tname, int iter);
-static void set_fork_info (TestResult * tr, int status, int expected_signal);
static void set_nofork_info (TestResult * tr);
+static char *pass_msg (void);
+
+#ifdef _POSIX_VERSION
+static TestResult *tcase_run_tfun_fork (SRunner * sr, TCase * tc, TF * tf,
+ int i);
+static TestResult *receive_result_info_fork (const char *tcname,
+ const char *tname, int iter, int status, int expected_signal,
+ unsigned char allowed_exit_value);
+static void set_fork_info (TestResult * tr, int status, int expected_signal,
+ unsigned char allowed_exit_value);
static char *signal_msg (int sig);
static char *signal_error_msg (int signal_received, int signal_expected);
-static char *pass_msg (void);
static char *exit_msg (int exitstatus);
static int waserror (int status, int expected_signal);
-#define MSG_LEN 100
-
static int alarm_received;
static pid_t group_pid;
-static void
+static void CK_ATTRIBUTE_UNUSED
sig_handler (int sig_nr)
{
switch (sig_nr) {
break;
}
}
+#endif /* _POSIX_VERSION */
+
+#define MSG_LEN 100
static void
srunner_run_init (SRunner * sr, enum print_output print_mode)
}
static void
-srunner_run_end (SRunner * sr, enum print_output print_mode)
+srunner_run_end (SRunner * sr, enum print_output CK_ATTRIBUTE_UNUSED print_mode)
{
log_srunner_end (sr);
srunner_end_logging (sr);
}
static void
-srunner_iterate_suites (SRunner * sr, enum print_output print_mode)
+srunner_iterate_suites (SRunner * sr,
+ enum print_output CK_ATTRIBUTE_UNUSED print_mode)
{
List *slst;
List *tcl;
}
}
-void
-srunner_run_all (SRunner * sr, enum print_output print_mode)
-{
- struct sigaction old_action;
- struct sigaction new_action;
-
- if (sr == NULL)
- return;
- if (print_mode >= CK_LAST) {
- eprintf ("Bad print_mode argument to srunner_run_all: %d",
- __FILE__, __LINE__, print_mode);
- }
- memset (&new_action, 0, sizeof new_action);
- new_action.sa_handler = sig_handler;
- sigaction (SIGALRM, &new_action, &old_action);
- srunner_run_init (sr, print_mode);
- srunner_iterate_suites (sr, print_mode);
- srunner_run_end (sr, print_mode);
- sigaction (SIGALRM, &old_action, NULL);
-}
-
-static void
-srunner_add_failure (SRunner * sr, TestResult * tr)
-{
- list_add_end (sr->resultlst, tr);
- sr->stats->n_checked++; /* count checks during setup, test, and teardown */
- if (tr->rtype == CK_FAILURE)
- sr->stats->n_failed++;
- else if (tr->rtype == CK_ERROR)
- sr->stats->n_errors++;
-
-}
-
static void
srunner_iterate_tcase_tfuns (SRunner * sr, TCase * tc)
{
tfun = list_val (tfl);
for (i = tfun->loop_start; i < tfun->loop_end; i++) {
+ log_test_start (sr, tc, tfun);
switch (srunner_fork_status (sr)) {
case CK_FORK:
+#ifdef _POSIX_VERSION
tr = tcase_run_tfun_fork (sr, tc, tfun, i);
+#else /* _POSIX_VERSION */
+ eprintf ("This version does not support fork", __FILE__, __LINE__);
+#endif /* _POSIX_VERSION */
break;
case CK_NOFORK:
tr = tcase_run_tfun_nofork (sr, tc, tfun, i);
}
}
+static void
+srunner_add_failure (SRunner * sr, TestResult * tr)
+{
+ list_add_end (sr->resultlst, tr);
+ sr->stats->n_checked++; /* count checks during setup, test, and teardown */
+ if (tr->rtype == CK_FAILURE)
+ sr->stats->n_failed++;
+ else if (tr->rtype == CK_ERROR)
+ sr->stats->n_errors++;
+
+}
+
static int
srunner_run_unchecked_setup (SRunner * sr, TCase * tc)
{
}
static void
-tcase_run_checked_teardown (TCase * tc)
+srunner_run_teardown (List * l)
{
- List *l;
Fixture *f;
- l = tc->ch_tflst;
-
- send_ctx_info (CK_CTX_TEARDOWN);
-
for (list_front (l); !list_at_end (l); list_advance (l)) {
f = list_val (l);
+ send_ctx_info (CK_CTX_TEARDOWN);
f->fun ();
}
}
static void
-srunner_run_unchecked_teardown (SRunner * sr, TCase * tc)
+srunner_run_unchecked_teardown (TCase * tc)
{
- List *l;
- Fixture *f;
-
- set_fork_status (CK_NOFORK);
- l = tc->unch_tflst;
-
- for (list_front (l); !list_at_end (l); list_advance (l)) {
+ srunner_run_teardown (tc->unch_tflst);
+}
- f = list_val (l);
- send_ctx_info (CK_CTX_TEARDOWN);
- f->fun ();
- }
- set_fork_status (srunner_fork_status (sr));
+static void
+tcase_run_checked_teardown (TCase * tc)
+{
+ srunner_run_teardown (tc->ch_tflst);
}
static void
{
if (srunner_run_unchecked_setup (sr, tc)) {
srunner_iterate_tcase_tfuns (sr, tc);
- srunner_run_unchecked_teardown (sr, tc);
+ srunner_run_unchecked_teardown (tc);
}
}
static TestResult *
-receive_result_info_fork (const char *tcname,
- const char *tname, int iter, int status, int expected_signal)
+tcase_run_tfun_nofork (SRunner * sr, TCase * tc, TF * tfun, int i)
{
TestResult *tr;
- tr = receive_test_result (waserror (status, expected_signal));
+ tr = tcase_run_checked_setup (sr, tc);
+ if (tr == NULL) {
+ tfun->fn (i);
+ tcase_run_checked_teardown (tc);
+ return receive_result_info_nofork (tc->name, tfun->name, i);
+ }
+
+ return tr;
+}
+
+static TestResult *
+receive_result_info_nofork (const char *tcname, const char *tname, int iter)
+{
+ TestResult *tr;
+
+ tr = receive_test_result (0);
if (tr == NULL)
eprintf ("Failed to receive test result", __FILE__, __LINE__);
tr->tcname = tcname;
tr->tname = tname;
tr->iter = iter;
- set_fork_info (tr, status, expected_signal);
+ set_nofork_info (tr);
return tr;
}
+static void
+set_nofork_info (TestResult * tr)
+{
+ if (tr->msg == NULL) {
+ tr->rtype = CK_PASS;
+ tr->msg = pass_msg ();
+ } else {
+ tr->rtype = CK_FAILURE;
+ }
+}
+
+static char *
+pass_msg (void)
+{
+ char *msg = emalloc (sizeof ("Passed"));
+ strcpy (msg, "Passed");
+ return msg;
+}
+
+#ifdef _POSIX_VERSION
static TestResult *
-receive_result_info_nofork (const char *tcname, const char *tname, int iter)
+tcase_run_tfun_fork (SRunner * sr, TCase * tc, TF * tfun, int i)
+{
+ pid_t pid_w;
+ pid_t pid;
+ int status = 0;
+
+ pid = fork ();
+ if (pid == -1)
+ eprintf ("Error in call to fork:", __FILE__, __LINE__ - 2);
+ if (pid == 0) {
+ setpgid (0, 0);
+ group_pid = getpgrp ();
+ tcase_run_checked_setup (sr, tc);
+ tfun->fn (i);
+ tcase_run_checked_teardown (tc);
+ exit (EXIT_SUCCESS);
+ } else {
+ group_pid = pid;
+ }
+
+ alarm_received = 0;
+ alarm (tc->timeout);
+ do {
+ pid_w = waitpid (pid, &status, 0);
+ } while (pid_w == -1);
+
+ killpg (pid, SIGKILL); /* Kill remaining processes. */
+
+ return receive_result_info_fork (tc->name, tfun->name, i, status,
+ tfun->signal, tfun->allowed_exit_value);
+}
+
+static TestResult *
+receive_result_info_fork (const char *tcname,
+ const char *tname,
+ int iter, int status, int expected_signal, unsigned char allowed_exit_value)
{
TestResult *tr;
- tr = receive_test_result (0);
+ tr = receive_test_result (waserror (status, expected_signal));
if (tr == NULL)
eprintf ("Failed to receive test result", __FILE__, __LINE__);
tr->tcname = tcname;
tr->tname = tname;
tr->iter = iter;
- set_nofork_info (tr);
+ set_fork_info (tr, status, expected_signal, allowed_exit_value);
return tr;
}
static void
-set_fork_info (TestResult * tr, int status, int signal_expected)
+set_fork_info (TestResult * tr, int status, int signal_expected,
+ unsigned char allowed_exit_value)
{
int was_sig = WIFSIGNALED (status);
int was_exit = WIFEXITED (status);
tr->msg = signal_msg (signal_received);
}
} else if (signal_expected == 0) {
- if (was_exit && exit_status == 0) {
+ if (was_exit && exit_status == allowed_exit_value) {
tr->rtype = CK_PASS;
tr->msg = pass_msg ();
- } else if (was_exit && exit_status != 0) {
+ } else if (was_exit && exit_status != allowed_exit_value) {
if (tr->msg == NULL) { /* early exit */
tr->rtype = CK_ERROR;
tr->msg = exit_msg (exit_status);
} else { /* a signal was expected and none raised */
if (was_exit) {
tr->msg = exit_msg (exit_status);
- if (exit_status == 0)
+ if (exit_status == allowed_exit_value)
tr->rtype = CK_FAILURE; /* normal exit status */
else
tr->rtype = CK_FAILURE; /* early exit */
}
}
-static void
-set_nofork_info (TestResult * tr)
-{
- if (tr->msg == NULL) {
- tr->rtype = CK_PASS;
- tr->msg = pass_msg ();
- } else {
- tr->rtype = CK_FAILURE;
- }
-}
-
-static TestResult *
-tcase_run_tfun_nofork (SRunner * sr, TCase * tc, TF * tfun, int i)
-{
- TestResult *tr;
-
- tr = tcase_run_checked_setup (sr, tc);
- if (tr == NULL) {
- tfun->fn (i);
- tcase_run_checked_teardown (tc);
- return receive_result_info_nofork (tc->name, tfun->name, i);
- }
-
- return tr;
-}
-
-
-static TestResult *
-tcase_run_tfun_fork (SRunner * sr, TCase * tc, TF * tfun, int i)
+static char *
+signal_msg (int signal)
{
- pid_t pid_w;
- pid_t pid;
- int status = 0;
- pid = fork ();
- if (pid == -1)
- eprintf ("Error in call to fork:", __FILE__, __LINE__ - 2);
- if (pid == 0) {
- setpgid (0, 0);
- group_pid = getpgrp ();
- tcase_run_checked_setup (sr, tc);
- tfun->fn (i);
- tcase_run_checked_teardown (tc);
- exit (EXIT_SUCCESS);
+ char *msg = emalloc (MSG_LEN); /* free'd by caller */
+ if (alarm_received) {
+ snprintf (msg, MSG_LEN, "Test timeout expired");
} else {
- group_pid = pid;
+ snprintf (msg, MSG_LEN, "Received signal %d (%s)",
+ signal, strsignal (signal));
}
-
- alarm_received = 0;
- alarm (tc->timeout);
- do {
- pid_w = waitpid (pid, &status, 0);
- } while (pid_w == -1);
-
- killpg (pid, SIGKILL); /* Kill remaining processes. */
-
- return receive_result_info_fork (tc->name, tfun->name, i, status,
- tfun->signal);
+ return msg;
}
static char *
return msg;
}
-static char *
-signal_msg (int signal)
-{
- char *msg = emalloc (MSG_LEN); /* free'd by caller */
- if (alarm_received) {
- snprintf (msg, MSG_LEN, "Test timeout expired");
- } else {
- snprintf (msg, MSG_LEN, "Received signal %d (%s)",
- signal, strsignal (signal));
- }
- return msg;
-}
-
static char *
exit_msg (int exitval)
{
return msg;
}
-static char *
-pass_msg (void)
+static int
+waserror (int status, int signal_expected)
{
- char *msg = emalloc (sizeof ("Passed"));
- strcpy (msg, "Passed");
- return msg;
+ int was_sig = WIFSIGNALED (status);
+ int was_exit = WIFEXITED (status);
+ int exit_status = WEXITSTATUS (status);
+ int signal_received = WTERMSIG (status);
+
+ return ((was_sig && (signal_received != signal_expected)) ||
+ (was_exit && exit_status != 0));
}
+#endif /* _POSIX_VERSION */
enum fork_status
srunner_fork_status (SRunner * sr)
return CK_FORK;
if (strcmp (env, "no") == 0)
return CK_NOFORK;
- else
+ else {
+#ifdef _POSIX_VERSION
return CK_FORK;
+#else /* _POSIX_VERSION */
+ eprintf ("This version does not support fork", __FILE__, __LINE__);
+ return CK_NOFORK;
+#endif /* _POSIX_VERSION */
+ }
} else
return sr->fstat;
}
sr->fstat = fstat;
}
+void
+srunner_run_all (SRunner * sr, enum print_output print_mode)
+{
+#ifdef _POSIX_VERSION
+ struct sigaction old_action;
+ struct sigaction new_action;
+#endif /* _POSIX_VERSION */
+
+ if (sr == NULL)
+ return;
+ if (print_mode >= CK_LAST) {
+ eprintf ("Bad print_mode argument to srunner_run_all: %d",
+ __FILE__, __LINE__, print_mode);
+ }
+#ifdef _POSIX_VERSION
+ memset (&new_action, 0, sizeof new_action);
+ new_action.sa_handler = sig_handler;
+ sigaction (SIGALRM, &new_action, &old_action);
+#endif /* _POSIX_VERSION */
+ srunner_run_init (sr, print_mode);
+ srunner_iterate_suites (sr, print_mode);
+ srunner_run_end (sr, print_mode);
+#ifdef _POSIX_VERSION
+ sigaction (SIGALRM, &old_action, NULL);
+#endif /* _POSIX_VERSION */
+}
+
pid_t
check_fork (void)
{
+#ifdef _POSIX_VERSION
pid_t pid = fork ();
/* Set the process to a process group to be able to kill it easily. */
setpgid (pid, group_pid);
return pid;
+#else /* _POSIX_VERSION */
+ eprintf ("This version does not support fork", __FILE__, __LINE__);
+ return 0;
+#endif /* _POSIX_VERSION */
}
void
-check_waitpid_and_exit (pid_t pid)
+check_waitpid_and_exit (pid_t pid CK_ATTRIBUTE_UNUSED)
{
+#ifdef _POSIX_VERSION
pid_t pid_w;
int status;
do {
pid_w = waitpid (pid, &status, 0);
} while (pid_w == -1);
- if (waserror (status, 0))
+ if (waserror (status, 0)) {
exit (EXIT_FAILURE);
+ }
}
exit (EXIT_SUCCESS);
-}
-
-static int
-waserror (int status, int signal_expected)
-{
- int was_sig = WIFSIGNALED (status);
- int was_exit = WIFEXITED (status);
- int exit_status = WEXITSTATUS (status);
- int signal_received = WTERMSIG (status);
-
- return ((was_sig && (signal_received != signal_expected)) ||
- (was_exit && exit_status != 0));
+#else /* _POSIX_VERSION */
+ eprintf ("This version does not support fork", __FILE__, __LINE__);
+#endif /* _POSIX_VERSION */
}