1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * 3f08c3bdfSopenharmony_ci * Copyright (c) Red Hat Inc., 2008 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 6f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 7f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 8f08c3bdfSopenharmony_ci * (at your option) any later version. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 11f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 16f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 17f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci/* 21f08c3bdfSopenharmony_ci * NAME 22f08c3bdfSopenharmony_ci * signalfd01.c 23f08c3bdfSopenharmony_ci * 24f08c3bdfSopenharmony_ci * DESCRIPTION 25f08c3bdfSopenharmony_ci * Check signalfd can receive signals 26f08c3bdfSopenharmony_ci * 27f08c3bdfSopenharmony_ci * USAGE 28f08c3bdfSopenharmony_ci * signalfd01 29f08c3bdfSopenharmony_ci * 30f08c3bdfSopenharmony_ci * HISTORY 31f08c3bdfSopenharmony_ci * 9/2008 Initial version by Masatake YAMATO <yamato@redhat.com> 32f08c3bdfSopenharmony_ci * 33f08c3bdfSopenharmony_ci * RESTRICTIONS 34f08c3bdfSopenharmony_ci * None 35f08c3bdfSopenharmony_ci */ 36f08c3bdfSopenharmony_ci#define _GNU_SOURCE 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_ci#include "config.h" 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci#include "test.h" 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci#include <errno.h> 43f08c3bdfSopenharmony_ci#include <signal.h> 44f08c3bdfSopenharmony_ci#include <unistd.h> 45f08c3bdfSopenharmony_ci#include <fcntl.h> 46f08c3bdfSopenharmony_ci#include <inttypes.h> 47f08c3bdfSopenharmony_ci#include "ltp_signal.h" 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ciTCID_DEFINE(signalfd01); 50f08c3bdfSopenharmony_ciint TST_TOTAL = 1; 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci#ifndef HAVE_SIGNALFD 53f08c3bdfSopenharmony_ci#define USE_STUB 54f08c3bdfSopenharmony_ci#endif 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci#if defined HAVE_SYS_SIGNALFD_H 57f08c3bdfSopenharmony_ci#include <sys/signalfd.h> 58f08c3bdfSopenharmony_ci#elif defined HAVE_LINUX_SIGNALFD_H 59f08c3bdfSopenharmony_ci#include <linux/signalfd.h> 60f08c3bdfSopenharmony_ci#define USE_OWNIMPL 61f08c3bdfSopenharmony_ci#else 62f08c3bdfSopenharmony_ci#define USE_STUB 63f08c3bdfSopenharmony_ci#endif 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_ci#ifndef HAVE_STRUCT_SIGNALFD_SIGINFO_SSI_SIGNO 66f08c3bdfSopenharmony_ci#define USE_STUB 67f08c3bdfSopenharmony_ci#endif 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci#ifdef USE_STUB 70f08c3bdfSopenharmony_ciint main(void) 71f08c3bdfSopenharmony_ci{ 72f08c3bdfSopenharmony_ci tst_brkm(TCONF, NULL, "System doesn't support execution of the test"); 73f08c3bdfSopenharmony_ci} 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci#else 76f08c3bdfSopenharmony_ci#if defined USE_OWNIMPL 77f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 78f08c3bdfSopenharmony_ciint signalfd(int fd, const sigset_t * mask, int flags) 79f08c3bdfSopenharmony_ci{ 80f08c3bdfSopenharmony_ci /* Taken from GLIBC. */ 81f08c3bdfSopenharmony_ci return tst_syscall(__NR_signalfd, fd, mask, SIGSETSIZE); 82f08c3bdfSopenharmony_ci} 83f08c3bdfSopenharmony_ci#endif 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_civoid cleanup(void); 86f08c3bdfSopenharmony_civoid setup(void); 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_ciint do_test1(uint32_t sig) 89f08c3bdfSopenharmony_ci{ 90f08c3bdfSopenharmony_ci int sfd_for_next; 91f08c3bdfSopenharmony_ci int sfd; 92f08c3bdfSopenharmony_ci sigset_t mask; 93f08c3bdfSopenharmony_ci pid_t pid; 94f08c3bdfSopenharmony_ci struct signalfd_siginfo fdsi; 95f08c3bdfSopenharmony_ci ssize_t s; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci sigemptyset(&mask); 98f08c3bdfSopenharmony_ci sigaddset(&mask, sig); 99f08c3bdfSopenharmony_ci if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) { 100f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 101f08c3bdfSopenharmony_ci "sigprocmask() Failed: errno=%d : %s", 102f08c3bdfSopenharmony_ci errno, strerror(errno)); 103f08c3bdfSopenharmony_ci } 104f08c3bdfSopenharmony_ci 105f08c3bdfSopenharmony_ci TEST(signalfd(-1, &mask, 0)); 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci if ((sfd = TEST_RETURN) == -1) { 108f08c3bdfSopenharmony_ci tst_resm(TFAIL, 109f08c3bdfSopenharmony_ci "signalfd() Failed, errno=%d : %s", 110f08c3bdfSopenharmony_ci TEST_ERRNO, strerror(TEST_ERRNO)); 111f08c3bdfSopenharmony_ci sfd_for_next = -1; 112f08c3bdfSopenharmony_ci return sfd_for_next; 113f08c3bdfSopenharmony_ci 114f08c3bdfSopenharmony_ci } else { 115f08c3bdfSopenharmony_ci tst_resm(TPASS, "signalfd is created successfully"); 116f08c3bdfSopenharmony_ci sfd_for_next = sfd; 117f08c3bdfSopenharmony_ci goto out; 118f08c3bdfSopenharmony_ci } 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci if (fcntl(sfd, F_SETFL, O_NONBLOCK) == -1) { 121f08c3bdfSopenharmony_ci close(sfd); 122f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 123f08c3bdfSopenharmony_ci "setting signalfd nonblocking mode failed: errno=%d : %s", 124f08c3bdfSopenharmony_ci errno, strerror(errno)); 125f08c3bdfSopenharmony_ci } 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci pid = getpid(); 128f08c3bdfSopenharmony_ci if (kill(pid, sig) == -1) { 129f08c3bdfSopenharmony_ci close(sfd); 130f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 131f08c3bdfSopenharmony_ci "kill(self, %s) failed: errno=%d : %s", 132f08c3bdfSopenharmony_ci strsignal(sig), errno, strerror(errno)); 133f08c3bdfSopenharmony_ci } 134f08c3bdfSopenharmony_ci 135f08c3bdfSopenharmony_ci s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo)); 136f08c3bdfSopenharmony_ci if ((s > 0) && (s != sizeof(struct signalfd_siginfo))) { 137f08c3bdfSopenharmony_ci tst_resm(TFAIL, 138f08c3bdfSopenharmony_ci "getting incomplete signalfd_siginfo data: " 139f08c3bdfSopenharmony_ci "actual-size=%zd, expected-size=%zu", 140f08c3bdfSopenharmony_ci s, sizeof(struct signalfd_siginfo)); 141f08c3bdfSopenharmony_ci sfd_for_next = -1; 142f08c3bdfSopenharmony_ci close(sfd); 143f08c3bdfSopenharmony_ci goto out; 144f08c3bdfSopenharmony_ci } else if (s < 0) { 145f08c3bdfSopenharmony_ci if (errno == EAGAIN) { 146f08c3bdfSopenharmony_ci tst_resm(TFAIL, 147f08c3bdfSopenharmony_ci "signalfd_siginfo data is not delivered yet"); 148f08c3bdfSopenharmony_ci sfd_for_next = -1; 149f08c3bdfSopenharmony_ci close(sfd); 150f08c3bdfSopenharmony_ci goto out; 151f08c3bdfSopenharmony_ci } else { 152f08c3bdfSopenharmony_ci close(sfd); 153f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 154f08c3bdfSopenharmony_ci "read signalfd_siginfo data failed: errno=%d : %s", 155f08c3bdfSopenharmony_ci errno, strerror(errno)); 156f08c3bdfSopenharmony_ci } 157f08c3bdfSopenharmony_ci } else if (s == 0) { 158f08c3bdfSopenharmony_ci tst_resm(TFAIL, "got EOF unexpectedly"); 159f08c3bdfSopenharmony_ci sfd_for_next = -1; 160f08c3bdfSopenharmony_ci close(sfd); 161f08c3bdfSopenharmony_ci goto out; 162f08c3bdfSopenharmony_ci } 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci if (fdsi.ssi_signo == sig) { 165f08c3bdfSopenharmony_ci tst_resm(TPASS, "got expected signal"); 166f08c3bdfSopenharmony_ci sfd_for_next = sfd; 167f08c3bdfSopenharmony_ci goto out; 168f08c3bdfSopenharmony_ci } else { 169f08c3bdfSopenharmony_ci tst_resm(TFAIL, "got unexpected signal: signal=%d : %s", 170f08c3bdfSopenharmony_ci fdsi.ssi_signo, strsignal(fdsi.ssi_signo)); 171f08c3bdfSopenharmony_ci sfd_for_next = -1; 172f08c3bdfSopenharmony_ci close(sfd); 173f08c3bdfSopenharmony_ci goto out; 174f08c3bdfSopenharmony_ci } 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ciout: 177f08c3bdfSopenharmony_ci return sfd_for_next; 178f08c3bdfSopenharmony_ci} 179f08c3bdfSopenharmony_ci 180f08c3bdfSopenharmony_civoid do_test2(int fd, uint32_t sig) 181f08c3bdfSopenharmony_ci{ 182f08c3bdfSopenharmony_ci int sfd; 183f08c3bdfSopenharmony_ci sigset_t mask; 184f08c3bdfSopenharmony_ci pid_t pid; 185f08c3bdfSopenharmony_ci struct signalfd_siginfo fdsi; 186f08c3bdfSopenharmony_ci ssize_t s; 187f08c3bdfSopenharmony_ci 188f08c3bdfSopenharmony_ci sigemptyset(&mask); 189f08c3bdfSopenharmony_ci sigaddset(&mask, sig); 190f08c3bdfSopenharmony_ci if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) { 191f08c3bdfSopenharmony_ci close(fd); 192f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 193f08c3bdfSopenharmony_ci "sigprocmask() Failed: errno=%d : %s", 194f08c3bdfSopenharmony_ci errno, strerror(errno)); 195f08c3bdfSopenharmony_ci } 196f08c3bdfSopenharmony_ci 197f08c3bdfSopenharmony_ci TEST(signalfd(fd, &mask, 0)); 198f08c3bdfSopenharmony_ci 199f08c3bdfSopenharmony_ci if ((sfd = TEST_RETURN) == -1) { 200f08c3bdfSopenharmony_ci tst_resm(TFAIL, 201f08c3bdfSopenharmony_ci "reassignment the file descriptor by signalfd() failed, errno=%d : %s", 202f08c3bdfSopenharmony_ci TEST_ERRNO, strerror(TEST_ERRNO)); 203f08c3bdfSopenharmony_ci return; 204f08c3bdfSopenharmony_ci } else if (sfd != fd) { 205f08c3bdfSopenharmony_ci tst_resm(TFAIL, 206f08c3bdfSopenharmony_ci "different fd is returned in reassignment: expected-fd=%d, actual-fd=%d", 207f08c3bdfSopenharmony_ci fd, sfd); 208f08c3bdfSopenharmony_ci close(sfd); 209f08c3bdfSopenharmony_ci return; 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci } else { 212f08c3bdfSopenharmony_ci tst_resm(TPASS, "signalfd is successfully reassigned"); 213f08c3bdfSopenharmony_ci goto out; 214f08c3bdfSopenharmony_ci } 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci pid = getpid(); 217f08c3bdfSopenharmony_ci if (kill(pid, sig) == -1) { 218f08c3bdfSopenharmony_ci close(sfd); 219f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 220f08c3bdfSopenharmony_ci "kill(self, %s) failed: errno=%d : %s", 221f08c3bdfSopenharmony_ci strsignal(sig), errno, strerror(errno)); 222f08c3bdfSopenharmony_ci } 223f08c3bdfSopenharmony_ci 224f08c3bdfSopenharmony_ci s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo)); 225f08c3bdfSopenharmony_ci if ((s > 0) && (s != sizeof(struct signalfd_siginfo))) { 226f08c3bdfSopenharmony_ci tst_resm(TFAIL, 227f08c3bdfSopenharmony_ci "getting incomplete signalfd_siginfo data: " 228f08c3bdfSopenharmony_ci "actual-size=%zd, expected-size= %zu", 229f08c3bdfSopenharmony_ci s, sizeof(struct signalfd_siginfo)); 230f08c3bdfSopenharmony_ci goto out; 231f08c3bdfSopenharmony_ci } else if (s < 0) { 232f08c3bdfSopenharmony_ci if (errno == EAGAIN) { 233f08c3bdfSopenharmony_ci tst_resm(TFAIL, 234f08c3bdfSopenharmony_ci "signalfd_siginfo data is not delivered yet"); 235f08c3bdfSopenharmony_ci goto out; 236f08c3bdfSopenharmony_ci } else { 237f08c3bdfSopenharmony_ci close(sfd); 238f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 239f08c3bdfSopenharmony_ci "read signalfd_siginfo data failed: errno=%d : %s", 240f08c3bdfSopenharmony_ci errno, strerror(errno)); 241f08c3bdfSopenharmony_ci } 242f08c3bdfSopenharmony_ci } else if (s == 0) { 243f08c3bdfSopenharmony_ci tst_resm(TFAIL, "got EOF unexpectedly"); 244f08c3bdfSopenharmony_ci goto out; 245f08c3bdfSopenharmony_ci } 246f08c3bdfSopenharmony_ci 247f08c3bdfSopenharmony_ci if (fdsi.ssi_signo == sig) { 248f08c3bdfSopenharmony_ci tst_resm(TPASS, "got expected signal"); 249f08c3bdfSopenharmony_ci goto out; 250f08c3bdfSopenharmony_ci } else { 251f08c3bdfSopenharmony_ci tst_resm(TFAIL, "got unexpected signal: signal=%d : %s", 252f08c3bdfSopenharmony_ci fdsi.ssi_signo, strsignal(fdsi.ssi_signo)); 253f08c3bdfSopenharmony_ci goto out; 254f08c3bdfSopenharmony_ci } 255f08c3bdfSopenharmony_ci 256f08c3bdfSopenharmony_ciout: 257f08c3bdfSopenharmony_ci return; 258f08c3bdfSopenharmony_ci} 259f08c3bdfSopenharmony_ci 260f08c3bdfSopenharmony_ciint main(int argc, char **argv) 261f08c3bdfSopenharmony_ci{ 262f08c3bdfSopenharmony_ci int lc; 263f08c3bdfSopenharmony_ci int sfd; 264f08c3bdfSopenharmony_ci 265f08c3bdfSopenharmony_ci tst_parse_opts(argc, argv, NULL, NULL); 266f08c3bdfSopenharmony_ci 267f08c3bdfSopenharmony_ci setup(); 268f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 269f08c3bdfSopenharmony_ci tst_count = 0; 270f08c3bdfSopenharmony_ci 271f08c3bdfSopenharmony_ci sfd = do_test1(SIGUSR1); 272f08c3bdfSopenharmony_ci if (sfd < 0) 273f08c3bdfSopenharmony_ci continue; 274f08c3bdfSopenharmony_ci 275f08c3bdfSopenharmony_ci do_test2(sfd, SIGUSR2); 276f08c3bdfSopenharmony_ci close(sfd); 277f08c3bdfSopenharmony_ci } 278f08c3bdfSopenharmony_ci 279f08c3bdfSopenharmony_ci cleanup(); 280f08c3bdfSopenharmony_ci 281f08c3bdfSopenharmony_ci tst_exit(); 282f08c3bdfSopenharmony_ci} 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ci/* 285f08c3bdfSopenharmony_ci * setup() - performs all the ONE TIME setup for this test. 286f08c3bdfSopenharmony_ci */ 287f08c3bdfSopenharmony_civoid setup(void) 288f08c3bdfSopenharmony_ci{ 289f08c3bdfSopenharmony_ci 290f08c3bdfSopenharmony_ci TEST_PAUSE; 291f08c3bdfSopenharmony_ci} 292f08c3bdfSopenharmony_ci 293f08c3bdfSopenharmony_ci/* 294f08c3bdfSopenharmony_ci * cleanup() - performs all the ONE TIME cleanup for this test at completion 295f08c3bdfSopenharmony_ci * or premature exit. 296f08c3bdfSopenharmony_ci */ 297f08c3bdfSopenharmony_civoid cleanup(void) 298f08c3bdfSopenharmony_ci{ 299f08c3bdfSopenharmony_ci 300f08c3bdfSopenharmony_ci} 301f08c3bdfSopenharmony_ci 302f08c3bdfSopenharmony_ci#endif 303