Imported Upstream version 20080930
[ltp-debian.git] / testcases / kernel / ipc / ipc_stress / message_queue_test_01.c
blobbeaa61864b99e7e0e074c8588aae73a585f8c578
1 /*
2 * Copyright (C) Bull S.A. 1996
3 * Copyright (c) International Business Machines Corp., 2001
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /*---------------------------------------------------------------------+
20 | message_queue_test_01 |
21 | ==================================================================== |
22 | |
23 | Description: Create a message queue to send messages between two |
24 | processes. |
25 | |
26 | Algorithm: o Parent |
27 | - Create a pipe |
28 | - Spawn a child process |
29 | - Create unique message queue identifier and send |
30 | it to child process via pipe |
31 | |
32 | o Child |
33 | - Wait for message queue identifier from parent |
34 | - Send data to parent via message queue and exit |
35 | |
36 | o Parent |
37 | - Receive message from child process |
38 | - Remove message queue |
39 | - Wait for child process to exit |
40 | |
41 | System calls: The following system calls are made |
42 | |
43 | msgget() - Gets a message queue identifier |
44 | msgrcv() - Reads a message from a queue |
45 | msgctl() - Provides message control operations |
46 | |
47 | Usage: message_queue_test_01 |
48 | |
49 | To compile: cc -o message_queue_test_01 message_queue_test_01. |
50 | |
51 | Last update: Ver. 1.2, 2/26/94 14:03:30 |
52 | |
53 | Change Activity |
54 | |
55 | Version Date Name Reason |
56 | 0.1 050689 CTU Initial version |
57 | 1.2 111993 DJK Modify for AIX version 4.1 |
58 | 1.3 022693 DJK Move to Prod directory |
59 | |
60 +---------------------------------------------------------------------*/
63 #include <errno.h>
64 #include <signal.h>
65 #include <stdio.h>
66 #include <unistd.h>
67 #include <sys/ipc.h>
68 #ifdef _LINUX_
69 // defines struct msgbuf
70 #define __USE_GNU
71 #endif
72 #include <sys/msg.h>
73 #include <sys/types.h>
74 #include <string.h>
75 #include <stdlib.h>
77 * Defines
79 * BUF_SIZE: size of message buffer...
82 #define key_tt int
83 #define FIRST_MSG 0
84 #define BUF_SIZE 256
86 #define SAFE_FREE(p) { if(p) { free(p); (p)=NULL; } }
89 * Function prototypes
91 * sys_error (): System error message function
92 * error (): Error message function
94 static void sys_error (const char *, int);
95 static void error (const char *, int);
96 static void child (int []);
97 enum { READ, WRITE };
100 /*---------------------------------------------------------------------+
101 | main |
102 | ==================================================================== |
104 | Function: Main program (see prolog for more details) |
106 | Returns: (0) Successful completion |
107 | (-1) Error occurred |
109 +---------------------------------------------------------------------*/
110 int main (int argc, char **argv)
112 key_tt msqid; /* message queue id */
113 struct msgbuf *buf;
114 pid_t pid;
115 int mode = 0666;
116 int fd [2];
119 * Print out program header
121 printf ("%s: IPC Message Queue TestSuite program\n", *argv);
122 fflush (stdout);
123 pipe (fd);
125 if ((pid = fork()) == 0) {
126 child (fd);
127 exit (0);
128 } else if (pid < (pid_t)0)
129 sys_error ("fork failed", __LINE__);
132 * Create a NEW unique message queue identifier.
134 if ((msqid = msgget (IPC_PRIVATE, mode|IPC_CREAT|IPC_EXCL)) < 0)
135 sys_error ("msgget failed", __LINE__);
136 printf ("\n\tCreate message queue, id: 0x%8.8x\n", msqid);
137 fflush (stdout);
140 * Send the newly created message queue identifier to the child
141 * process via pipes. Close pipes after sending identifier.
143 close (fd [READ]);
144 if (write (fd [WRITE], &msqid, sizeof (key_tt)) < 0)
145 sys_error ("write failed", __LINE__);
146 close (fd [WRITE]);
149 * Read the data from the message queue
151 buf = (struct msgbuf *)calloc ((size_t)(sizeof(struct msgbuf) + BUF_SIZE),
152 sizeof (char));
153 if(!buf)
154 sys_error ("calloc failed", __LINE__);
156 if (msgrcv (msqid, (void *)buf, (size_t)BUF_SIZE, FIRST_MSG, 0) < 0) {
157 SAFE_FREE(buf);
158 sys_error ("msgsnd failed", __LINE__);
160 printf ("\n\tParent: received message: %s\n", buf->mtext);
161 fflush (stdout);
162 SAFE_FREE(buf);
165 * Remove the message queue from the system
167 printf ("\n\tRemove the message queue\n");
168 fflush (stdout);
169 if (msgctl (msqid, IPC_RMID, 0) < 0)
170 sys_error ("msgctl (IPC_RMID) failed", __LINE__);
172 printf ("\nsuccessful!\n");
173 fflush (stdout);
174 return (0);
178 /*---------------------------------------------------------------------+
179 | child |
180 | ==================================================================== |
182 | Function: ... |
184 +---------------------------------------------------------------------*/
185 static void child (int fd[])
187 key_tt msqid; /* message queue id */
188 size_t nbytes;
189 struct msgbuf *buf;
192 * Read the message queue identifier from the parent through
193 * the pipe. Close pipe after reading identifier.
195 close (fd [WRITE]);
196 if (read (fd [READ], &msqid, sizeof (key_tt)) < 0)
197 sys_error ("read failed", __LINE__);
198 close (fd [READ]);
199 printf ("\n\tChild: received message queue id: %d\n", msqid);
200 fflush (stdout);
203 * Put data on the message queue
205 buf = (struct msgbuf *)calloc ((size_t)(sizeof(struct msgbuf) + BUF_SIZE),
206 sizeof (char));
207 if(!buf)
208 sys_error ("calloc failed", __LINE__);
210 buf->mtype = 1;
211 sprintf (buf->mtext, "\"message queue transmission test....\"");
212 nbytes = strlen (buf->mtext) + 1;
214 printf ("\n\tChild: sending message: %s\n", buf->mtext);
215 fflush (stdout);
216 if (msgsnd (msqid, buf, nbytes, 0) < 0) {
217 SAFE_FREE(buf);
218 sys_error ("msgsnd failed", __LINE__);
220 SAFE_FREE(buf);
224 /*---------------------------------------------------------------------+
225 | sys_error () |
226 | ==================================================================== |
228 | Function: Creates system error message and calls error () |
230 +---------------------------------------------------------------------*/
231 static void sys_error (const char *msg, int line)
233 char syserr_msg [256];
235 sprintf (syserr_msg, "%s: %s\n", msg, strerror (errno));
236 error (syserr_msg, line);
240 /*---------------------------------------------------------------------+
241 | error () |
242 | ==================================================================== |
244 | Function: Prints out message and exits... |
246 +---------------------------------------------------------------------*/
247 static void error (const char *msg, int line)
249 fprintf (stderr, "ERROR [line: %d] %s\n", line, msg);
250 exit (-1);