1/* 2 * Copyright (c) 2003, Intel Corporation. All rights reserved. 3 * Created by: julie.n.fleischer REMOVE-THIS AT intel DOT com 4 * This file is licensed under the GPL license. For the full content 5 * of this license, see the COPYING file at the top level of this 6 * source tree. 7 */ 8 9/* 10 * Test that if the access mode is O_RDWR, the message queue can 11 * send and receive messages. 12 * 13 * Test for a message queue opened twice in two different processes. 14 * 15 * 3/13/03 - Added fix from Gregoire Pichon for specifying an attr 16 * with a mq_maxmsg >= BUFFER. 17 */ 18 19#include <stdio.h> 20#include <mqueue.h> 21#include <fcntl.h> 22#include <sys/stat.h> 23#include <sys/types.h> 24#include <unistd.h> 25#include <string.h> 26#include <sys/wait.h> 27#include "posixtest.h" 28 29#define NAMESIZE 50 30#define MSGSTR "0123456789" 31#define BUFFER 40 32 33#define CHILDPASS 1 34#define CHILDFAIL 0 35 36void handler(int signo) 37{ 38 return; 39} 40 41int main() 42{ 43 char qname[NAMESIZE]; 44 const char *msgptr = MSGSTR; 45 int pid; 46 47 sprintf(qname, "/mq_open_9-2_%d", getpid()); 48 49 if ((pid = fork()) == 0) { 50 mqd_t rdwrqueuechild; 51 sigset_t mask; 52 struct mq_attr attr; 53 struct sigaction act; 54 char msgrcd[BUFFER]; 55 int sig; 56 unsigned pri; 57 58 /* child here */ 59 60 /* Set up handler for SIGUSR1 */ 61 act.sa_handler = handler; 62 act.sa_flags = 0; 63 sigaction(SIGUSR1, &act, NULL); 64 65 /* wait for parent to finish with first queue */ 66 sigemptyset(&mask); 67 sigaddset(&mask, SIGUSR1); 68 sigprocmask(SIG_BLOCK,&mask,NULL); 69 sigwait(&mask, &sig); 70 71 /* once parent has finished, open next queue */ 72 attr.mq_msgsize = BUFFER; 73 attr.mq_maxmsg = BUFFER; 74 rdwrqueuechild = mq_open(qname, O_RDWR, 75 S_IRUSR | S_IWUSR, &attr); 76 if (rdwrqueuechild == (mqd_t)-1) { 77 perror("mq_open() read only failed"); 78 return CHILDFAIL; 79 } 80#ifdef DEBUG 81 printf("read-write message queue opened in child\n"); 82#endif 83 84 if (mq_send(rdwrqueuechild, msgptr, strlen(msgptr)+1, 1) == -1) { 85 perror("mq_send() did not return success"); 86 mq_close(rdwrqueuechild); 87 return CHILDFAIL; 88 } 89#ifdef DEBUG 90 printf("Message %s sent in child\n", msgptr); 91#endif 92 93 if (mq_receive(rdwrqueuechild, msgrcd, BUFFER, &pri) == -1) { 94 perror("mq_receive() did not return success"); 95 mq_close(rdwrqueuechild); 96 return CHILDFAIL; 97 } 98#ifdef DEBUG 99 printf("Message %s received in child\n", msgrcd); 100#endif 101 102 mq_close(rdwrqueuechild); 103 104 return CHILDPASS; 105 } else { 106 /* parent here */ 107 mqd_t rdwrqueue; 108 char msgrcd[BUFFER]; 109 struct mq_attr attr; 110 int i; 111 unsigned pri; 112 113 attr.mq_msgsize = BUFFER; 114 attr.mq_maxmsg = BUFFER; 115 rdwrqueue = mq_open(qname, O_CREAT |O_RDWR, 116 S_IRUSR | S_IWUSR, &attr); 117 if (rdwrqueue == (mqd_t)-1) { 118 perror("mq_open() did not return success"); 119 printf("Test UNRESOLVED\n"); 120 /* kill child and exit */ 121 kill(pid, SIGABRT); 122 return PTS_UNRESOLVED; 123 } 124#ifdef DEBUG 125 printf("read-write message queue opened in parent\n"); 126#endif 127 128 if (mq_send(rdwrqueue, msgptr, strlen(msgptr), 1) == -1) { 129 perror("mq_send() did not return success"); 130 printf("Test FAILED\n"); 131 /* close queue, kill child and exit */ 132 mq_close(rdwrqueue); 133 mq_unlink(qname); 134 kill(pid, SIGABRT); 135 return PTS_FAIL; 136 } 137#ifdef DEBUG 138 printf("Message %s sent\n", msgptr); 139#endif 140 141 if (mq_receive(rdwrqueue, msgrcd, BUFFER, &pri) == -1) { 142 perror("mq_receive() did not return success"); 143 printf("Test FAILED\n"); 144 /* close queue, kill child and exit */ 145 mq_close(rdwrqueue); 146 mq_unlink(qname); 147 kill(pid, SIGABRT); 148 return PTS_FAIL; 149 } 150#ifdef DEBUG 151 printf("Message %s received\n", msgrcd); 152#endif 153 154 sleep(1); 155 kill(pid, SIGUSR1); //tell child mq_open and mq_send finished 156 157 if (wait(&i) == -1) { 158 perror("Error waiting for child to exit"); 159 printf("Test UNRESOLVED\n"); 160 /* close queue and exit */ 161 mq_close(rdwrqueue); 162 mq_unlink(qname); 163 return PTS_UNRESOLVED; 164 } 165#ifdef DEBUG 166 printf("Child finished\n"); 167#endif 168 169 mq_close(rdwrqueue); 170 mq_unlink(qname); 171 172 if (!WIFEXITED(i) || !WEXITSTATUS(i)) { 173 printf("Test FAILED\n"); 174 return PTS_FAIL; 175 } 176 177 printf("Test PASSED\n"); 178 return PTS_PASS; 179 } 180 181 return PTS_UNRESOLVED; 182} 183 184