clone3_clear_sighand.c (2598B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2 3#define _GNU_SOURCE 4#include <errno.h> 5#include <sched.h> 6#include <signal.h> 7#include <stdio.h> 8#include <stdlib.h> 9#include <string.h> 10#include <unistd.h> 11#include <linux/sched.h> 12#include <linux/types.h> 13#include <sys/syscall.h> 14#include <sys/wait.h> 15 16#include "../kselftest.h" 17#include "clone3_selftests.h" 18 19#ifndef CLONE_CLEAR_SIGHAND 20#define CLONE_CLEAR_SIGHAND 0x100000000ULL 21#endif 22 23static void nop_handler(int signo) 24{ 25} 26 27static int wait_for_pid(pid_t pid) 28{ 29 int status, ret; 30 31again: 32 ret = waitpid(pid, &status, 0); 33 if (ret == -1) { 34 if (errno == EINTR) 35 goto again; 36 37 return -1; 38 } 39 40 if (!WIFEXITED(status)) 41 return -1; 42 43 return WEXITSTATUS(status); 44} 45 46static void test_clone3_clear_sighand(void) 47{ 48 int ret; 49 pid_t pid; 50 struct __clone_args args = {}; 51 struct sigaction act; 52 53 /* 54 * Check that CLONE_CLEAR_SIGHAND and CLONE_SIGHAND are mutually 55 * exclusive. 56 */ 57 args.flags |= CLONE_CLEAR_SIGHAND | CLONE_SIGHAND; 58 args.exit_signal = SIGCHLD; 59 pid = sys_clone3(&args, sizeof(args)); 60 if (pid > 0) 61 ksft_exit_fail_msg( 62 "clone3(CLONE_CLEAR_SIGHAND | CLONE_SIGHAND) succeeded\n"); 63 64 act.sa_handler = nop_handler; 65 ret = sigemptyset(&act.sa_mask); 66 if (ret < 0) 67 ksft_exit_fail_msg("%s - sigemptyset() failed\n", 68 strerror(errno)); 69 70 act.sa_flags = 0; 71 72 /* Register signal handler for SIGUSR1 */ 73 ret = sigaction(SIGUSR1, &act, NULL); 74 if (ret < 0) 75 ksft_exit_fail_msg( 76 "%s - sigaction(SIGUSR1, &act, NULL) failed\n", 77 strerror(errno)); 78 79 /* Register signal handler for SIGUSR2 */ 80 ret = sigaction(SIGUSR2, &act, NULL); 81 if (ret < 0) 82 ksft_exit_fail_msg( 83 "%s - sigaction(SIGUSR2, &act, NULL) failed\n", 84 strerror(errno)); 85 86 /* Check that CLONE_CLEAR_SIGHAND works. */ 87 args.flags = CLONE_CLEAR_SIGHAND; 88 pid = sys_clone3(&args, sizeof(args)); 89 if (pid < 0) 90 ksft_exit_fail_msg("%s - clone3(CLONE_CLEAR_SIGHAND) failed\n", 91 strerror(errno)); 92 93 if (pid == 0) { 94 ret = sigaction(SIGUSR1, NULL, &act); 95 if (ret < 0) 96 exit(EXIT_FAILURE); 97 98 if (act.sa_handler != SIG_DFL) 99 exit(EXIT_FAILURE); 100 101 ret = sigaction(SIGUSR2, NULL, &act); 102 if (ret < 0) 103 exit(EXIT_FAILURE); 104 105 if (act.sa_handler != SIG_DFL) 106 exit(EXIT_FAILURE); 107 108 exit(EXIT_SUCCESS); 109 } 110 111 ret = wait_for_pid(pid); 112 if (ret) 113 ksft_exit_fail_msg( 114 "Failed to clear signal handler for child process\n"); 115 116 ksft_test_result_pass("Cleared signal handlers for child process\n"); 117} 118 119int main(int argc, char **argv) 120{ 121 ksft_print_header(); 122 ksft_set_plan(1); 123 test_clone3_supported(); 124 125 test_clone3_clear_sighand(); 126 127 return ksft_exit_pass(); 128}