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 | ==================================================================== |
23 | Description: Create a message queue to send messages between two |
26 | Algorithm: o Parent |
28 | - Spawn a child process |
29 | - Create unique message queue identifier and send |
30 | it to child process via pipe |
33 | - Wait for message queue identifier from parent |
34 | - Send data to parent via message queue and exit |
37 | - Receive message from child process |
38 | - Remove message queue |
39 | - Wait for child process to exit |
41 | System calls: The following system calls are made |
43 | msgget() - Gets a message queue identifier |
44 | msgrcv() - Reads a message from a queue |
45 | msgctl() - Provides message control operations |
47 | Usage: message_queue_test_01 |
49 | To compile: cc -o message_queue_test_01 message_queue_test_01. |
51 | Last update: Ver. 1.2, 2/26/94 14:03:30 |
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 |
60 +---------------------------------------------------------------------*/
69 // defines struct msgbuf
73 #include <sys/types.h>
79 * BUF_SIZE: size of message buffer...
86 #define SAFE_FREE(p) { if(p) { free(p); (p)=NULL; } }
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 []);
100 /*---------------------------------------------------------------------+
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 */
119 * Print out program header
121 printf ("%s: IPC Message Queue TestSuite program\n", *argv
);
125 if ((pid
= fork()) == 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
);
140 * Send the newly created message queue identifier to the child
141 * process via pipes. Close pipes after sending identifier.
144 if (write (fd
[WRITE
], &msqid
, sizeof (key_tt
)) < 0)
145 sys_error ("write failed", __LINE__
);
149 * Read the data from the message queue
151 buf
= (struct msgbuf
*)calloc ((size_t)(sizeof(struct msgbuf
) + BUF_SIZE
),
154 sys_error ("calloc failed", __LINE__
);
156 if (msgrcv (msqid
, (void *)buf
, (size_t)BUF_SIZE
, FIRST_MSG
, 0) < 0) {
158 sys_error ("msgsnd failed", __LINE__
);
160 printf ("\n\tParent: received message: %s\n", buf
->mtext
);
165 * Remove the message queue from the system
167 printf ("\n\tRemove the message queue\n");
169 if (msgctl (msqid
, IPC_RMID
, 0) < 0)
170 sys_error ("msgctl (IPC_RMID) failed", __LINE__
);
172 printf ("\nsuccessful!\n");
178 /*---------------------------------------------------------------------+
180 | ==================================================================== |
184 +---------------------------------------------------------------------*/
185 static void child (int fd
[])
187 key_tt msqid
; /* message queue id */
192 * Read the message queue identifier from the parent through
193 * the pipe. Close pipe after reading identifier.
196 if (read (fd
[READ
], &msqid
, sizeof (key_tt
)) < 0)
197 sys_error ("read failed", __LINE__
);
199 printf ("\n\tChild: received message queue id: %d\n", msqid
);
203 * Put data on the message queue
205 buf
= (struct msgbuf
*)calloc ((size_t)(sizeof(struct msgbuf
) + BUF_SIZE
),
208 sys_error ("calloc failed", __LINE__
);
211 sprintf (buf
->mtext
, "\"message queue transmission test....\"");
212 nbytes
= strlen (buf
->mtext
) + 1;
214 printf ("\n\tChild: sending message: %s\n", buf
->mtext
);
216 if (msgsnd (msqid
, buf
, nbytes
, 0) < 0) {
218 sys_error ("msgsnd failed", __LINE__
);
224 /*---------------------------------------------------------------------+
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 /*---------------------------------------------------------------------+
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
);