Home | History | Annotate | Line # | Download | only in kernel
t_mqueue.c revision 1.4.8.1
      1 /*	$NetBSD: t_mqueue.c,v 1.4.8.1 2017/03/20 06:57:57 pgoyette Exp $ */
      2 
      3 /*
      4  * Test for POSIX message queue priority handling.
      5  *
      6  * This file is in the Public Domain.
      7  */
      8 
      9 #include <sys/stat.h>
     10 
     11 #include <atf-c.h>
     12 #include <errno.h>
     13 #include <fcntl.h>
     14 #include <mqueue.h>
     15 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <string.h>
     18 #include <unistd.h>
     19 
     20 #define	MQ_PRIO_BASE	24
     21 
     22 static void
     23 send_msgs(mqd_t mqfd)
     24 {
     25 	char msg[2];
     26 
     27 	msg[1] = '\0';
     28 
     29 	msg[0] = 'a';
     30 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
     31 	    "mq_send 1 failed: %d", errno);
     32 
     33 	msg[0] = 'b';
     34 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
     35 	    "mq_send 2 failed: %d", errno);
     36 
     37 	msg[0] = 'c';
     38 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
     39 	    "mq_send 3 failed: %d", errno);
     40 
     41 	msg[0] = 'd';
     42 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1,
     43 	    "mq_send 4 failed: %d", errno);
     44 
     45 	msg[0] = 'e';
     46 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1,
     47 	    "mq_send 5 failed: %d", errno);
     48 
     49 	msg[0] = 'f';
     50 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
     51 	    "mq_send 6 failed: %d", errno);
     52 }
     53 
     54 static void
     55 receive_msgs(mqd_t mqfd)
     56 {
     57 	struct mq_attr mqa;
     58 	char *m;
     59 	unsigned p;
     60 	int len;
     61 
     62 	ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d",
     63 	    errno);
     64 
     65 	len = mqa.mq_msgsize;
     66 	m = calloc(1, len);
     67 	ATF_REQUIRE_MSG(m != NULL, "calloc failed");
     68 
     69 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
     70 	    "mq_receive 1 failed: %d", errno);
     71 	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b',
     72 	    "mq_receive 1 prio/data mismatch");
     73 
     74 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
     75 	    "mq_receive 2 failed: %d", errno);
     76 	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f',
     77 	    "mq_receive 2 prio/data mismatch");
     78 
     79 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
     80 	    "mq_receive 3 failed: %d", errno);
     81 	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a',
     82 	    "mq_receive 3 prio/data mismatch");
     83 
     84 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
     85 	    "mq_receive 4 failed: %d", errno);
     86 	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c',
     87 	    "mq_receive 4 prio/data mismatch");
     88 
     89 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
     90 	    "mq_receive 5 failed: %d", errno);
     91 	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd',
     92 	    "mq_receive 5 prio/data mismatch");
     93 
     94 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
     95 	    "mq_receive 6 failed: %d", errno);
     96 	ATF_REQUIRE_MSG(p == 0 && m[0] == 'e',
     97 	    "mq_receive 6 prio/data mismatch");
     98 }
     99 
    100 ATF_TC(mqueue);
    101 ATF_TC_HEAD(mqueue, tc)
    102 {
    103 
    104 	atf_tc_set_md_var(tc, "timeout", "3");
    105 	atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive");
    106 }
    107 
    108 ATF_TC_BODY(mqueue, tc)
    109 {
    110 	int status;
    111 	char *tmpdir;
    112 	char template[32];
    113 	char mq_name[64];
    114 
    115 	strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template));
    116 	tmpdir = mkdtemp(template);
    117 	ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno);
    118 	snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir);
    119 
    120 	mqd_t mqfd;
    121 
    122 	mqfd = mq_open(mq_name, O_RDWR | O_CREAT,
    123 	    S_IRUSR | S_IRWXG | S_IROTH, NULL);
    124 	ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno);
    125 
    126 	send_msgs(mqfd);
    127 	receive_msgs(mqfd);
    128 
    129 	status = mq_close(mqfd);
    130 	ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno);
    131 }
    132 
    133 ATF_TP_ADD_TCS(tp)
    134 {
    135 	ATF_TP_ADD_TC(tp, mqueue);
    136 
    137 	return atf_no_error();
    138 }
    139