Home | History | Annotate | Download | only in mq_open
      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 first letter of name is "/", any other processes
     11  * calling the message queue with that name will refer to the same
     12  * message queue object.
     13  *
     14  * Test by creating a message queue and placing a message within it.  Then,
     15  * in another process open the first message queue and ensure the message
     16  * can be received.
     17  *
     18  * 3/13/03 - Added fix from Gregoire Pichon for specifying an attr
     19  *           with a mq_maxmsg >= BUFFER.
     20  */
     21 
     22 #include <sys/stat.h>
     23 #include <sys/types.h>
     24 #include <sys/wait.h>
     25 #include <fcntl.h>
     26 #include <mqueue.h>
     27 #include <signal.h>
     28 #include <stdio.h>
     29 #include <string.h>
     30 #include <unistd.h>
     31 #include "posixtest.h"
     32 
     33 #define NAMESIZE 50
     34 #define MSGSTR "0123456789"
     35 #define BUFFER 40
     36 
     37 #define CHILDPASS 1
     38 #define CHILDFAIL 0
     39 
     40 void handler(int signo)
     41 {
     42 	(void) signo;
     43 	return;
     44 }
     45 
     46 int main(void)
     47 {
     48 	char qname[NAMESIZE];
     49 	const char *msgptr = MSGSTR;
     50 	int pid, ret;
     51 
     52 	sprintf(qname, "/mq_open_2-1_%d", getpid());
     53 
     54 	pid = fork();
     55 	if (pid == 0) {
     56 		mqd_t childqueue;
     57 		char msgrcd[BUFFER];
     58 		sigset_t mask;
     59 		struct mq_attr attr;
     60 		struct sigaction act;
     61 		int sig;
     62 		unsigned pri;
     63 
     64 		/* child here */
     65 
     66 		/* Set up handler for SIGUSR1 */
     67 		act.sa_handler = handler;
     68 		act.sa_flags = 0;
     69 		sigaction(SIGUSR1, &act, NULL);
     70 
     71 		/* wait for parent to finish mq_open */
     72 		sigemptyset(&mask);
     73 		sigaddset(&mask, SIGUSR1);
     74 		sigprocmask(SIG_BLOCK, &mask, NULL);
     75 		sigwait(&mask, &sig);
     76 
     77 		/* now that parent has finished, open qname */
     78 		attr.mq_msgsize = BUFFER;
     79 		attr.mq_maxmsg = BUFFER;
     80 		childqueue = mq_open(qname, O_RDWR, S_IRUSR | S_IWUSR, &attr);
     81 		if (childqueue == (mqd_t) - 1) {
     82 			perror("mq_open() did not return success in child");
     83 			return CHILDFAIL;
     84 		}
     85 
     86 		ret = mq_receive(childqueue, msgrcd, BUFFER, &pri);
     87 		if (ret == -1) {
     88 			perror("mq_receive() returned failure in child");
     89 			return CHILDFAIL;
     90 		}
     91 
     92 		if (strcmp(msgptr, msgrcd) != 0) {
     93 			printf("FAIL:  sent %s received %s\n", msgptr, msgrcd);
     94 			return CHILDFAIL;
     95 		}
     96 #ifdef DEBUG
     97 		printf("Received message %s\n", msgrcd);
     98 #endif
     99 		return CHILDPASS;
    100 	} else {
    101 		/* parent here */
    102 		mqd_t queue;
    103 		int i;
    104 		struct mq_attr attr;
    105 
    106 		attr.mq_msgsize = BUFFER;
    107 		attr.mq_maxmsg = BUFFER;
    108 		queue = mq_open(qname, O_CREAT | O_RDWR,
    109 				S_IRUSR | S_IWUSR, &attr);
    110 		if (queue == (mqd_t) - 1) {
    111 			perror("mq_open() did not return success");
    112 			printf("Test UNRESOLVED\n");
    113 			/* stop child and exit */
    114 			kill(pid, SIGABRT);
    115 			return PTS_UNRESOLVED;
    116 		}
    117 
    118 		if (mq_send(queue, msgptr, strlen(msgptr) + 1, 1) != 0) {
    119 			perror("mq_send() did not return success");
    120 			printf("Test UNRESOLVED\n");
    121 			/* close queue, stop child and exit */
    122 			mq_close(queue);
    123 			mq_unlink(qname);
    124 			kill(pid, SIGABRT);
    125 			return PTS_UNRESOLVED;
    126 		}
    127 
    128 		sleep(1);
    129 		kill(pid, SIGUSR1);
    130 
    131 		if (wait(&i) == -1) {
    132 			perror("Error waiting for child to exit");
    133 			/* close queue and exit */
    134 			printf("Test UNRESOLVED\n");
    135 			mq_close(queue);
    136 			mq_unlink(qname);
    137 			return PTS_UNRESOLVED;
    138 		}
    139 
    140 		mq_close(queue);
    141 		mq_unlink(qname);
    142 
    143 		if (!WIFEXITED(i) || !WEXITSTATUS(i)) {
    144 			printf("Test FAILED\n");
    145 			return PTS_FAIL;
    146 		}
    147 
    148 		printf("Test PASSED\n");
    149 		return PTS_PASS;
    150 	}
    151 
    152 	return PTS_UNRESOLVED;
    153 }
    154