1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd 4f08c3bdfSopenharmony_ci * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> 5f08c3bdfSopenharmony_ci * 6f08c3bdfSopenharmony_ci * Authors: 7f08c3bdfSopenharmony_ci * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, 8f08c3bdfSopenharmony_ci * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, 9f08c3bdfSopenharmony_ci * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> 10f08c3bdfSopenharmony_ci */ 11f08c3bdfSopenharmony_ci 12f08c3bdfSopenharmony_ci#include <errno.h> 13f08c3bdfSopenharmony_ci#include <limits.h> 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_cistatic int fd, fd_root, fd_nonblock, fd_maxint = INT_MAX - 1, fd_invalid = -1; 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci#include "mq_timed.h" 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_cistatic struct tst_ts ts; 20f08c3bdfSopenharmony_cistatic void *bad_addr; 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_cistatic struct test_case tcase[] = { 23f08c3bdfSopenharmony_ci { 24f08c3bdfSopenharmony_ci .fd = &fd, 25f08c3bdfSopenharmony_ci .len = 0, 26f08c3bdfSopenharmony_ci .ret = 0, 27f08c3bdfSopenharmony_ci .err = 0, 28f08c3bdfSopenharmony_ci }, 29f08c3bdfSopenharmony_ci { 30f08c3bdfSopenharmony_ci .fd = &fd, 31f08c3bdfSopenharmony_ci .len = 1, 32f08c3bdfSopenharmony_ci .ret = 0, 33f08c3bdfSopenharmony_ci .err = 0, 34f08c3bdfSopenharmony_ci }, 35f08c3bdfSopenharmony_ci { 36f08c3bdfSopenharmony_ci .fd = &fd, 37f08c3bdfSopenharmony_ci .len = MAX_MSGSIZE, 38f08c3bdfSopenharmony_ci .ret = 0, 39f08c3bdfSopenharmony_ci .err = 0, 40f08c3bdfSopenharmony_ci }, 41f08c3bdfSopenharmony_ci { 42f08c3bdfSopenharmony_ci .fd = &fd, 43f08c3bdfSopenharmony_ci .len = 1, 44f08c3bdfSopenharmony_ci .prio = MQ_PRIO_MAX - 1, 45f08c3bdfSopenharmony_ci .ret = 0, 46f08c3bdfSopenharmony_ci .err = 0, 47f08c3bdfSopenharmony_ci }, 48f08c3bdfSopenharmony_ci { 49f08c3bdfSopenharmony_ci .fd = &fd, 50f08c3bdfSopenharmony_ci .len = MAX_MSGSIZE + 1, 51f08c3bdfSopenharmony_ci .ret = -1, 52f08c3bdfSopenharmony_ci .err = EMSGSIZE, 53f08c3bdfSopenharmony_ci }, 54f08c3bdfSopenharmony_ci { 55f08c3bdfSopenharmony_ci .fd = &fd_invalid, 56f08c3bdfSopenharmony_ci .len = 0, 57f08c3bdfSopenharmony_ci .ret = -1, 58f08c3bdfSopenharmony_ci .err = EBADF, 59f08c3bdfSopenharmony_ci }, 60f08c3bdfSopenharmony_ci { 61f08c3bdfSopenharmony_ci .fd = &fd_maxint, 62f08c3bdfSopenharmony_ci .len = 0, 63f08c3bdfSopenharmony_ci .ret = -1, 64f08c3bdfSopenharmony_ci .err = EBADF, 65f08c3bdfSopenharmony_ci }, 66f08c3bdfSopenharmony_ci { 67f08c3bdfSopenharmony_ci .fd = &fd_root, 68f08c3bdfSopenharmony_ci .len = 0, 69f08c3bdfSopenharmony_ci .ret = -1, 70f08c3bdfSopenharmony_ci .err = EBADF, 71f08c3bdfSopenharmony_ci }, 72f08c3bdfSopenharmony_ci { 73f08c3bdfSopenharmony_ci .fd = &fd_nonblock, 74f08c3bdfSopenharmony_ci .len = 16, 75f08c3bdfSopenharmony_ci .ret = -1, 76f08c3bdfSopenharmony_ci .err = EAGAIN, 77f08c3bdfSopenharmony_ci }, 78f08c3bdfSopenharmony_ci { 79f08c3bdfSopenharmony_ci .fd = &fd, 80f08c3bdfSopenharmony_ci .len = 1, 81f08c3bdfSopenharmony_ci .prio = MQ_PRIO_MAX, 82f08c3bdfSopenharmony_ci .ret = -1, 83f08c3bdfSopenharmony_ci .err = EINVAL, 84f08c3bdfSopenharmony_ci }, 85f08c3bdfSopenharmony_ci { 86f08c3bdfSopenharmony_ci .fd = &fd, 87f08c3bdfSopenharmony_ci .len = 16, 88f08c3bdfSopenharmony_ci .tv_sec = -1, 89f08c3bdfSopenharmony_ci .tv_nsec = 0, 90f08c3bdfSopenharmony_ci .rq = &ts, 91f08c3bdfSopenharmony_ci .send = 1, 92f08c3bdfSopenharmony_ci .ret = -1, 93f08c3bdfSopenharmony_ci .err = EINVAL, 94f08c3bdfSopenharmony_ci }, 95f08c3bdfSopenharmony_ci { 96f08c3bdfSopenharmony_ci .fd = &fd, 97f08c3bdfSopenharmony_ci .len = 16, 98f08c3bdfSopenharmony_ci .tv_sec = 0, 99f08c3bdfSopenharmony_ci .tv_nsec = -1, 100f08c3bdfSopenharmony_ci .rq = &ts, 101f08c3bdfSopenharmony_ci .send = 1, 102f08c3bdfSopenharmony_ci .ret = -1, 103f08c3bdfSopenharmony_ci .err = EINVAL, 104f08c3bdfSopenharmony_ci }, 105f08c3bdfSopenharmony_ci { 106f08c3bdfSopenharmony_ci .fd = &fd, 107f08c3bdfSopenharmony_ci .len = 16, 108f08c3bdfSopenharmony_ci .tv_sec = 0, 109f08c3bdfSopenharmony_ci .tv_nsec = 1000000000, 110f08c3bdfSopenharmony_ci .rq = &ts, 111f08c3bdfSopenharmony_ci .send = 1, 112f08c3bdfSopenharmony_ci .ret = -1, 113f08c3bdfSopenharmony_ci .err = EINVAL, 114f08c3bdfSopenharmony_ci }, 115f08c3bdfSopenharmony_ci { 116f08c3bdfSopenharmony_ci .fd = &fd, 117f08c3bdfSopenharmony_ci .len = 16, 118f08c3bdfSopenharmony_ci .rq = &ts, 119f08c3bdfSopenharmony_ci .send = 1, 120f08c3bdfSopenharmony_ci .timeout = 1, 121f08c3bdfSopenharmony_ci .ret = -1, 122f08c3bdfSopenharmony_ci .err = ETIMEDOUT, 123f08c3bdfSopenharmony_ci }, 124f08c3bdfSopenharmony_ci { 125f08c3bdfSopenharmony_ci .fd = &fd, 126f08c3bdfSopenharmony_ci .len = 16, 127f08c3bdfSopenharmony_ci .send = 1, 128f08c3bdfSopenharmony_ci .signal = 1, 129f08c3bdfSopenharmony_ci .rq = &ts, 130f08c3bdfSopenharmony_ci .ret = -1, 131f08c3bdfSopenharmony_ci .err = EINTR, 132f08c3bdfSopenharmony_ci }, 133f08c3bdfSopenharmony_ci { 134f08c3bdfSopenharmony_ci .fd = &fd, 135f08c3bdfSopenharmony_ci .len = 16, 136f08c3bdfSopenharmony_ci .bad_msg_addr = 1, 137f08c3bdfSopenharmony_ci .ret = -1, 138f08c3bdfSopenharmony_ci .err = EFAULT, 139f08c3bdfSopenharmony_ci }, 140f08c3bdfSopenharmony_ci { 141f08c3bdfSopenharmony_ci .fd = &fd, 142f08c3bdfSopenharmony_ci .len = 16, 143f08c3bdfSopenharmony_ci .bad_ts_addr = 1, 144f08c3bdfSopenharmony_ci .ret = -1, 145f08c3bdfSopenharmony_ci .err = EFAULT, 146f08c3bdfSopenharmony_ci } 147f08c3bdfSopenharmony_ci}; 148f08c3bdfSopenharmony_ci 149f08c3bdfSopenharmony_cistatic void setup(void) 150f08c3bdfSopenharmony_ci{ 151f08c3bdfSopenharmony_ci struct time64_variants *tv = &variants[tst_variant]; 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci tst_res(TINFO, "Testing variant: %s", tv->desc); 154f08c3bdfSopenharmony_ci ts.type = tv->ts_type; 155f08c3bdfSopenharmony_ci 156f08c3bdfSopenharmony_ci bad_addr = tst_get_bad_addr(cleanup_common); 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ci setup_common(); 159f08c3bdfSopenharmony_ci} 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_cistatic void do_test(unsigned int i) 162f08c3bdfSopenharmony_ci{ 163f08c3bdfSopenharmony_ci struct time64_variants *tv = &variants[tst_variant]; 164f08c3bdfSopenharmony_ci const struct test_case *tc = &tcase[i]; 165f08c3bdfSopenharmony_ci unsigned int j; 166f08c3bdfSopenharmony_ci unsigned int prio; 167f08c3bdfSopenharmony_ci size_t len = MAX_MSGSIZE; 168f08c3bdfSopenharmony_ci char rmsg[len]; 169f08c3bdfSopenharmony_ci pid_t pid = -1; 170f08c3bdfSopenharmony_ci void *msg_ptr, *abs_timeout; 171f08c3bdfSopenharmony_ci 172f08c3bdfSopenharmony_ci tst_ts_set_sec(&ts, tc->tv_sec); 173f08c3bdfSopenharmony_ci tst_ts_set_nsec(&ts, tc->tv_nsec); 174f08c3bdfSopenharmony_ci 175f08c3bdfSopenharmony_ci if (tc->signal) 176f08c3bdfSopenharmony_ci pid = set_sig(tc->rq, tv->clock_gettime); 177f08c3bdfSopenharmony_ci 178f08c3bdfSopenharmony_ci if (tc->timeout) 179f08c3bdfSopenharmony_ci set_timeout(tc->rq, tv->clock_gettime); 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_ci if (tc->send) { 182f08c3bdfSopenharmony_ci for (j = 0; j < MSG_LENGTH; j++) 183f08c3bdfSopenharmony_ci if (tv->mqt_send(*tc->fd, smsg, tc->len, tc->prio, NULL) < 0) { 184f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "mq_timedsend() failed"); 185f08c3bdfSopenharmony_ci return; 186f08c3bdfSopenharmony_ci } 187f08c3bdfSopenharmony_ci } 188f08c3bdfSopenharmony_ci 189f08c3bdfSopenharmony_ci if (tc->bad_msg_addr) 190f08c3bdfSopenharmony_ci msg_ptr = bad_addr; 191f08c3bdfSopenharmony_ci else 192f08c3bdfSopenharmony_ci msg_ptr = smsg; 193f08c3bdfSopenharmony_ci 194f08c3bdfSopenharmony_ci if (tc->bad_ts_addr) 195f08c3bdfSopenharmony_ci abs_timeout = bad_addr; 196f08c3bdfSopenharmony_ci else 197f08c3bdfSopenharmony_ci abs_timeout = tst_ts_get(tc->rq); 198f08c3bdfSopenharmony_ci 199f08c3bdfSopenharmony_ci TEST(tv->mqt_send(*tc->fd, msg_ptr, tc->len, tc->prio, abs_timeout)); 200f08c3bdfSopenharmony_ci 201f08c3bdfSopenharmony_ci if (pid > 0) 202f08c3bdfSopenharmony_ci kill_pid(pid); 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci if (TST_RET < 0) { 205f08c3bdfSopenharmony_ci if (tc->err != TST_ERR) 206f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, 207f08c3bdfSopenharmony_ci "mq_timedsend() failed unexpectedly, expected %s", 208f08c3bdfSopenharmony_ci tst_strerrno(tc->err)); 209f08c3bdfSopenharmony_ci else 210f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "mq_timedsend() failed expectedly"); 211f08c3bdfSopenharmony_ci 212f08c3bdfSopenharmony_ci if (*tc->fd == fd) 213f08c3bdfSopenharmony_ci cleanup_queue(fd); 214f08c3bdfSopenharmony_ci 215f08c3bdfSopenharmony_ci return; 216f08c3bdfSopenharmony_ci } 217f08c3bdfSopenharmony_ci 218f08c3bdfSopenharmony_ci TEST(tv->mqt_receive(*tc->fd, rmsg, len, &prio, tst_ts_get(tc->rq))); 219f08c3bdfSopenharmony_ci 220f08c3bdfSopenharmony_ci if (*tc->fd == fd) 221f08c3bdfSopenharmony_ci cleanup_queue(fd); 222f08c3bdfSopenharmony_ci 223f08c3bdfSopenharmony_ci if (TST_RET < 0) { 224f08c3bdfSopenharmony_ci if (tc->err != TST_ERR) { 225f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, 226f08c3bdfSopenharmony_ci "mq_timedreceive() failed unexpectedly, expected %s", 227f08c3bdfSopenharmony_ci tst_strerrno(tc->err)); 228f08c3bdfSopenharmony_ci return; 229f08c3bdfSopenharmony_ci } 230f08c3bdfSopenharmony_ci 231f08c3bdfSopenharmony_ci if (tc->ret >= 0) { 232f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "mq_timedreceive() returned %ld, expected %d", 233f08c3bdfSopenharmony_ci TST_RET, tc->ret); 234f08c3bdfSopenharmony_ci return; 235f08c3bdfSopenharmony_ci } 236f08c3bdfSopenharmony_ci } 237f08c3bdfSopenharmony_ci 238f08c3bdfSopenharmony_ci if (tc->len != TST_RET) { 239f08c3bdfSopenharmony_ci tst_res(TFAIL, "mq_timedreceive() wrong length %ld, expected %u", 240f08c3bdfSopenharmony_ci TST_RET, tc->len); 241f08c3bdfSopenharmony_ci return; 242f08c3bdfSopenharmony_ci } 243f08c3bdfSopenharmony_ci 244f08c3bdfSopenharmony_ci if (tc->prio != prio) { 245f08c3bdfSopenharmony_ci tst_res(TFAIL, "mq_timedreceive() wrong prio %d, expected %d", 246f08c3bdfSopenharmony_ci prio, tc->prio); 247f08c3bdfSopenharmony_ci return; 248f08c3bdfSopenharmony_ci } 249f08c3bdfSopenharmony_ci 250f08c3bdfSopenharmony_ci for (j = 0; j < tc->len; j++) { 251f08c3bdfSopenharmony_ci if (rmsg[j] != smsg[j]) { 252f08c3bdfSopenharmony_ci tst_res(TFAIL, 253f08c3bdfSopenharmony_ci "mq_timedreceive() wrong data %d in %u, expected %d", 254f08c3bdfSopenharmony_ci rmsg[j], i, smsg[j]); 255f08c3bdfSopenharmony_ci return; 256f08c3bdfSopenharmony_ci } 257f08c3bdfSopenharmony_ci } 258f08c3bdfSopenharmony_ci 259f08c3bdfSopenharmony_ci tst_res(TPASS, "mq_timedreceive() returned %ld, priority %u, length: %zu", 260f08c3bdfSopenharmony_ci TST_RET, prio, len); 261f08c3bdfSopenharmony_ci} 262f08c3bdfSopenharmony_ci 263f08c3bdfSopenharmony_cistatic struct tst_test test = { 264f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcase), 265f08c3bdfSopenharmony_ci .test = do_test, 266f08c3bdfSopenharmony_ci .test_variants = ARRAY_SIZE(variants), 267f08c3bdfSopenharmony_ci .setup = setup, 268f08c3bdfSopenharmony_ci .cleanup = cleanup_common, 269f08c3bdfSopenharmony_ci .forks_child = 1, 270f08c3bdfSopenharmony_ci}; 271