1/* 2* Copyright (c) 2004, Bull S.A.. All rights reserved. 3* Created by: Sebastien Decugis 4 5* This program is free software; you can redistribute it and/or modify it 6* under the terms of version 2 of the GNU General Public License as 7* published by the Free Software Foundation. 8* 9* This program is distributed in the hope that it would be useful, but 10* WITHOUT ANY WARRANTY; without even the implied warranty of 11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12* 13* You should have received a copy of the GNU General Public License along 14* with this program; if not, write the Free Software Foundation, Inc., 59 15* Temple Place - Suite 330, Boston MA 02111-1307, USA. 16 17 18* This sample test aims to check the following assertion: 19* 20* The opened message queue descriptors are copied to the child process and 21* refer to the same object. 22 23* The steps are: 24* -> Open a message queue descriptor. 25* -> Send a message to this descriptor. 26* -> fork 27* -> check if that the child's message count for this descriptor is 1. 28 29* The test fails if the child reports 0 message count 30* or if it fails to read the descriptor. 31 32*/ 33 34 35/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 36#define _POSIX_C_SOURCE 200112L 37 38/********************************************************************************************/ 39/****************************** standard includes *****************************************/ 40/********************************************************************************************/ 41#include <pthread.h> 42 #include <stdarg.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <unistd.h> 47 48#include <sys/wait.h> 49 #include <errno.h> 50 51#include <mqueue.h> 52#include <sys/stat.h> 53 54/********************************************************************************************/ 55/****************************** Test framework *****************************************/ 56/********************************************************************************************/ 57#include "testfrmw.h" 58 #include "testfrmw.c" 59/* This header is responsible for defining the following macros: 60 * UNRESOLVED(ret, descr); 61 * where descr is a description of the error and ret is an int (error code for example) 62 * FAILED(descr); 63 * where descr is a short text saying why the test has failed. 64 * PASSED(); 65 * No parameter. 66 * 67 * Both three macros shall terminate the calling process. 68 * The testcase shall not terminate in any other maneer. 69 * 70 * The other file defines the functions 71 * void output_init() 72 * void output(char * string, ...) 73 * 74 * Those may be used to output information. 75 */ 76 77/********************************************************************************************/ 78/********************************** Configuration ******************************************/ 79/********************************************************************************************/ 80#ifndef VERBOSE 81#define VERBOSE 1 82#endif 83 84/********************************************************************************************/ 85/*********************************** Test case *****************************************/ 86/********************************************************************************************/ 87 88/* The main test function. */ 89int main( int argc, char * argv[] ) 90{ 91 int ret, status; 92 pid_t child, ctl; 93 94 mqd_t mq; 95 char rcv[ 20 ]; 96 97 struct mq_attr mqa; 98 99 100 /* Initialize output */ 101 output_init(); 102 103 /* Create a message queue descriptor */ 104 mqa.mq_maxmsg = 2; 105 mqa.mq_msgsize = 20; 106 107 mq = mq_open( "/fork_19_1_mq" 108 , O_RDWR | O_CREAT | O_NONBLOCK 109 , S_IRUSR | S_IWUSR 110 , &mqa ); 111 112 if ( mq == ( mqd_t ) - 1 ) 113 { 114 UNRESOLVED( errno, "Failed to create the message queue descriptor" ); 115 } 116 117 /* Send 1 message to this message queue */ 118 ret = mq_send( mq, "I'm your father...", 19, 0 ); 119 120 if ( ret != 0 ) 121 { 122 UNRESOLVED( errno, "Failed to send the message" ); 123 } 124 125 /* Check the message has been queued */ 126 ret = mq_getattr( mq, &mqa ); 127 128 if ( ret != 0 ) 129 { 130 UNRESOLVED( errno, "Failed to get message queue attributes" ); 131 } 132 133 if ( mqa.mq_curmsgs != 1 ) 134 { 135 UNRESOLVED( -1, "The queue information does not show the new message" ); 136 } 137 138 139 /* Create the child */ 140 child = fork(); 141 142 if ( child == ( pid_t ) - 1 ) 143 { 144 UNRESOLVED( errno, "Failed to fork" ); 145 } 146 147 /* child */ 148 if ( child == ( pid_t ) 0 ) 149 { 150 ret = mq_getattr( mq, &mqa ); 151 152 if ( ret != 0 ) 153 { 154 FAILED( "Failed to get message queue attributes in child" ); 155 } 156 157 if ( mqa.mq_curmsgs != 1 ) 158 { 159 FAILED( "The queue information does not show the message in child" ); 160 } 161 162 /* Now, receive the message */ 163 ret = mq_receive( mq, rcv, 20, NULL ); 164 165 if ( ret != 19 ) /* expected message size */ 166 { 167 UNRESOLVED( errno, "Failed to receive the message" ); 168 } 169 170#if VERBOSE > 0 171 output( "Received message: %s\n", rcv ); 172 173#endif 174 175 /* We're done */ 176 exit( PTS_PASS ); 177 } 178 179 /* Parent joins the child */ 180 ctl = waitpid( child, &status, 0 ); 181 182 if ( ctl != child ) 183 { 184 UNRESOLVED( errno, "Waitpid returned the wrong PID" ); 185 } 186 187 if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) ) 188 { 189 FAILED( "Child exited abnormally" ); 190 } 191 192 /* Check the message has been unqueued */ 193 ret = mq_getattr( mq, &mqa ); 194 195 if ( ret != 0 ) 196 { 197 UNRESOLVED( errno, "Failed to get message queue attributes the 2nd time" ); 198 } 199 200 if ( mqa.mq_curmsgs != 0 ) 201 { 202 FAILED( "The message received in child was not dequeued." ); 203 } 204 205 /* Test passed */ 206#if VERBOSE > 0 207 output( "Test passed\n" ); 208 209#endif 210 PASSED; 211} 212 213