blob: a20565b36c23e7b9411de68d8c28074904c0028b [file] [log] [blame]
robbiew577ff1a2002-12-05 20:12:28 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2002
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiew577ff1a2002-12-05 20:12:28 +000018 */
19
20/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */
21/* 11/06/2002 Port to LTP dbarrera@us.ibm.com */
subrata_modak6fa4a542008-04-06 11:44:36 +000022/* 12/03/2008 Fix concurrency issue mfertre@irisa.fr */
robbiew577ff1a2002-12-05 20:12:28 +000023
24/*
25 * NAME
26 * msgctl07
27 *
28 * CALLS
29 * msgget(2) msgctl(2) msgop(2)
30 *
31 * ALGORITHM
32 * Get and manipulate a message queue.
33 *
34 * RESTRICTIONS
35 *
36 */
37
Cyril Hrubis9e4b1172014-09-23 13:10:52 +020038#include <sys/types.h>
39#include <sys/ipc.h>
40#include <sys/msg.h>
41#include <signal.h>
42#include <wait.h>
43#include <stdio.h>
robbiew577ff1a2002-12-05 20:12:28 +000044#include "test.h"
subrata_modak6fa4a542008-04-06 11:44:36 +000045#include "ipcmsg.h"
robbiew577ff1a2002-12-05 20:12:28 +000046#include <stdlib.h>
47#include <unistd.h>
48#include <errno.h>
49
subrata_modak56207ce2009-03-23 13:35:39 +000050typedef void (*sighandler_t) (int);
robbiew577ff1a2002-12-05 20:12:28 +000051volatile int ready;
52
robbiew577ff1a2002-12-05 20:12:28 +000053#define BYTES 100
54#define SECS 10
55
56void setup();
57void cleanup();
robbiewd34d5812005-07-11 22:28:09 +000058void do_child_1();
59void do_child_2();
robbiew577ff1a2002-12-05 20:12:28 +000060
Cyril Hrubis9e4b1172014-09-23 13:10:52 +020061char *TCID = "msgctl07";
62int TST_TOTAL = 1;
robbiew577ff1a2002-12-05 20:12:28 +000063
robbiewd34d5812005-07-11 22:28:09 +000064/* Used by main() and do_child_1(): */
65static int msqid;
66struct my_msgbuf {
67 long type;
68 char text[BYTES];
69} p1_msgp, p2_msgp, p3_msgp, c1_msgp, c2_msgp, c3_msgp;
70
subrata_modak56207ce2009-03-23 13:35:39 +000071int main(int argc, char *argv[])
robbiew577ff1a2002-12-05 20:12:28 +000072{
73 key_t key;
robbiewd34d5812005-07-11 22:28:09 +000074 int pid, status;
robbiew577ff1a2002-12-05 20:12:28 +000075 int i, j, k;
robbiew577ff1a2002-12-05 20:12:28 +000076 sighandler_t alrm();
77
robbiewd34d5812005-07-11 22:28:09 +000078#ifdef UCLINUX
Cyril Hrubis74225622014-06-02 17:54:38 +020079 const char *msg;
robbiewd34d5812005-07-11 22:28:09 +000080
Cyril Hrubis74225622014-06-02 17:54:38 +020081 if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080082 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiewd34d5812005-07-11 22:28:09 +000083
84 maybe_run_child(&do_child_1, "ndd", 1, &msqid, &c1_msgp.type);
85 maybe_run_child(&do_child_2, "ndddd", 2, &msqid, &c1_msgp.type,
86 &c2_msgp.type, &c3_msgp.type);
87#endif
88
subrata_modak6fa4a542008-04-06 11:44:36 +000089 setup();
90
91 key = getipckey();
subrata_modak56207ce2009-03-23 13:35:39 +000092 if ((msqid = msgget(key, IPC_CREAT | IPC_EXCL)) == -1) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +010093 tst_brkm(TFAIL | TERRNO, NULL, "msgget() failed");
robbiew577ff1a2002-12-05 20:12:28 +000094
95 }
96
robbiewd34d5812005-07-11 22:28:09 +000097 pid = FORK_OR_VFORK();
robbiew577ff1a2002-12-05 20:12:28 +000098 if (pid < 0) {
Garrett Cooperdf3eb162010-11-28 22:44:32 -080099 (void)msgctl(msqid, IPC_RMID, NULL);
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100100 tst_brkm(TFAIL, NULL,
101 "\tFork failed (may be OK if under stress)");
subrata_modak56207ce2009-03-23 13:35:39 +0000102 } else if (pid == 0) {
robbiewd34d5812005-07-11 22:28:09 +0000103#ifdef UCLINUX
104 if (self_exec(argv[0], "ndd", 1, msqid, c1_msgp.type) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100105 tst_brkm(TFAIL, NULL, "\tself_exec failed");
robbiew577ff1a2002-12-05 20:12:28 +0000106 }
robbiewd34d5812005-07-11 22:28:09 +0000107#else
108 do_child_1();
109#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000110 } else {
robbiewd16a7932005-02-24 17:02:44 +0000111 struct sigaction act;
112
113 memset(&act, 0, sizeof(act));
114 act.sa_handler = (sighandler_t) alrm;
115 sigemptyset(&act.sa_mask);
116 sigaddset(&act.sa_mask, SIGALRM);
117 if ((sigaction(SIGALRM, &act, NULL)) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800118 tst_resm(TFAIL | TERRNO, "signal failed");
robbiew577ff1a2002-12-05 20:12:28 +0000119 kill(pid, SIGKILL);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800120 (void)msgctl(msqid, IPC_RMID, NULL);
subrata_modak56207ce2009-03-23 13:35:39 +0000121 tst_exit();
robbiew577ff1a2002-12-05 20:12:28 +0000122 }
123 ready = 0;
124 alarm(SECS);
subrata_modak56207ce2009-03-23 13:35:39 +0000125 while (!ready) /* make the child wait */
robbiew577ff1a2002-12-05 20:12:28 +0000126 ;
subrata_modak56207ce2009-03-23 13:35:39 +0000127 for (i = 0; i < BYTES; i++)
robbiew577ff1a2002-12-05 20:12:28 +0000128 p1_msgp.text[i] = 'i';
129 p1_msgp.type = 1;
130 if (msgsnd(msqid, &p1_msgp, BYTES, 0) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800131 tst_resm(TFAIL | TERRNO, "msgsnd() failed");
robbiew577ff1a2002-12-05 20:12:28 +0000132 kill(pid, SIGKILL);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800133 (void)msgctl(msqid, IPC_RMID, NULL);
subrata_modak56207ce2009-03-23 13:35:39 +0000134 tst_exit();
robbiew577ff1a2002-12-05 20:12:28 +0000135 }
136 wait(&status);
137 }
subrata_modak56207ce2009-03-23 13:35:39 +0000138 if ((status >> 8) == 1) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100139 tst_brkm(TFAIL, NULL, "test failed. status = %d",
140 (status >> 8));
robbiew577ff1a2002-12-05 20:12:28 +0000141 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000142
robbiewd34d5812005-07-11 22:28:09 +0000143 pid = FORK_OR_VFORK();
robbiew577ff1a2002-12-05 20:12:28 +0000144 if (pid < 0) {
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800145 (void)msgctl(msqid, IPC_RMID, NULL);
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100146 tst_brkm(TFAIL, NULL,
147 "\tFork failed (may be OK if under stress)");
subrata_modak56207ce2009-03-23 13:35:39 +0000148 } else if (pid == 0) {
robbiewd34d5812005-07-11 22:28:09 +0000149#ifdef UCLINUX
150 if (self_exec(argv[0], "ndddd", 1, msqid, c1_msgp.type,
151 c2_msgp.type, c3_msgp.type) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100152 tst_brkm(TFAIL, NULL, "\tself_exec failed");
robbiew577ff1a2002-12-05 20:12:28 +0000153 }
robbiewd34d5812005-07-11 22:28:09 +0000154#else
155 do_child_2();
156#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000157 } else {
robbiewd16a7932005-02-24 17:02:44 +0000158 struct sigaction act;
159
160 memset(&act, 0, sizeof(act));
161 act.sa_handler = (sighandler_t) alrm;
162 sigemptyset(&act.sa_mask);
163 sigaddset(&act.sa_mask, SIGALRM);
164 if ((sigaction(SIGALRM, &act, NULL)) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800165 tst_resm(TFAIL | TERRNO, "signal failed");
robbiew577ff1a2002-12-05 20:12:28 +0000166 kill(pid, SIGKILL);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800167 (void)msgctl(msqid, IPC_RMID, NULL);
subrata_modak56207ce2009-03-23 13:35:39 +0000168 tst_exit();
robbiew577ff1a2002-12-05 20:12:28 +0000169 }
170 ready = 0;
171 alarm(SECS);
subrata_modak56207ce2009-03-23 13:35:39 +0000172 while (!ready) /* make the child wait */
robbiew577ff1a2002-12-05 20:12:28 +0000173 ;
subrata_modak56207ce2009-03-23 13:35:39 +0000174 for (i = 0; i < BYTES; i++)
robbiew577ff1a2002-12-05 20:12:28 +0000175 p1_msgp.text[i] = 'i';
176 p1_msgp.type = 1;
177 if (msgsnd(msqid, &p1_msgp, BYTES, 0) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800178 tst_resm(TFAIL | TERRNO, "msgsnd() failed");
robbiew577ff1a2002-12-05 20:12:28 +0000179 kill(pid, SIGKILL);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800180 (void)msgctl(msqid, IPC_RMID, NULL);
subrata_modak56207ce2009-03-23 13:35:39 +0000181 tst_exit();
robbiew577ff1a2002-12-05 20:12:28 +0000182 }
subrata_modak56207ce2009-03-23 13:35:39 +0000183 for (j = 0; j < BYTES; j++)
robbiew577ff1a2002-12-05 20:12:28 +0000184 p2_msgp.text[j] = 'j';
185 p2_msgp.type = 2;
186 if (msgsnd(msqid, &p2_msgp, BYTES, 0) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800187 tst_resm(TFAIL | TERRNO, "msgsnd() failed");
robbiew577ff1a2002-12-05 20:12:28 +0000188 kill(pid, SIGKILL);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800189 (void)msgctl(msqid, IPC_RMID, NULL);
subrata_modak56207ce2009-03-23 13:35:39 +0000190 tst_exit();
robbiew577ff1a2002-12-05 20:12:28 +0000191 }
subrata_modak56207ce2009-03-23 13:35:39 +0000192 for (k = 0; k < BYTES; k++)
robbiew577ff1a2002-12-05 20:12:28 +0000193 p3_msgp.text[k] = 'k';
194 p3_msgp.type = 3;
195 if (msgsnd(msqid, &p3_msgp, BYTES, 0) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800196 tst_resm(TFAIL | TERRNO, "msgsnd() failed");
robbiew577ff1a2002-12-05 20:12:28 +0000197 kill(pid, SIGKILL);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800198 (void)msgctl(msqid, IPC_RMID, NULL);
subrata_modak56207ce2009-03-23 13:35:39 +0000199 tst_exit();
robbiew577ff1a2002-12-05 20:12:28 +0000200 }
201 wait(&status);
202 }
subrata_modak56207ce2009-03-23 13:35:39 +0000203 if ((status >> 8) == 1) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100204 tst_brkm(TFAIL, NULL, "test failed. status = %d",
205 (status >> 8));
robbiew577ff1a2002-12-05 20:12:28 +0000206 }
subrata_modak56207ce2009-03-23 13:35:39 +0000207 /*
robbiew577ff1a2002-12-05 20:12:28 +0000208 * Remove the message queue from the system
209 */
210#ifdef DEBUG
subrata_modak56207ce2009-03-23 13:35:39 +0000211 tst_resm(TINFO, "Removing the message queue");
robbiew577ff1a2002-12-05 20:12:28 +0000212#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000213 fflush(stdout);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800214 (void)msgctl(msqid, IPC_RMID, NULL);
215 if ((status = msgctl(msqid, IPC_STAT, NULL)) != -1) {
216 (void)msgctl(msqid, IPC_RMID, NULL);
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100217 tst_brkm(TFAIL, NULL, "msgctl(msqid, IPC_RMID) failed");
robbiew577ff1a2002-12-05 20:12:28 +0000218
subrata_modak56207ce2009-03-23 13:35:39 +0000219 }
robbiew577ff1a2002-12-05 20:12:28 +0000220
subrata_modak56207ce2009-03-23 13:35:39 +0000221 fflush(stdout);
222 tst_resm(TPASS, "msgctl07 ran successfully!");
robbiew577ff1a2002-12-05 20:12:28 +0000223
subrata_modak6fa4a542008-04-06 11:44:36 +0000224 cleanup();
225
Cyril Hrubis4dff8542014-09-23 12:11:59 +0200226 tst_exit();
robbiew577ff1a2002-12-05 20:12:28 +0000227}
subrata_modak56207ce2009-03-23 13:35:39 +0000228
subrata_modak6fa4a542008-04-06 11:44:36 +0000229sighandler_t alrm(int sig)
robbiew577ff1a2002-12-05 20:12:28 +0000230{
231 ready++;
subrata_modak43337a32009-02-26 11:43:51 +0000232 return 0;
robbiew577ff1a2002-12-05 20:12:28 +0000233}
subrata_modak56207ce2009-03-23 13:35:39 +0000234
Mike Frysingerc57fba52014-04-09 18:56:30 -0400235void do_child_1(void)
subrata_modakbdbaec52009-02-26 12:14:51 +0000236{
robbiewd34d5812005-07-11 22:28:09 +0000237 int i;
238 int size;
239
subrata_modak56207ce2009-03-23 13:35:39 +0000240 if ((size = msgrcv(msqid, &c1_msgp, BYTES, 0, 0)) == -1) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100241 tst_brkm(TFAIL | TERRNO, NULL, "msgrcv() failed");
robbiewd34d5812005-07-11 22:28:09 +0000242 }
subrata_modak56207ce2009-03-23 13:35:39 +0000243 if (size != BYTES) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100244 tst_brkm(TFAIL, NULL, "error: received %d bytes expected %d",
245 size,
subrata_modak56207ce2009-03-23 13:35:39 +0000246 BYTES);
robbiewd34d5812005-07-11 22:28:09 +0000247 }
subrata_modak56207ce2009-03-23 13:35:39 +0000248 for (i = 0; i < BYTES; i++)
249 if (c1_msgp.text[i] != 'i') {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100250 tst_brkm(TFAIL, NULL, "error: corrup message");
robbiewd34d5812005-07-11 22:28:09 +0000251 }
252 exit(0);
253}
254
Mike Frysingerc57fba52014-04-09 18:56:30 -0400255void do_child_2(void)
robbiewd34d5812005-07-11 22:28:09 +0000256{
257 int i, j, k;
258 int size;
259
260 if ((size = msgrcv(msqid, &c3_msgp, BYTES, 3, 0)) == -1) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100261 tst_brkm(TFAIL | TERRNO, NULL, "msgrcv() failed");
robbiewd34d5812005-07-11 22:28:09 +0000262 }
263 if (size != BYTES) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100264 tst_brkm(TFAIL, NULL, "error: received %d bytes expected %d",
265 size,
subrata_modak56207ce2009-03-23 13:35:39 +0000266 BYTES);
robbiewd34d5812005-07-11 22:28:09 +0000267 }
subrata_modak56207ce2009-03-23 13:35:39 +0000268 for (k = 0; k < BYTES; k++)
robbiewd34d5812005-07-11 22:28:09 +0000269 if (c3_msgp.text[k] != 'k') {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100270 tst_brkm(TFAIL, NULL, "error: corrupt message");
robbiewd34d5812005-07-11 22:28:09 +0000271 }
272 if ((size = msgrcv(msqid, &c2_msgp, BYTES, 2, 0)) == -1) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100273 tst_brkm(TFAIL | TERRNO, NULL, "msgrcv() failed");
robbiewd34d5812005-07-11 22:28:09 +0000274 }
275 if (size != BYTES) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100276 tst_brkm(TFAIL, NULL, "error: received %d bytes expected %d",
277 size,
subrata_modak56207ce2009-03-23 13:35:39 +0000278 BYTES);
robbiewd34d5812005-07-11 22:28:09 +0000279 }
subrata_modak56207ce2009-03-23 13:35:39 +0000280 for (j = 0; j < BYTES; j++)
robbiewd34d5812005-07-11 22:28:09 +0000281 if (c2_msgp.text[j] != 'j') {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100282 tst_brkm(TFAIL, NULL, "error: corrupt message");
robbiewd34d5812005-07-11 22:28:09 +0000283 }
284 if ((size = msgrcv(msqid, &c1_msgp, BYTES, 1, 0)) == -1) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100285 tst_brkm(TFAIL | TERRNO, NULL, "msgrcv() failed");
robbiewd34d5812005-07-11 22:28:09 +0000286 }
287 if (size != BYTES) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100288 tst_brkm(TFAIL, NULL, "error: received %d bytes expected %d",
289 size,
subrata_modak56207ce2009-03-23 13:35:39 +0000290 BYTES);
robbiewd34d5812005-07-11 22:28:09 +0000291 }
subrata_modak56207ce2009-03-23 13:35:39 +0000292 for (i = 0; i < BYTES; i++)
robbiewd34d5812005-07-11 22:28:09 +0000293 if (c1_msgp.text[i] != 'i') {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100294 tst_brkm(TFAIL, NULL, "error: corrupt message");
robbiewd34d5812005-07-11 22:28:09 +0000295 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000296
robbiewd34d5812005-07-11 22:28:09 +0000297 exit(0);
298}
299
Mike Frysingerc57fba52014-04-09 18:56:30 -0400300void setup(void)
robbiew577ff1a2002-12-05 20:12:28 +0000301{
subrata_modak56207ce2009-03-23 13:35:39 +0000302 tst_sig(FORK, DEF_HANDLER, cleanup);
robbiew577ff1a2002-12-05 20:12:28 +0000303
robbiew577ff1a2002-12-05 20:12:28 +0000304 TEST_PAUSE;
subrata_modak6fa4a542008-04-06 11:44:36 +0000305
subrata_modak6fa4a542008-04-06 11:44:36 +0000306 tst_tmpdir();
robbiew577ff1a2002-12-05 20:12:28 +0000307}
308
Mike Frysingerc57fba52014-04-09 18:56:30 -0400309void cleanup(void)
robbiew577ff1a2002-12-05 20:12:28 +0000310{
subrata_modak6fa4a542008-04-06 11:44:36 +0000311 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700312}