blob: 9cbe07759698fd3f47f738748da83faac2414107 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
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
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
22 * msgrcv05.c
23 *
24 * DESCRIPTION
25 * msgrcv05 - test for EINTR error
26 *
27 * ALGORITHM
28 * create a message queue with read/write permissions
29 * loop if that option was specified
30 * fork a child who attempts to read a non-existent message with msgrcv()
robbiewd34d5812005-07-11 22:28:09 +000031 * parent sends a SIGHUP to the child, then waits for the child to complete
plars865695b2001-08-27 22:15:12 +000032 * check the errno value
33 * issue a PASS message if we get EINTR
34 * otherwise, the tests fails
35 * issue a FAIL message
robbiewd34d5812005-07-11 22:28:09 +000036 * child exits, parent calls cleanup
plars865695b2001-08-27 22:15:12 +000037 *
38 * USAGE: <for command-line>
39 * msgrcv05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
40 * where, -c n : Run n copies concurrently.
41 * -e : Turn on errno logging.
42 * -i n : Execute test n times.
43 * -I x : Execute test for x seconds.
44 * -P x : Pause for x seconds between iterations.
45 * -t : Turn on syscall timing.
46 *
47 * HISTORY
48 * 03/2001 - Written by Wayne Boyer
subrata_modakc79243b2008-04-06 11:47:48 +000049 * 14/03/2008 Matthieu Fertré (Matthieu.Fertre@irisa.fr)
50 * - Fix concurrency issue. Due to the use of usleep function to
51 * synchronize processes, synchronization issues can occur on a loaded
52 * system. Fix this by using pipes to synchronize processes.
plars865695b2001-08-27 22:15:12 +000053 *
54 * RESTRICTIONS
55 * none
56 */
57
58#include "test.h"
plars865695b2001-08-27 22:15:12 +000059
robbiew23499f02002-11-18 19:54:58 +000060#include "ipcmsg.h"
subrata_modak39fe9772008-06-03 14:38:50 +000061#include "libtestsuite.h"
plars865695b2001-08-27 22:15:12 +000062
robbiewd34d5812005-07-11 22:28:09 +000063#include <sys/types.h>
64#include <sys/wait.h>
65
66void do_child(void);
plars865695b2001-08-27 22:15:12 +000067void cleanup(void);
68void setup(void);
robbiewd34d5812005-07-11 22:28:09 +000069#ifdef UCLINUX
subrata_modak4b13c892009-01-22 09:51:33 +000070#define PIPE_NAME "msgrcv05"
robbiewd34d5812005-07-11 22:28:09 +000071void do_child_uclinux(void);
72#endif
plars865695b2001-08-27 22:15:12 +000073
74char *TCID = "msgrcv05";
75int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000076
plars865695b2001-08-27 22:15:12 +000077int msg_q_1 = -1; /* The message queue id created in setup */
78
subrata_modak4b13c892009-01-22 09:51:33 +000079int sync_pipes[2];
80
plars865695b2001-08-27 22:15:12 +000081MSGBUF rcv_buf;
82pid_t c_pid;
83
robbiew23499f02002-11-18 19:54:58 +000084int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000085{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020086 int lc;
Cyril Hrubis74225622014-06-02 17:54:38 +020087 const char *msg;
plars865695b2001-08-27 22:15:12 +000088
Garrett Cooper9307ff62010-12-20 15:47:10 -080089 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080090 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper9307ff62010-12-20 15:47:10 -080091
robbiewd34d5812005-07-11 22:28:09 +000092#ifdef UCLINUX
93 maybe_run_child(&do_child_uclinux, "d", &msg_q_1);
94#endif
95
subrata_modak56207ce2009-03-23 13:35:39 +000096 setup(); /* global setup */
plars865695b2001-08-27 22:15:12 +000097
subrata_modak4b13c892009-01-22 09:51:33 +000098 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
subrata_modak8791f672008-05-20 10:11:00 +000099 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
subrata_modakc79243b2008-04-06 11:47:48 +0000100
plars865695b2001-08-27 22:15:12 +0000101 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800102 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000103
104 /*
105 * fork a child that will attempt to read a non-existent
106 * message from the queue
107 */
Garrett Cooper9307ff62010-12-20 15:47:10 -0800108 if ((c_pid = FORK_OR_VFORK()) == -1)
plars865695b2001-08-27 22:15:12 +0000109 tst_brkm(TBROK, cleanup, "could not fork");
plars865695b2001-08-27 22:15:12 +0000110
Garrett Cooper9307ff62010-12-20 15:47:10 -0800111 if (c_pid == 0) {
plars865695b2001-08-27 22:15:12 +0000112 /*
113 * Attempt to read a message without IPC_NOWAIT.
114 * With no message to read, the child sleeps.
115 */
subrata_modakc79243b2008-04-06 11:47:48 +0000116
robbiewd34d5812005-07-11 22:28:09 +0000117#ifdef UCLINUX
Garrett Cooper9307ff62010-12-20 15:47:10 -0800118 if (self_exec(av[0], "d", msg_q_1) < 0)
robbiewd34d5812005-07-11 22:28:09 +0000119 tst_brkm(TBROK, cleanup, "could not self_exec");
robbiewd34d5812005-07-11 22:28:09 +0000120#else
121 do_child();
122#endif
Garrett Cooper9307ff62010-12-20 15:47:10 -0800123 } else {
subrata_modakc79243b2008-04-06 11:47:48 +0000124
subrata_modak8791f672008-05-20 10:11:00 +0000125 if (sync_pipe_wait(sync_pipes) == -1)
subrata_modak56207ce2009-03-23 13:35:39 +0000126 tst_brkm(TBROK, cleanup,
127 "sync_pipe_wait failed");
subrata_modak8791f672008-05-20 10:11:00 +0000128
subrata_modak4b13c892009-01-22 09:51:33 +0000129 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
subrata_modak56207ce2009-03-23 13:35:39 +0000130 tst_brkm(TBROK, cleanup,
131 "sync_pipe_close failed");
subrata_modak8791f672008-05-20 10:11:00 +0000132
subrata_modakc79243b2008-04-06 11:47:48 +0000133 /* After son has been created, give it a chance to execute the
134 * msgrcv command before we continue. Without this sleep, on SMP machine
135 * the father kill could be executed before the son msgrcv.
136 */
137 sleep(1);
plars865695b2001-08-27 22:15:12 +0000138
139 /* send a signal that must be caught to the child */
Garrett Cooper9307ff62010-12-20 15:47:10 -0800140 if (kill(c_pid, SIGHUP) == -1)
plars865695b2001-08-27 22:15:12 +0000141 tst_brkm(TBROK, cleanup, "kill failed");
plars865695b2001-08-27 22:15:12 +0000142
robbiewd34d5812005-07-11 22:28:09 +0000143 waitpid(c_pid, NULL, 0);
plars865695b2001-08-27 22:15:12 +0000144 }
plars865695b2001-08-27 22:15:12 +0000145 }
146
147 cleanup();
148
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800149 tst_exit();
plars865695b2001-08-27 22:15:12 +0000150}
151
Mike Frysingerc57fba52014-04-09 18:56:30 -0400152void do_child(void)
robbiewd34d5812005-07-11 22:28:09 +0000153{
subrata_modak4b13c892009-01-22 09:51:33 +0000154 if (sync_pipe_notify(sync_pipes) == -1)
155 tst_brkm(TBROK, cleanup, "sync_pipe_notify failed");
156
157 if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1)
158 tst_brkm(TBROK, cleanup, "sync_pipe_close failed");
159
robbiewd34d5812005-07-11 22:28:09 +0000160 TEST(msgrcv(msg_q_1, &rcv_buf, MSGSIZE, 1, 0));
161
Garrett Cooper9307ff62010-12-20 15:47:10 -0800162 if (TEST_RETURN != -1)
163 tst_brkm(TFAIL, NULL, "call succeeded unexpectedly");
subrata_modakbdbaec52009-02-26 12:14:51 +0000164
subrata_modak56207ce2009-03-23 13:35:39 +0000165 switch (TEST_ERRNO) {
robbiewd34d5812005-07-11 22:28:09 +0000166 case EINTR:
Garrett Cooper9307ff62010-12-20 15:47:10 -0800167 tst_resm(TPASS, "got EINTR as expected");
robbiewd34d5812005-07-11 22:28:09 +0000168 break;
subrata_modak56207ce2009-03-23 13:35:39 +0000169 default:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800170 tst_resm(TFAIL | TTERRNO,
171 "call failed with an unexpected error");
subrata_modak56207ce2009-03-23 13:35:39 +0000172 break;
173 }
robbiewd34d5812005-07-11 22:28:09 +0000174
175 exit(0);
176}
177
Wanlong Gao354ebb42012-12-07 10:10:04 +0800178void sighandler(int sig)
Garrett Cooper9307ff62010-12-20 15:47:10 -0800179{
180 if (sig == SIGHUP)
181 return;
182 else
183 tst_brkm(TBROK, NULL, "unexpected signal %d received", sig);
184}
185
robbiewd34d5812005-07-11 22:28:09 +0000186#ifdef UCLINUX
187/*
188 * do_child_uclinux() - capture signals again, then run do_child()
189 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400190void do_child_uclinux(void)
robbiewd34d5812005-07-11 22:28:09 +0000191{
subrata_modak4b13c892009-01-22 09:51:33 +0000192 if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1)
193 tst_brkm(TBROK, cleanup, "sync_pipe_create failed");
194
Garrett Cooper9307ff62010-12-20 15:47:10 -0800195 tst_sig(FORK, sighandler, cleanup);
robbiewd34d5812005-07-11 22:28:09 +0000196
197 do_child();
198}
199#endif
200
201/*
plars865695b2001-08-27 22:15:12 +0000202 * setup() - performs all the ONE TIME setup for this test.
203 */
subrata_modak56207ce2009-03-23 13:35:39 +0000204void setup(void)
plars865695b2001-08-27 22:15:12 +0000205{
Garrett Cooper2c282152010-12-16 00:55:50 -0800206
Garrett Cooper9307ff62010-12-20 15:47:10 -0800207 tst_sig(FORK, sighandler, cleanup);
plars865695b2001-08-27 22:15:12 +0000208
plars865695b2001-08-27 22:15:12 +0000209 TEST_PAUSE;
210
211 /*
212 * Create a temporary directory and cd into it.
213 * This helps to ensure that a unique msgkey is created.
214 * See ../lib/libipc.c for more information.
215 */
216 tst_tmpdir();
217
218 msgkey = getipckey();
219
220 /* create a message queue with read/write permission */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800221 if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1)
plars865695b2001-08-27 22:15:12 +0000222 tst_brkm(TBROK, cleanup, "Can't create message queue");
plars865695b2001-08-27 22:15:12 +0000223}
224
225/*
226 * cleanup() - performs all the ONE TIME cleanup for this test at completion
227 * or premature exit.
228 */
subrata_modak56207ce2009-03-23 13:35:39 +0000229void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000230{
231 /* if it exists, remove the message queue that was created */
232 rm_queue(msg_q_1);
233
plars865695b2001-08-27 22:15:12 +0000234 tst_rmdir();
235
Garrett Cooper52626672010-12-20 15:03:21 -0800236}