• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2014 Fujitsu Ltd.
3  * Author: Xiaoguang Wang <wangxg.fnst@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 
main(int ac,char ** av)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 
setup(void)64 void setup(void)
65 {
66 	tst_sig(FORK, DEF_HANDLER, cleanup);
67 
68 	TEST_PAUSE;
69 }
70 
test_msg_except(void)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 
test_msg_noerror(void)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 
wait4child(pid_t child,char * tst_flag)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 
cleanup(void)170 void cleanup(void)
171 {
172 }
173