blob: 2f09f409cff19830eafe71d62f410d08a92948be [file] [log] [blame]
Xiaoguang Wang22d33012014-02-12 16:06:10 +08001/*
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"
Xiaoguang Wang22d33012014-02-12 16:06:10 +080026#include "ipcmsg.h"
27
28
29#define MSGTYPE1 1
30#define MSGTYPE2 2
31#define MSG1 "message type1"
32#define MSG2 "message type2"
33
34static void wait4child(pid_t child, char *tst_flag);
35
36static void test_msg_except(void);
37static void test_msg_noerror(void);
38
39static void (*testfunc[])(void) = { test_msg_except, test_msg_noerror };
40
41char *TCID = "msgrcv07";
42int TST_TOTAL = ARRAY_SIZE(testfunc);
43
44int main(int ac, char **av)
45{
46 int lc;
Cyril Hrubis74225622014-06-02 17:54:38 +020047 const char *msg;
Xiaoguang Wang22d33012014-02-12 16:06:10 +080048 int i;
49
50 msg = parse_opts(ac, av, NULL, NULL);
51 if (msg != NULL)
52 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
53
54 setup();
55
56 for (lc = 0; TEST_LOOPING(lc); lc++) {
57 tst_count = 0;
58
59 for (i = 0; i < TST_TOTAL; i++)
60 (*testfunc[i])();
61 }
62
63 cleanup();
64 tst_exit();
65}
66
67void setup(void)
68{
69 tst_sig(FORK, DEF_HANDLER, cleanup);
70
71 TEST_PAUSE;
72}
73
74static void test_msg_except(void)
75{
76 pid_t child_pid;
77 int msgq_id;
78 MSGBUF snd_buf1 = {.mtype = MSGTYPE1, .mtext = MSG1};
79 MSGBUF snd_buf2 = {.mtype = MSGTYPE2, .mtext = MSG2};
80 MSGBUF rcv_buf;
81
82 msgq_id = msgget(IPC_PRIVATE, MSG_RW);
83 if (msgq_id == -1)
84 tst_brkm(TBROK | TERRNO, cleanup, "Can't create message queue");
85
86 if (msgsnd(msgq_id, &snd_buf1, MSGSIZE, 0) == -1)
87 tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message");
88
89 if (msgsnd(msgq_id, &snd_buf2, MSGSIZE, 0) == -1)
90 tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message");
91
92 child_pid = tst_fork();
93 if (child_pid == -1) {
94 tst_brkm(TBROK, cleanup, "fork failed");
95 } else if (child_pid > 0) {
96 wait4child(child_pid, "MSG_EXCEPT");
97 } else {
98 memset(&rcv_buf, 0, sizeof(rcv_buf));
99 TEST(msgrcv(msgq_id, &rcv_buf, MSGSIZE, MSGTYPE2, MSG_EXCEPT));
100 if (TEST_RETURN == -1) {
101 fprintf(stderr, "msgrcv(MSG_EXCEPT) failed\n");
102 exit(TBROK);
103 }
104 /* check the received message */
105 if (strcmp(rcv_buf.mtext, MSG1) == 0 &&
106 rcv_buf.mtype == MSGTYPE1)
107 exit(TPASS);
108 else
109 exit(TFAIL);
110 }
111
112 rm_queue(msgq_id);
113}
114
115
116static void test_msg_noerror(void)
117{
118 pid_t child_pid;
119 int msg_len, msgq_id;
120 MSGBUF snd_buf1 = {.mtype = MSGTYPE1, .mtext = MSG1};
121 MSGBUF rcv_buf;
122
123 msgq_id = msgget(IPC_PRIVATE, MSG_RW);
124 if (msgq_id == -1)
125 tst_brkm(TBROK | TERRNO, cleanup, "Can't create message queue");
126
127 if (msgsnd(msgq_id, &snd_buf1, MSGSIZE, 0) == -1)
128 tst_brkm(TBROK | TERRNO, cleanup, "Can't enqueue message");
129
130 child_pid = tst_fork();
131 if (child_pid == -1) {
132 tst_brkm(TBROK, cleanup, "fork failed");
133 } else if (child_pid > 0) {
134 wait4child(child_pid, "MSG_NOERROR");
135 } else {
136 msg_len = sizeof(MSG1) / 2;
137 memset(&rcv_buf, 0, sizeof(rcv_buf));
138
139 TEST(msgrcv(msgq_id, &rcv_buf, msg_len, MSGTYPE1, MSG_NOERROR));
140 if (TEST_RETURN == -1)
141 exit(TFAIL);
142
143 if (strncmp(rcv_buf.mtext, MSG1, msg_len) == 0 &&
144 rcv_buf.mtype == MSGTYPE1)
145 exit(TPASS);
146 exit(TFAIL);
147 }
148
149 rm_queue(msgq_id);
150}
151
152static void wait4child(pid_t child, char *tst_flag)
153{
154 int status;
155 int ret;
156
157 if (waitpid(child, &status, 0) == -1)
158 tst_resm(TBROK | TERRNO, "waitpid");
159 if (WIFEXITED(status)) {
160 ret = WEXITSTATUS(status);
161 if (ret == 0)
162 tst_resm(TPASS, "test %s success", tst_flag);
163 else if (ret == 1)
164 tst_resm(TFAIL, "test %s failed", tst_flag);
165 else
166 tst_brkm(TBROK, cleanup, "msgrcv failed unexpectedly");
167 } else {
168 tst_brkm(TBROK, cleanup, "child process terminated "
169 "abnormally. status: %d", status);
170 }
171}
172
173void cleanup(void)
174{
Xiaoguang Wang22d33012014-02-12 16:06:10 +0800175}