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