diff options
author | Greg Hackmann <ghackmann@google.com> | 2019-03-19 12:19:41 +0530 |
---|---|---|
committer | Cyril Hrubis <chrubis@suse.cz> | 2019-03-19 14:53:21 +0100 |
commit | 42e5ab9af142f8d9a7ef554472e702f5ca95904c (patch) | |
tree | 62c5fe75c3a19e44ffd7c30db701597d5d53b543 /testcases/kernel | |
parent | 5ac694f3cc6e2b29965a80c386b7abf2ab42e10b (diff) |
syscalls/tgkill03: add new test
Test simple tgkill() error cases.
Signed-off-by: Greg Hackmann <ghackmann@google.com>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Li Wang <liwang@redhat.com>
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Diffstat (limited to 'testcases/kernel')
-rw-r--r-- | testcases/kernel/syscalls/tgkill/.gitignore | 1 | ||||
-rw-r--r-- | testcases/kernel/syscalls/tgkill/tgkill03.c | 111 |
2 files changed, 112 insertions, 0 deletions
diff --git a/testcases/kernel/syscalls/tgkill/.gitignore b/testcases/kernel/syscalls/tgkill/.gitignore index 42be2bb0b..a6d2299da 100644 --- a/testcases/kernel/syscalls/tgkill/.gitignore +++ b/testcases/kernel/syscalls/tgkill/.gitignore @@ -1,2 +1,3 @@ tgkill01 tgkill02 +tgkill03 diff --git a/testcases/kernel/syscalls/tgkill/tgkill03.c b/testcases/kernel/syscalls/tgkill/tgkill03.c new file mode 100644 index 000000000..f5bbdc5a8 --- /dev/null +++ b/testcases/kernel/syscalls/tgkill/tgkill03.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2018 Google, Inc. + * + * Test simple tgkill() error cases. + */ + +#include <pthread.h> +#include <pwd.h> +#include <sys/types.h> + +#include "tst_safe_pthread.h" +#include "tst_test.h" +#include "tgkill.h" + +static pthread_t child_thread; + +static pid_t parent_tgid; +static pid_t parent_tid; +static pid_t child_tid; +static pid_t defunct_tid; + +static const int invalid_pid = -1; + +static void *child_thread_func(void *arg) +{ + child_tid = sys_gettid(); + + TST_CHECKPOINT_WAKE_AND_WAIT(0); + + return arg; +} + +static void *defunct_thread_func(void *arg) +{ + defunct_tid = sys_gettid(); + + return arg; +} + +static void setup(void) +{ + sigset_t sigusr1; + pthread_t defunct_thread; + + sigemptyset(&sigusr1); + sigaddset(&sigusr1, SIGUSR1); + pthread_sigmask(SIG_BLOCK, &sigusr1, NULL); + + parent_tgid = getpid(); + parent_tid = sys_gettid(); + + SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func, NULL); + + TST_CHECKPOINT_WAIT(0); + + SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func, NULL); + + SAFE_PTHREAD_JOIN(defunct_thread, NULL); +} + +static void cleanup(void) +{ + TST_CHECKPOINT_WAKE(0); + + SAFE_PTHREAD_JOIN(child_thread, NULL); +} + +static const struct testcase { + const char *desc; + const int *tgid; + const int *tid; + const int sig; + const int err; +} testcases[] = { + { "Invalid tgid", &invalid_pid, &parent_tid, SIGUSR1, EINVAL }, + { "Invalid tid", &parent_tgid, &invalid_pid, SIGUSR1, EINVAL }, + { "Invalid signal", &parent_tgid, &parent_tid, -1, EINVAL }, + { "Defunct tid", &parent_tgid, &defunct_tid, SIGUSR1, ESRCH }, + { "Defunct tgid", &defunct_tid, &child_tid, SIGUSR1, ESRCH }, + { "Valid tgkill call", &parent_tgid, &child_tid, SIGUSR1, 0 }, +}; + +static void run(unsigned int i) +{ + const struct testcase *tc = &testcases[i]; + + TEST(sys_tgkill(*tc->tgid, *tc->tid, tc->sig)); + if (tc->err) { + if (TST_RET < 0 && TST_ERR == tc->err) + tst_res(TPASS | TTERRNO, "%s failed as expected", + tc->desc); + else + tst_res(TFAIL | TTERRNO, + "%s should have failed with %s", tc->desc, + tst_strerrno(tc->err)); + } else { + if (TST_RET == 0) + tst_res(TPASS, "%s succeeded", tc->desc); + else + tst_res(TFAIL | TTERRNO, "%s failed", tc->desc); + } +} + +static struct tst_test test = { + .tcnt = ARRAY_SIZE(testcases), + .needs_checkpoints = 1, + .setup = setup, + .cleanup = cleanup, + .test = run, +}; |