1 /*
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
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * msgsnd01.c
23 *
24 * DESCRIPTION
25 * msgsnd01 - test that msgsnd() enqueues a message correctly
26 *
27 * ALGORITHM
28 * create a message queue
29 * initialize a message buffer with a known message and type
30 * loop if that option was specified
31 * enqueue the message
32 * check the return code
33 * if failure, issue a FAIL message.
34 * otherwise,
35 * if doing functionality testing
36 * stat the message queue
37 * check for # of bytes = MSGSIZE and # of messages = 1
38 * if correct,
39 * issue a PASS message
40 * otherwise
41 * issue a FAIL message
42 * call cleanup
43 *
44 * USAGE: <for command-line>
45 * msgsnd01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
46 * where, -c n : Run n copies concurrently.
47 * -f : Turn off functionality Testing.
48 * -i n : Execute test n times.
49 * -I x : Execute test for x seconds.
50 * -P x : Pause for x seconds between iterations.
51 * -t : Turn on syscall timing.
52 *
53 * HISTORY
54 * 03/2001 - Written by Wayne Boyer
55 *
56 * RESTRICTIONS
57 * None
58 */
59
60 #include "test.h"
61
62 #include "ipcmsg.h"
63
64 void cleanup(void);
65 void setup(void);
66
67 char *TCID = "msgsnd01";
68 int TST_TOTAL = 1;
69
70 int msg_q_1;
71 MSGBUF msg_buf, rd_buf;
72
73 struct msqid_ds qs_buf;
74
main(int ac,char ** av)75 int main(int ac, char **av)
76 {
77 int lc;
78
79 tst_parse_opts(ac, av, NULL, NULL);
80
81 setup(); /* global setup */
82
83 /* The following loop checks looping state if -i option given */
84
85 for (lc = 0; TEST_LOOPING(lc); lc++) {
86 /* reset tst_count in case we are looping */
87 tst_count = 0;
88
89 /*
90 * Use TEST macro to make the call
91 */
92
93 TEST(msgsnd(msg_q_1, &msg_buf, MSGSIZE, 0));
94
95 if (TEST_RETURN == -1) {
96 tst_resm(TFAIL, "%s call failed - errno = %d : %s",
97 TCID, TEST_ERRNO, strerror(TEST_ERRNO));
98 continue;
99 }
100
101 /* get the queue status */
102 if (msgctl(msg_q_1, IPC_STAT, &qs_buf) == -1) {
103 tst_brkm(TBROK, cleanup, "Could not "
104 "get queue status");
105 }
106
107 if (qs_buf.msg_cbytes != MSGSIZE) {
108 tst_resm(TFAIL, "queue bytes != MSGSIZE");
109 }
110
111 if (qs_buf.msg_qnum != 1) {
112 tst_resm(TFAIL, "queue message != 1");
113 }
114
115 tst_resm(TPASS, "queue bytes = MSGSIZE and "
116 "queue messages = 1");
117
118 /*
119 * remove the message by reading from the queue
120 */
121 if (msgrcv(msg_q_1, &rd_buf, MSGSIZE, 1, 0) == -1) {
122 tst_brkm(TBROK, cleanup, "Could not read from queue");
123 }
124 }
125
126 cleanup();
127 tst_exit();
128 }
129
130 /*
131 * setup() - performs all the ONE TIME setup for this test.
132 */
setup(void)133 void setup(void)
134 {
135
136 tst_sig(NOFORK, DEF_HANDLER, cleanup);
137
138 TEST_PAUSE;
139
140 /*
141 * Create a temporary directory and cd into it.
142 * This helps to ensure that a unique msgkey is created.
143 * See ../lib/libipc.c for more information.
144 */
145 tst_tmpdir();
146
147 msgkey = getipckey();
148
149 /* create a message queue with read/write permissions */
150 if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1) {
151 tst_brkm(TBROK, cleanup, "Can't create message queue");
152 }
153
154 /* initialize the message buffer */
155 init_buf(&msg_buf, MSGTYPE, MSGSIZE);
156 }
157
158 /*
159 * cleanup() - performs all the ONE TIME cleanup for this test at completion
160 * or premature exit.
161 */
cleanup(void)162 void cleanup(void)
163 {
164 /* if it exists, remove the message queue if it exists */
165 rm_queue(msg_q_1);
166
167 tst_rmdir();
168
169 }
170