From 96cd0558bcd69481ccc42e1b392f0c0b36fce2b0 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 28 Nov 2018 19:59:45 +0100 Subject: [PATCH] support: Add signal support to support_capture_subprocess_check Signal zero does not terminate a process, so it is safe to use negative values for signal numbers. Adjust libio/tst-vtables-common.c to use this new functionality, instead of determining the termination status for a signal indirectly. --- ChangeLog | 17 +++++++++++++ libio/tst-vtables-common.c | 18 +------------ support/capture_subprocess.h | 15 ++++++----- support/support_capture_subprocess_check.c | 41 ++++++++++++++++++++++++++---- support/tst-support_capture_subprocess.c | 14 ++++++++++ 5 files changed, 77 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 28d7735..75e1b17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2018-11-28 Florian Weimer + + support: Add signal support to support_capture_subprocess_check. + * support/capture_subprocess.h (support_capture_subprocess_check): + Adjust comment and rename parameter. + * support/support_capture_subprocess_check.c + (print_actual_status): New function. + (support_capture_subprocess_check): Support negative + status_or_signal. Call print_actual_status. + * support/tst-support_capture_subprocess.c (do_test): Call + support_capture_subprocess_check. + * libio/tst-vtables-common.c (termination_status) + (init_termination_status): Remove. + (check_for_termination): Adjust support_capture_subprocess_check + call. + (do_test): Remove call to init_termination_status. + 2018-11-28 Joseph Myers * scripts/build-many-glibcs.py (Glibc.build_glibc): Use original diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c index 5e31012..85e246c 100644 --- a/libio/tst-vtables-common.c +++ b/libio/tst-vtables-common.c @@ -380,21 +380,6 @@ without_compatibility_fflush (void *closure) _exit (1); } -/* Exit status after abnormal termination. */ -static int termination_status; - -static void -init_termination_status (void) -{ - pid_t pid = xfork (); - if (pid == 0) - abort (); - xwaitpid (pid, &termination_status, 0); - - TEST_VERIFY (WIFSIGNALED (termination_status)); - TEST_COMPARE (WTERMSIG (termination_status), SIGABRT); -} - static void check_for_termination (const char *name, void (*callback) (void *)) { @@ -404,7 +389,7 @@ check_for_termination (const char *name, void (*callback) (void *)) shared->calls = 0; struct support_capture_subprocess proc = support_capture_subprocess (callback, NULL); - support_capture_subprocess_check (&proc, name, termination_status, + support_capture_subprocess_check (&proc, name, -SIGABRT, sc_allow_stderr); const char *message = "Fatal error: glibc detected an invalid stdio handle\n"; @@ -491,7 +476,6 @@ run_tests (bool initially_disabled) shared = support_shared_allocate (sizeof (*shared)); shared->initially_disabled = initially_disabled; - init_termination_status (); if (initially_disabled) { diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h index b0886ba..4734b87 100644 --- a/support/capture_subprocess.h +++ b/support/capture_subprocess.h @@ -49,13 +49,16 @@ enum support_capture_allow sc_allow_stderr = 0x04, }; -/* Check that the subprocess exited with STATUS and that only the - allowed outputs happened. ALLOWED is a combination of - support_capture_allow flags. Report errors under the CONTEXT - message. */ +/* Check that the subprocess exited and that only the allowed outputs + happened. If STATUS_OR_SIGNAL is nonnegative, it is the expected + (decoded) exit status of the process, as returned by WEXITSTATUS. + If STATUS_OR_SIGNAL is negative, -STATUS_OR_SIGNAL is the expected + termination signal, as returned by WTERMSIG. ALLOWED is a + combination of support_capture_allow flags. Report errors under + the CONTEXT message. */ void support_capture_subprocess_check (struct support_capture_subprocess *, - const char *context, int status, - int allowed) + const char *context, + int status_or_signal, int allowed) __attribute__ ((nonnull (1, 2))); #endif /* SUPPORT_CAPTURE_SUBPROCESS_H */ diff --git a/support/support_capture_subprocess_check.c b/support/support_capture_subprocess_check.c index ff5ee89..8b4c352 100644 --- a/support/support_capture_subprocess_check.c +++ b/support/support_capture_subprocess_check.c @@ -20,6 +20,7 @@ #include #include #include +#include static void print_context (const char *context, bool *failed) @@ -31,9 +32,22 @@ print_context (const char *context, bool *failed) printf ("error: subprocess failed: %s\n", context); } +static void +print_actual_status (struct support_capture_subprocess *proc) +{ + if (WIFEXITED (proc->status)) + printf ("error: actual exit status: %d [0x%x]\n", + WEXITSTATUS (proc->status), proc->status); + else if (WIFSIGNALED (proc->status)) + printf ("error: actual termination signal: %d [0x%x]\n", + WTERMSIG (proc->status), proc->status); + else + printf ("error: actual undecoded exit status: [0x%x]\n", proc->status); +} + void support_capture_subprocess_check (struct support_capture_subprocess *proc, - const char *context, int status, + const char *context, int status_or_signal, int allowed) { TEST_VERIFY ((allowed & sc_allow_none) @@ -44,11 +58,28 @@ support_capture_subprocess_check (struct support_capture_subprocess *proc, || (allowed & sc_allow_stderr)))); bool failed = false; - if (proc->status != status) + if (status_or_signal >= 0) { - print_context (context, &failed); - printf ("error: expected exit status: %d\n", status); - printf ("error: actual exit status: %d\n", proc->status); + /* Expect regular termination. */ + if (!(WIFEXITED (proc->status) + && WEXITSTATUS (proc->status) == status_or_signal)) + { + print_context (context, &failed); + printf ("error: expected exit status: %d\n", status_or_signal); + print_actual_status (proc); + } + } + else + { + /* status_or_signal < 0. Expect termination by signal. */ + if (!(WIFSIGNALED (proc->status) + && WTERMSIG (proc->status) == -status_or_signal)) + { + print_context (context, &failed); + printf ("error: expected termination signal: %d\n", + -status_or_signal); + print_actual_status (proc); + } } if (!(allowed & sc_allow_stdout) && proc->out.length != 0) { diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c index a685256..5339e85 100644 --- a/support/tst-support_capture_subprocess.c +++ b/support/tst-support_capture_subprocess.c @@ -168,15 +168,29 @@ do_test (void) = support_capture_subprocess (callback, &test); check_stream ("stdout", &result.out, test.out); check_stream ("stderr", &result.err, test.err); + + /* Allowed output for support_capture_subprocess_check. */ + int check_allow = 0; + if (lengths[length_idx_stdout] > 0) + check_allow |= sc_allow_stdout; + if (lengths[length_idx_stderr] > 0) + check_allow |= sc_allow_stderr; + if (check_allow == 0) + check_allow = sc_allow_none; + if (test.signal != 0) { TEST_VERIFY (WIFSIGNALED (result.status)); TEST_VERIFY (WTERMSIG (result.status) == test.signal); + support_capture_subprocess_check (&result, "signal", + -SIGTERM, check_allow); } else { TEST_VERIFY (WIFEXITED (result.status)); TEST_VERIFY (WEXITSTATUS (result.status) == test.status); + support_capture_subprocess_check (&result, "exit", + test.status, check_allow); } support_capture_subprocess_free (&result); free (test.out); -- 2.7.4