forked from rpms/glibc
186 lines
7.3 KiB
Diff
186 lines
7.3 KiB
Diff
|
commit 96cd0558bcd69481ccc42e1b392f0c0b36fce2b0
|
||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||
|
Date: Wed Nov 28 19:59:45 2018 +0100
|
||
|
|
||
|
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.
|
||
|
|
||
|
diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c
|
||
|
index 5e3101206919fa1b..85e246cd1131f8e8 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 d5eac84d09ae325f..2d2384e73df0d2d0 100644
|
||
|
--- a/support/capture_subprocess.h
|
||
|
+++ b/support/capture_subprocess.h
|
||
|
@@ -55,13 +55,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 ff5ee89fb02599ae..8b4c352c96227b78 100644
|
||
|
--- a/support/support_capture_subprocess_check.c
|
||
|
+++ b/support/support_capture_subprocess_check.c
|
||
|
@@ -20,6 +20,7 @@
|
||
|
#include <stdio.h>
|
||
|
#include <support/capture_subprocess.h>
|
||
|
#include <support/check.h>
|
||
|
+#include <sys/wait.h>
|
||
|
|
||
|
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 63b6699622f97fcc..99570879eedd65b1 100644
|
||
|
--- a/support/tst-support_capture_subprocess.c
|
||
|
+++ b/support/tst-support_capture_subprocess.c
|
||
|
@@ -285,15 +285,29 @@ do_multiple_tests (enum test_type type)
|
||
|
|
||
|
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);
|