1 /* 2 * Copyright (c) 2014 Fujitsu Ltd. 3 * Author: Xiaoguang Wang <wangxg.fnst (at) cn.fujitsu.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write the Free Software Foundation, Inc., 15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 */ 17 18 /* 19 * Description: 20 * Basic test for msgrcv(2) using MSG_EXCEPT, MSG_NOERROR 21 */ 22 23 #define _GNU_SOURCE 24 #include <sys/wait.h> 25 #include "test.h" 26 #include "ipcmsg.h" 27 28 29 #define MSGTYPE1 1 30 #define MSGTYPE2 2 31 #define MSG1 "message type1" 32 #define MSG2 "message type2" 33 34 static void wait4child(pid_t child, char *tst_flag); 35 36 static void test_msg_except(void); 37 static void test_msg_noerror(void); 38 39 static void (*testfunc[])(void) = { test_msg_except, test_msg_noerror }; 40 41 char *TCID = "msgrcv07"; 42 int TST_TOTAL = ARRAY_SIZE(testfunc); 43 44 int main(int ac, char **av) 45 { 46 int lc; 47 int i; 48 49 tst_parse_opts(ac, av, NULL, NULL); 50 51 setup(); 52 53 for (lc = 0; TEST_LOOPING(lc); lc++) { 54 tst_count = 0; 55 56 for (i = 0; i < TST_TOTAL; i++) 57 (*testfunc[i])(); 58 } 59 60 cleanup(); 61 tst_exit(); 62 } 63 64 void setup(void) 65 { 66 tst_sig(FORK, DEF_HANDLER, cleanup); 67 68 TEST_PAUSE; 69 } 70 71 static void test_msg_except(void) 72 { 73 pid_t child_pid; 74 int msgq_id; 75 MSGBUF snd_buf1 = {.mtype = MSGTYPE1, .mtext = MSG1}; 76 MSGBUF snd_buf2 = {.mtype = MSGTYPE2, .mtext = MSG2}; 77 MSGBUF rcv_buf; 78 79 msgq_id = msgget(IPC_PRIVATE, MSG_RW); 80 if (msgq_id == -1) 81 tst_brkm(TBROK | TERRNO, cleanup, "Can't create message queue"); 82 83 if (msgsnd(msgq_id, &snd_buf1, MSGSIZE, 0) == -1) 84 tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message"); 85 86 if (msgsnd(msgq_id, &snd_buf2, MSGSIZE, 0) == -1) 87 tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message"); 88 89 child_pid = tst_fork(); 90 if (child_pid == -1) { 91 tst_brkm(TBROK, cleanup, "fork failed"); 92 } else if (child_pid > 0) { 93 wait4child(child_pid, "MSG_EXCEPT"); 94 } else { 95 memset(&rcv_buf, 0, sizeof(rcv_buf)); 96 TEST(msgrcv(msgq_id, &rcv_buf, MSGSIZE, MSGTYPE2, MSG_EXCEPT)); 97 if (TEST_RETURN == -1) { 98 fprintf(stderr, "msgrcv(MSG_EXCEPT) failed\n"); 99 exit(TBROK); 100 } 101 /* check the received message */ 102 if (strcmp(rcv_buf.mtext, MSG1) == 0 && 103 rcv_buf.mtype == MSGTYPE1) 104 exit(TPASS); 105 else 106 exit(TFAIL); 107 } 108 109 rm_queue(msgq_id); 110 } 111 112 113 static void test_msg_noerror(void) 114 { 115 pid_t child_pid; 116 int msg_len, msgq_id; 117 MSGBUF snd_buf1 = {.mtype = MSGTYPE1, .mtext = MSG1}; 118 MSGBUF rcv_buf; 119 120 msgq_id = msgget(IPC_PRIVATE, MSG_RW); 121 if (msgq_id == -1) 122 tst_brkm(TBROK | TERRNO, cleanup, "Can't create message queue"); 123 124 if (msgsnd(msgq_id, &snd_buf1, MSGSIZE, 0) == -1) 125 tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message"); 126 127 child_pid = tst_fork(); 128 if (child_pid == -1) { 129 tst_brkm(TBROK, cleanup, "fork failed"); 130 } else if (child_pid > 0) { 131 wait4child(child_pid, "MSG_NOERROR"); 132 } else { 133 msg_len = sizeof(MSG1) / 2; 134 memset(&rcv_buf, 0, sizeof(rcv_buf)); 135 136 TEST(msgrcv(msgq_id, &rcv_buf, msg_len, MSGTYPE1, MSG_NOERROR)); 137 if (TEST_RETURN == -1) 138 exit(TFAIL); 139 140 if (strncmp(rcv_buf.mtext, MSG1, msg_len) == 0 && 141 rcv_buf.mtype == MSGTYPE1) 142 exit(TPASS); 143 exit(TFAIL); 144 } 145 146 rm_queue(msgq_id); 147 } 148 149 static void wait4child(pid_t child, char *tst_flag) 150 { 151 int status; 152 int ret; 153 154 if (waitpid(child, &status, 0) == -1) 155 tst_resm(TBROK | TERRNO, "waitpid"); 156 if (WIFEXITED(status)) { 157 ret = WEXITSTATUS(status); 158 if (ret == 0) 159 tst_resm(TPASS, "test %s success", tst_flag); 160 else if (ret == 1) 161 tst_resm(TFAIL, "test %s failed", tst_flag); 162 else 163 tst_brkm(TBROK, cleanup, "msgrcv failed unexpectedly"); 164 } else { 165 tst_brkm(TBROK, cleanup, "child process terminated " 166 "abnormally. status: %d", status); 167 } 168 } 169 170 void cleanup(void) 171 { 172 } 173