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 *	msgctl02.c
23 *
24 * DESCRIPTION
25 *	msgctl02 - create a message queue, then issue the IPC_SET command
26 *		   to lower the msg_qbytes value.
27 *
28 * ALGORITHM
29 *	create a message queue
30 *	loop if that option was specified
31 *	call msgctl() with the IPC_SET command with a new msg_qbytes value
32 *	check the return code
33 *	  if failure, issue a FAIL message and break remaining tests
34 *	otherwise,
35 *	  if doing functionality testing
36 *	  	if the msg_qbytes value is the new value
37 *			issue a PASS message
38 *		otherwise
39 *			issue a FAIL message
40 *	  else issue a PASS message
41 *	call cleanup
42 *
43 * USAGE:  <for command-line>
44 *  msgctl02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
45 *     where,  -c n : Run n copies concurrently.
46 *             -f   : Turn off functionality Testing.
47 *	       -i n : Execute test n times.
48 *	       -I x : Execute test for x seconds.
49 *	       -P x : Pause for x seconds between iterations.
50 *	       -t   : Turn on syscall timing.
51 *
52 * HISTORY
53 *	03/2001 - Written by Wayne Boyer
54 *
55 * RESTRICTIONS
56 *	none
57 */
58
59#include "test.h"
60
61#include "ipcmsg.h"
62
63char *TCID = "msgctl02";
64int TST_TOTAL = 1;
65
66int msg_q_1 = -1;		/* to hold the message queue id */
67
68struct msqid_ds qs_buf;
69
70unsigned long int new_bytes;
71
72int main(int ac, char **av)
73{
74	int lc;
75
76	tst_parse_opts(ac, av, NULL, NULL);
77
78	setup();		/* global setup */
79
80	/* The following loop checks looping state if -i option given */
81
82	for (lc = 0; TEST_LOOPING(lc); lc++) {
83		/* reset tst_count in case we are looping */
84		tst_count = 0;
85
86		/*
87		 * Set the msqid_ds structure values for the queue
88		 */
89
90		TEST(msgctl(msg_q_1, IPC_SET, &qs_buf));
91
92		if (TEST_RETURN == -1) {
93			tst_resm(TFAIL | TTERRNO, "msgctl() call failed");
94		} else {
95			/* do a stat to get current queue values */
96			if ((msgctl(msg_q_1, IPC_STAT, &qs_buf) == -1)) {
97				tst_resm(TBROK, "stat on queue failed");
98				continue;
99			}
100
101			if (qs_buf.msg_qbytes == new_bytes) {
102				tst_resm(TPASS, "qs_buf.msg_qbytes is"
103					 " the new value - %ld",
104					 qs_buf.msg_qbytes);
105			} else {
106				tst_resm(TFAIL, "qs_buf.msg_qbytes "
107					 "value is not expected");
108				tst_resm(TINFO, "expected - %ld, "
109					 "received - %ld", new_bytes,
110					 qs_buf.msg_qbytes);
111			}
112		}
113
114		/*
115		 * decrement by one the msq_qbytes value
116		 */
117		qs_buf.msg_qbytes -= 1;
118		new_bytes = qs_buf.msg_qbytes;
119	}
120
121	cleanup();
122
123	tst_exit();
124}
125
126/*
127 * setup() - performs all the ONE TIME setup for this test.
128 */
129void setup(void)
130{
131
132	tst_sig(NOFORK, DEF_HANDLER, cleanup);
133
134	TEST_PAUSE;
135
136	/*
137	 * Create a temporary directory and cd into it.
138	 * This helps to ensure that a unique msgkey is created.
139	 * See ../lib/libipc.c for more information.
140	 */
141	tst_tmpdir();
142
143	/* get a message key */
144	msgkey = getipckey();
145
146	/* make sure the initial # of bytes is 0 in our buffer */
147	qs_buf.msg_qbytes = 0x3000;
148
149	/* now we have a key, so let's create a message queue */
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	/* now stat the queue to get the default msg_qbytes value */
155	if ((msgctl(msg_q_1, IPC_STAT, &qs_buf)) == -1) {
156		tst_brkm(TBROK, cleanup, "Can't stat the message queue");
157	}
158
159	/* decrement msg_qbytes and copy its value */
160	qs_buf.msg_qbytes -= 1;
161	new_bytes = qs_buf.msg_qbytes;
162}
163
164/*
165 * cleanup() - performs all the ONE TIME cleanup for this test at completion
166 * 	       or premature exit.
167 */
168void cleanup(void)
169{
170	/* if it exists, remove the message queue */
171	rm_queue(msg_q_1);
172
173	tst_rmdir();
174
175}
176