Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 
0003 #define _GNU_SOURCE
0004 #include <errno.h>
0005 #include <sched.h>
0006 #include <signal.h>
0007 #include <stdio.h>
0008 #include <stdlib.h>
0009 #include <string.h>
0010 #include <unistd.h>
0011 #include <linux/sched.h>
0012 #include <linux/types.h>
0013 #include <sys/syscall.h>
0014 #include <sys/wait.h>
0015 
0016 #include "../kselftest.h"
0017 #include "clone3_selftests.h"
0018 
0019 #ifndef CLONE_CLEAR_SIGHAND
0020 #define CLONE_CLEAR_SIGHAND 0x100000000ULL
0021 #endif
0022 
0023 static void nop_handler(int signo)
0024 {
0025 }
0026 
0027 static int wait_for_pid(pid_t pid)
0028 {
0029     int status, ret;
0030 
0031 again:
0032     ret = waitpid(pid, &status, 0);
0033     if (ret == -1) {
0034         if (errno == EINTR)
0035             goto again;
0036 
0037         return -1;
0038     }
0039 
0040     if (!WIFEXITED(status))
0041         return -1;
0042 
0043     return WEXITSTATUS(status);
0044 }
0045 
0046 static void test_clone3_clear_sighand(void)
0047 {
0048     int ret;
0049     pid_t pid;
0050     struct __clone_args args = {};
0051     struct sigaction act;
0052 
0053     /*
0054      * Check that CLONE_CLEAR_SIGHAND and CLONE_SIGHAND are mutually
0055      * exclusive.
0056      */
0057     args.flags |= CLONE_CLEAR_SIGHAND | CLONE_SIGHAND;
0058     args.exit_signal = SIGCHLD;
0059     pid = sys_clone3(&args, sizeof(args));
0060     if (pid > 0)
0061         ksft_exit_fail_msg(
0062             "clone3(CLONE_CLEAR_SIGHAND | CLONE_SIGHAND) succeeded\n");
0063 
0064     act.sa_handler = nop_handler;
0065     ret = sigemptyset(&act.sa_mask);
0066     if (ret < 0)
0067         ksft_exit_fail_msg("%s - sigemptyset() failed\n",
0068                    strerror(errno));
0069 
0070     act.sa_flags = 0;
0071 
0072     /* Register signal handler for SIGUSR1 */
0073     ret = sigaction(SIGUSR1, &act, NULL);
0074     if (ret < 0)
0075         ksft_exit_fail_msg(
0076             "%s - sigaction(SIGUSR1, &act, NULL) failed\n",
0077             strerror(errno));
0078 
0079     /* Register signal handler for SIGUSR2 */
0080     ret = sigaction(SIGUSR2, &act, NULL);
0081     if (ret < 0)
0082         ksft_exit_fail_msg(
0083             "%s - sigaction(SIGUSR2, &act, NULL) failed\n",
0084             strerror(errno));
0085 
0086     /* Check that CLONE_CLEAR_SIGHAND works. */
0087     args.flags = CLONE_CLEAR_SIGHAND;
0088     pid = sys_clone3(&args, sizeof(args));
0089     if (pid < 0)
0090         ksft_exit_fail_msg("%s - clone3(CLONE_CLEAR_SIGHAND) failed\n",
0091                    strerror(errno));
0092 
0093     if (pid == 0) {
0094         ret = sigaction(SIGUSR1, NULL, &act);
0095         if (ret < 0)
0096             exit(EXIT_FAILURE);
0097 
0098         if (act.sa_handler != SIG_DFL)
0099             exit(EXIT_FAILURE);
0100 
0101         ret = sigaction(SIGUSR2, NULL, &act);
0102         if (ret < 0)
0103             exit(EXIT_FAILURE);
0104 
0105         if (act.sa_handler != SIG_DFL)
0106             exit(EXIT_FAILURE);
0107 
0108         exit(EXIT_SUCCESS);
0109     }
0110 
0111     ret = wait_for_pid(pid);
0112     if (ret)
0113         ksft_exit_fail_msg(
0114             "Failed to clear signal handler for child process\n");
0115 
0116     ksft_test_result_pass("Cleared signal handlers for child process\n");
0117 }
0118 
0119 int main(int argc, char **argv)
0120 {
0121     ksft_print_header();
0122     ksft_set_plan(1);
0123     test_clone3_supported();
0124 
0125     test_clone3_clear_sighand();
0126 
0127     return ksft_exit_pass();
0128 }