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