1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2019 SUSE LLC 4f08c3bdfSopenharmony_ci * Author: Christian Amann <camann@suse.com> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/* 8f08c3bdfSopenharmony_ci * This tests the rt_sigqueueinfo() syscall. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * It does so by creating a thread which registers the corresponding 11f08c3bdfSopenharmony_ci * signal handler. After that the main thread sends a signal and data 12f08c3bdfSopenharmony_ci * to the handler thread. If the correct signal and data is received, 13f08c3bdfSopenharmony_ci * the test is successful. 14f08c3bdfSopenharmony_ci */ 15f08c3bdfSopenharmony_ci 16f08c3bdfSopenharmony_ci#include <signal.h> 17f08c3bdfSopenharmony_ci#include <stdlib.h> 18f08c3bdfSopenharmony_ci#include "config.h" 19f08c3bdfSopenharmony_ci#include "tst_test.h" 20f08c3bdfSopenharmony_ci#include "tst_safe_pthread.h" 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci#ifdef HAVE_STRUCT_SIGACTION_SA_SIGACTION 23f08c3bdfSopenharmony_ci#include "rt_sigqueueinfo.h" 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_ci#define SIGNAL SIGUSR1 26f08c3bdfSopenharmony_ci#define DATA 777 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_cistatic struct sigaction *sig_action; 29f08c3bdfSopenharmony_cistatic int sig_rec; 30f08c3bdfSopenharmony_cistatic siginfo_t *uinfo; 31f08c3bdfSopenharmony_cistatic pid_t tid; 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_cistatic void received_signal(int sig, siginfo_t *info, void *ucontext) 34f08c3bdfSopenharmony_ci{ 35f08c3bdfSopenharmony_ci if (info && ucontext) { 36f08c3bdfSopenharmony_ci if (sig == SIGNAL && info->si_value.sival_int == DATA) { 37f08c3bdfSopenharmony_ci tst_res(TPASS, "Received correct signal and data!"); 38f08c3bdfSopenharmony_ci sig_rec = 1; 39f08c3bdfSopenharmony_ci } else 40f08c3bdfSopenharmony_ci tst_res(TFAIL, "Received wrong signal and/or data!"); 41f08c3bdfSopenharmony_ci } else 42f08c3bdfSopenharmony_ci tst_res(TFAIL, "Signal handling went wrong!"); 43f08c3bdfSopenharmony_ci} 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_cistatic void *handle_thread(void *arg LTP_ATTRIBUTE_UNUSED) 46f08c3bdfSopenharmony_ci{ 47f08c3bdfSopenharmony_ci int ret; 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ci tid = tst_syscall(__NR_gettid); 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_ci ret = sigaction(SIGNAL, sig_action, NULL); 52f08c3bdfSopenharmony_ci if (ret) 53f08c3bdfSopenharmony_ci tst_brk(TBROK, "Failed to set sigaction for handler thread!"); 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAKE(0); 56f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAIT(1); 57f08c3bdfSopenharmony_ci return arg; 58f08c3bdfSopenharmony_ci} 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_cistatic void verify_sigqueueinfo(void) 61f08c3bdfSopenharmony_ci{ 62f08c3bdfSopenharmony_ci pthread_t thr; 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci SAFE_PTHREAD_CREATE(&thr, NULL, handle_thread, NULL); 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAIT(0); 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci TEST(sys_rt_sigqueueinfo(tid, SIGNAL, uinfo)); 69f08c3bdfSopenharmony_ci if (TST_RET != 0) { 70f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "rt_sigqueueinfo() failed"); 71f08c3bdfSopenharmony_ci return; 72f08c3bdfSopenharmony_ci } 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAKE(1); 75f08c3bdfSopenharmony_ci SAFE_PTHREAD_JOIN(thr, NULL); 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_ci if (sig_rec) 78f08c3bdfSopenharmony_ci tst_res(TPASS, "rt_sigqueueinfo() was successful!"); 79f08c3bdfSopenharmony_ci} 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_cistatic void setup(void) 82f08c3bdfSopenharmony_ci{ 83f08c3bdfSopenharmony_ci sig_action = SAFE_MALLOC(sizeof(struct sigaction)); 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci memset(sig_action, 0, sizeof(*sig_action)); 86f08c3bdfSopenharmony_ci sig_action->sa_sigaction = received_signal; 87f08c3bdfSopenharmony_ci sig_action->sa_flags = SA_SIGINFO; 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci uinfo = SAFE_MALLOC(sizeof(siginfo_t)); 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci memset(uinfo, 0, sizeof(*uinfo)); 92f08c3bdfSopenharmony_ci uinfo->si_code = SI_QUEUE; 93f08c3bdfSopenharmony_ci uinfo->si_pid = getpid(); 94f08c3bdfSopenharmony_ci uinfo->si_uid = getuid(); 95f08c3bdfSopenharmony_ci uinfo->si_value.sival_int = DATA; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci sig_rec = 0; 98f08c3bdfSopenharmony_ci} 99f08c3bdfSopenharmony_ci 100f08c3bdfSopenharmony_cistatic void cleanup(void) 101f08c3bdfSopenharmony_ci{ 102f08c3bdfSopenharmony_ci free(uinfo); 103f08c3bdfSopenharmony_ci free(sig_action); 104f08c3bdfSopenharmony_ci} 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_cistatic struct tst_test test = { 107f08c3bdfSopenharmony_ci .test_all = verify_sigqueueinfo, 108f08c3bdfSopenharmony_ci .setup = setup, 109f08c3bdfSopenharmony_ci .cleanup = cleanup, 110f08c3bdfSopenharmony_ci .needs_checkpoints = 1, 111f08c3bdfSopenharmony_ci}; 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci#else 114f08c3bdfSopenharmony_ci TST_TEST_TCONF( 115f08c3bdfSopenharmony_ci "This system does not support rt_sigqueueinfo()."); 116f08c3bdfSopenharmony_ci#endif /* HAVE_STRUCT_SIGACTION_SA_SIGACTION */ 117