• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (C) Bull S.A. 1996
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 |                       message_queue_test_05                          |
21 | ==================================================================== |
22 |                                                                      |
23 | Description:  Creates N message queues.  Creates three and deletes   |
24 |               one until N is reached.                                |
25 |                                                                      |
26 | Algorithm:    o  Loop until N message queues have been created       |
27 |                  - Create three message queues                       |
28 |                  - Delete one message queue                          |
29 |                                                                      |
30 |               o  Delete all of the message queues                    |
31 |                                                                      |
32 | System calls: The following system calls are made                    |
33 |                                                                      |
34 |               o  msgctl () - provides message control operations     |
35 |               o  msgget () - gets a message queue identifier         |
36 |                                                                      |
37 | Usage:        message_queue_test_05 [-n num_queues] [-d]             |
38 |                                                                      |
39 |               where: [-n] number of message queues to create         |
40 |                      [-d] debug option                               |
41 |                                                                      |
42 | To compile:   cc -o message_queue_test_05 message_queue_test_05.     |
43 |                                                                      |
44 | Last update:   Ver. 1.2, 2/26/94 14:10:17                           |
45 |                                                                      |
46 | Change Activity                                                      |
47 |                                                                      |
48 |   Version  Date    Name  Reason                                      |
49 |    0.1     032789  CTU   Initial version                             |
50 |    1.2     111993  DJK   Modify for AIX version 4.1                  |
51 |    1.3     022694  DJK   Moved to Prod directory                     |
52 |                                                                      |
53 +---------------------------------------------------------------------*/
54 
55 #include <errno.h>
56 #include <fcntl.h>
57 #include <signal.h>
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <unistd.h>
62 #include <sys/ipc.h>
63 #ifdef _LINUX_
64 // defines struct msgbuf
65 #define __USE_GNU
66 #endif
67 #include <sys/msg.h>
68 #include <sys/types.h>
69 
70 /*
71  * Defines
72  *
73  * MAX_MESSAGE_QUEUES: maximum number of message queues to create
74  *
75  * DEFAULT_MESSAGE_QUEUES: default number of message queues to create
76  * unless specified with [-n] command line option
77  *
78  * USAGE: usage statement macro
79  */
80 
81 #ifdef _LINUX_
82 #define	MAX_MESSAGE_QUEUES 128
83 #define	DEFAULT_MESSAGE_QUEUES 10
84 #else
85 #define	MAX_MESSAGE_QUEUES 4096
86 #define	DEFAULT_MESSAGE_QUEUES 1000
87 #endif
88 
89 #define USAGE	"\nUsage: %s [-n num_message_queues] [-d]\n\n"
90 
91 /*
92  * Function prototypes
93  *
94  * parse_args (): Parse command line arguments
95  * sys_error (): System error message function
96  * error (): Error message function
97  * cleanup (): Cleanup function for the test
98  */
99 static void parse_args(int, char **);
100 static void sys_error(const char *, int);
101 static void error(const char *, int);
102 static void cleanup(int qnum);
103 /*
104  * Global variables
105  *
106  * max_queues: maximum number of message queues allowed (system limit)
107  * msqid_array: array containing the unique message queue identifiers
108  * debug: debugging flag, set with [-d] command line option
109  */
110 int max_queues = DEFAULT_MESSAGE_QUEUES;
111 int msqid_array[MAX_MESSAGE_QUEUES];
112 int debug = 0;
113 
114 /*---------------------------------------------------------------------+
115 |                               main                                   |
116 | ==================================================================== |
117 |                                                                      |
118 | Function:  Main program  (see prolog for more details)               |
119 |                                                                      |
120 | Returns:   (0)  Successful completion                                |
121 |            (-1) Error occurred                                       |
122 |                                                                      |
123 +---------------------------------------------------------------------*/
main(int argc,char ** argv)124 int main(int argc, char **argv)
125 {
126 	int nqueues = 0;	/* Current number of message queues */
127 	int i;			/* Loop index */
128 	int mode = 0777;	/* Misc mode bits */
129 
130 	/*
131 	 * Parse command line arguments and print out program header
132 	 */
133 	parse_args(argc, argv);
134 	printf("%s: IPC Message Queue TestSuite program\n", *argv);
135 
136 	printf("\n\tCreating %d message queues ...\n", max_queues);
137 	while (nqueues < max_queues) {
138 
139 		for (i = 0; i < 3; i++) {
140 			if (debug)
141 				printf("\tcreating queue [%d]\n", nqueues);
142 			if ((msqid_array[nqueues++]
143 			     = msgget(IPC_PRIVATE, IPC_CREAT | mode)) < 0) {
144 				cleanup(nqueues);
145 				sys_error("msgget failed", __LINE__);
146 			}
147 
148 			if (nqueues > MAX_MESSAGE_QUEUES)
149 				break;
150 		}
151 
152 		/*
153 		 * Delete the last message queue...
154 		 */
155 		if (msgctl(msqid_array[--nqueues], IPC_RMID, 0) < 0)
156 			sys_error("msgctl (IPC_RMID) failed", __LINE__);
157 		if (debug)
158 			printf("\tremoved queue  [%d]\n", nqueues);
159 	}
160 	printf("\n\tAll message queues created successfully\n");
161 
162 	cleanup(nqueues);
163 	printf("\nsuccessful!\n");
164 	return (0);
165 }
166 
167 /*---------------------------------------------------------------------+
168 |                             parse_args ()                            |
169 | ==================================================================== |
170 |                                                                      |
171 | Function:  Parse the command line arguments & initialize global      |
172 |            variables.                                                |
173 |                                                                      |
174 | Updates:   (command line options)                                    |
175 |                                                                      |
176 |            [-n] num:   number of message queues to create            |
177 |                                                                      |
178 +---------------------------------------------------------------------*/
parse_args(int argc,char ** argv)179 static void parse_args(int argc, char **argv)
180 {
181 	int opt;
182 	int errflag = 0;
183 	char *program_name = *argv;
184 	extern char *optarg;	/* Command line option */
185 
186 	/*
187 	 * Parse command line options.
188 	 */
189 	while ((opt = getopt(argc, argv, "n:d")) != EOF) {
190 		switch (opt) {
191 		case 'n':	/* number of queues to create */
192 			max_queues = atoi(optarg);
193 			break;
194 		case 'd':	/* debug */
195 			debug++;
196 			break;
197 		default:
198 			errflag++;
199 			break;
200 		}
201 	}
202 	if (max_queues > MAX_MESSAGE_QUEUES)
203 		errflag++;
204 
205 	if (errflag) {
206 		fprintf(stderr, USAGE, program_name);
207 		exit(2);
208 	}
209 }
210 
211 /*---------------------------------------------------------------------+
212 |                             sys_error ()                             |
213 | ==================================================================== |
214 |                                                                      |
215 | Function:  Creates system error message and calls error ()           |
216 |                                                                      |
217 +---------------------------------------------------------------------*/
sys_error(const char * msg,int line)218 static void sys_error(const char *msg, int line)
219 {
220 	char syserr_msg[256];
221 
222 	sprintf(syserr_msg, "%s: %s\n", msg, strerror(errno));
223 	error(syserr_msg, line);
224 }
225 
226 /*---------------------------------------------------------------------+
227 |                               error ()                               |
228 | ==================================================================== |
229 |                                                                      |
230 | Function:  Prints out message and exits...                           |
231 |                                                                      |
232 +---------------------------------------------------------------------*/
error(const char * msg,int line)233 static void error(const char *msg, int line)
234 {
235 	fprintf(stderr, "ERROR [line: %d] %s\n", line, msg);
236 	exit(-1);
237 }
238 
239 /*---------------------------------------------------------------------+
240 |                              cleanup()                               |
241 | ==================================================================== |
242 | cleanup() - performs all message queues cleanup for this test at     |
243 |             completion or premature exit.                            |
244 |             Remove the temporary message queues created.             |
245 |                                                                      |
246 +---------------------------------------------------------------------*/
cleanup(int qnum)247 void cleanup(int qnum)
248 {
249 	/*
250 	 *  Remove the allocated message queues.
251 	 */
252 	while (qnum > 0) {
253 		if (msqid_array[--qnum] < 0)
254 			continue;
255 		if (msgctl(msqid_array[qnum], IPC_RMID, 0) < 0)
256 			sys_error("msgctl (IPC_RMID) failed", __LINE__);
257 		if (debug)
258 			printf("\tremoved queue  [%d]\n", qnum);
259 	}
260 }
261