1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * Description: 6f08c3bdfSopenharmony_ci * Verify the basic function of sigsuspend(): 7f08c3bdfSopenharmony_ci * 1) sigsuspend() can replace process's current signal mask 8f08c3bdfSopenharmony_ci * by the specified signal mask and suspend the process 9f08c3bdfSopenharmony_ci * execution until the delivery of a signal. 10f08c3bdfSopenharmony_ci * 2) sigsuspend() should return after the execution of signal 11f08c3bdfSopenharmony_ci * handler and restore the previous signal mask. 12f08c3bdfSopenharmony_ci */ 13f08c3bdfSopenharmony_ci 14f08c3bdfSopenharmony_ci#include <errno.h> 15f08c3bdfSopenharmony_ci#include <unistd.h> 16f08c3bdfSopenharmony_ci#include <string.h> 17f08c3bdfSopenharmony_ci#include <signal.h> 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci#include "tst_test.h" 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_cistatic sigset_t signalset, sigset1, sigset2; 22f08c3bdfSopenharmony_cistatic volatile sig_atomic_t alarm_num; 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_cistatic void sig_handler(int sig) 25f08c3bdfSopenharmony_ci{ 26f08c3bdfSopenharmony_ci alarm_num = sig; 27f08c3bdfSopenharmony_ci} 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_cistatic void verify_sigsuspend(void) 30f08c3bdfSopenharmony_ci{ 31f08c3bdfSopenharmony_ci alarm_num = 0; 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci SAFE_SIGFILLSET(&sigset2); 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_ci alarm(1); 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci /* Unblock SIGALRM */ 38f08c3bdfSopenharmony_ci TEST(sigsuspend(&signalset)); 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci alarm(0); 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci if (TST_RET != -1 || TST_ERR != EINTR) { 43f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, 44f08c3bdfSopenharmony_ci "sigsuspend() returned value %ld", TST_RET); 45f08c3bdfSopenharmony_ci return; 46f08c3bdfSopenharmony_ci } 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci if (alarm_num != SIGALRM) { 49f08c3bdfSopenharmony_ci tst_res(TFAIL, "sigsuspend() didn't unblock SIGALRM"); 50f08c3bdfSopenharmony_ci return; 51f08c3bdfSopenharmony_ci } 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci SAFE_SIGPROCMASK(0, NULL, &sigset2); 54f08c3bdfSopenharmony_ci if (memcmp(&sigset1, &sigset2, sizeof(unsigned long))) { 55f08c3bdfSopenharmony_ci tst_res(TFAIL, "sigsuspend() failed to " 56f08c3bdfSopenharmony_ci "restore the previous signal mask"); 57f08c3bdfSopenharmony_ci return; 58f08c3bdfSopenharmony_ci } 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci tst_res(TPASS, "sigsuspend() succeeded"); 61f08c3bdfSopenharmony_ci} 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic void setup(void) 64f08c3bdfSopenharmony_ci{ 65f08c3bdfSopenharmony_ci SAFE_SIGEMPTYSET(&signalset); 66f08c3bdfSopenharmony_ci SAFE_SIGEMPTYSET(&sigset1); 67f08c3bdfSopenharmony_ci SAFE_SIGADDSET(&sigset1, SIGALRM); 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci struct sigaction sa_new = { 70f08c3bdfSopenharmony_ci .sa_handler = sig_handler, 71f08c3bdfSopenharmony_ci }; 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci SAFE_SIGACTION(SIGALRM, &sa_new, 0); 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci /* Block SIGALRM */ 76f08c3bdfSopenharmony_ci SAFE_SIGPROCMASK(SIG_SETMASK, &sigset1, NULL); 77f08c3bdfSopenharmony_ci} 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_cistatic struct tst_test test = { 80f08c3bdfSopenharmony_ci .setup = setup, 81f08c3bdfSopenharmony_ci .test_all = verify_sigsuspend, 82f08c3bdfSopenharmony_ci}; 83