xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/pidfd_send_signal/pidfd_send_signal01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2019 SUSE LLC
4  * Author: Christian Amann <[email protected]>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Tests if the pidfd_send_signal syscall behaves
11  * like rt_sigqueueinfo when a pointer to a siginfo_t
12  * struct is passed.
13  */
14 
15 #define _GNU_SOURCE
16 #include <signal.h>
17 #include <stdlib.h>
18 #include "tst_test.h"
19 #include "lapi/pidfd.h"
20 #include "tst_safe_pthread.h"
21 
22 #define SIGNAL  SIGUSR1
23 #define DATA	777
24 
25 static struct sigaction *sig_action;
26 static int sig_rec;
27 static siginfo_t *uinfo;
28 static int pidfd;
29 
received_signal(int sig,siginfo_t * info,void * ucontext)30 static void received_signal(int sig, siginfo_t *info, void *ucontext)
31 {
32 	if (info && ucontext) {
33 		if (sig == SIGNAL && info->si_value.sival_int == DATA) {
34 			tst_res(TPASS, "Received correct signal and data!");
35 			sig_rec = 1;
36 		} else {
37 			tst_res(TFAIL, "Received wrong signal and/or data!");
38 		}
39 	} else {
40 		tst_res(TFAIL, "Signal handling went wrong!");
41 	}
42 }
43 
handle_thread(void * arg)44 static void *handle_thread(void *arg)
45 {
46 	SAFE_SIGACTION(SIGNAL, sig_action, NULL);
47 	TST_CHECKPOINT_WAKE_AND_WAIT(0);
48 	return arg;
49 }
50 
verify_pidfd_send_signal(void)51 static void verify_pidfd_send_signal(void)
52 {
53 	pthread_t thr;
54 
55 	SAFE_PTHREAD_CREATE(&thr, NULL, handle_thread, NULL);
56 
57 	TST_CHECKPOINT_WAIT(0);
58 
59 	TEST(pidfd_send_signal(pidfd, SIGNAL, uinfo, 0));
60 	if (TST_RET != 0) {
61 		tst_res(TFAIL | TTERRNO, "pidfd_send_signal() failed");
62 		return;
63 	}
64 
65 	TST_CHECKPOINT_WAKE(0);
66 	SAFE_PTHREAD_JOIN(thr, NULL);
67 
68 	if (sig_rec) {
69 		tst_res(TPASS,
70 			"pidfd_send_signal() behaved like rt_sigqueueinfo()");
71 	}
72 }
73 
setup(void)74 static void setup(void)
75 {
76 	pidfd_send_signal_supported();
77 
78 	pidfd = SAFE_OPEN("/proc/self", O_DIRECTORY | O_CLOEXEC);
79 
80 	sig_action = SAFE_MALLOC(sizeof(struct sigaction));
81 
82 	memset(sig_action, 0, sizeof(*sig_action));
83 	sig_action->sa_sigaction = received_signal;
84 	sig_action->sa_flags = SA_SIGINFO;
85 
86 	uinfo = SAFE_MALLOC(sizeof(siginfo_t));
87 
88 	memset(uinfo, 0, sizeof(*uinfo));
89 	uinfo->si_signo = SIGNAL;
90 	uinfo->si_code = SI_QUEUE;
91 	uinfo->si_pid = getpid();
92 	uinfo->si_uid = getuid();
93 	uinfo->si_value.sival_int = DATA;
94 }
95 
cleanup(void)96 static void cleanup(void)
97 {
98 	free(uinfo);
99 	free(sig_action);
100 	if (pidfd > 0)
101 		SAFE_CLOSE(pidfd);
102 }
103 
104 static struct tst_test test = {
105 	.test_all = verify_pidfd_send_signal,
106 	.setup = setup,
107 	.cleanup = cleanup,
108 	.needs_checkpoints = 1,
109 };
110