10dc076565f772bb1953209fb69ea150b494aaa40robbiew/*
20dc076565f772bb1953209fb69ea150b494aaa40robbiew * Copyright (c) 2003, Intel Corporation. All rights reserved.
30dc076565f772bb1953209fb69ea150b494aaa40robbiew * Created by:  julie.n.fleischer REMOVE-THIS AT intel DOT com
40dc076565f772bb1953209fb69ea150b494aaa40robbiew * This file is licensed under the GPL license.  For the full content
50dc076565f772bb1953209fb69ea150b494aaa40robbiew * of this license, see the COPYING file at the top level of this
60dc076565f772bb1953209fb69ea150b494aaa40robbiew * source tree.
70dc076565f772bb1953209fb69ea150b494aaa40robbiew */
80dc076565f772bb1953209fb69ea150b494aaa40robbiew
90dc076565f772bb1953209fb69ea150b494aaa40robbiew/*
100dc076565f772bb1953209fb69ea150b494aaa40robbiew * Test that tests to check if O_CREAT and O_EXCL are set that no other
110dc076565f772bb1953209fb69ea150b494aaa40robbiew * message queue exists are atomic.
120dc076565f772bb1953209fb69ea150b494aaa40robbiew *
130dc076565f772bb1953209fb69ea150b494aaa40robbiew * Test case will just attempt to call mq_open() with O_CREAT and O_EXCL
140dc076565f772bb1953209fb69ea150b494aaa40robbiew * using the same name in two different processes.  If one process fails,
150dc076565f772bb1953209fb69ea150b494aaa40robbiew * the test is considered a pass.
160dc076565f772bb1953209fb69ea150b494aaa40robbiew *
170dc076565f772bb1953209fb69ea150b494aaa40robbiew * This is a best attempt to test that these are atomic.  It does make the
180dc076565f772bb1953209fb69ea150b494aaa40robbiew * assumption (which could generally be untrue) that both mq_open() calls
190dc076565f772bb1953209fb69ea150b494aaa40robbiew * will attempt to be made at the same time.  For the sake of this test case,
200dc076565f772bb1953209fb69ea150b494aaa40robbiew * this is fine (will have some false positives, but no false negatives).
210dc076565f772bb1953209fb69ea150b494aaa40robbiew */
220dc076565f772bb1953209fb69ea150b494aaa40robbiew
23d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai#include <sys/mman.h>
240dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/stat.h>
250dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/types.h>
260dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/wait.h>
27d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai#include <errno.h>
2880886b520423c015b63cff03082e274147042243Garrett Cooper#include <fcntl.h>
2980886b520423c015b63cff03082e274147042243Garrett Cooper#include <mqueue.h>
3080886b520423c015b63cff03082e274147042243Garrett Cooper#include <signal.h>
3180886b520423c015b63cff03082e274147042243Garrett Cooper#include <stdio.h>
3280886b520423c015b63cff03082e274147042243Garrett Cooper#include <string.h>
3380886b520423c015b63cff03082e274147042243Garrett Cooper#include <unistd.h>
340dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "posixtest.h"
350dc076565f772bb1953209fb69ea150b494aaa40robbiew
360dc076565f772bb1953209fb69ea150b494aaa40robbiew#define NAMESIZE 50
37d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai#define TNAME "mq_open/16-1.c"
380dc076565f772bb1953209fb69ea150b494aaa40robbiew
394ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void)
400dc076565f772bb1953209fb69ea150b494aaa40robbiew{
41f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao	char qname[NAMESIZE];
42d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	char fname[NAMESIZE];
43f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao	int pid, succeeded = 0;
44d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	int fd;
45d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	void *pa = NULL;
460dc076565f772bb1953209fb69ea150b494aaa40robbiew	mqd_t childqueue, queue;
470dc076565f772bb1953209fb69ea150b494aaa40robbiew
480dc076565f772bb1953209fb69ea150b494aaa40robbiew	/*
490dc076565f772bb1953209fb69ea150b494aaa40robbiew	 * initialize both queues
500dc076565f772bb1953209fb69ea150b494aaa40robbiew	 */
51354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	childqueue = (mqd_t) - 1;
52354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	queue = (mqd_t) - 1;
530dc076565f772bb1953209fb69ea150b494aaa40robbiew
54f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao	sprintf(qname, "/mq_open_16-1_%d", getpid());
550dc076565f772bb1953209fb69ea150b494aaa40robbiew
56d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	sprintf(fname, "/tmp/pts_mq_open_16_1_%d", getpid());
57d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	unlink(fname);
58354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	fd = open(fname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
59d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	if (fd == -1) {
60d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai		printf(TNAME " Error at open(): %s\n", strerror(errno));
61064fe1a1dc44414f15056f1004c829df8a877285Cyril Hrubis		return PTS_UNRESOLVED;
62d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	}
63d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	/* file is empty now, will cause "Bus error" */
64d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	write(fd, fname, sizeof(int));
65d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	unlink(fname);
66d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai
67d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	pa = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
68d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	if (pa == MAP_FAILED) {
69d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai		printf(TNAME " Error at mmap: %s\n", strerror(errno));
70d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai		close(fd);
71064fe1a1dc44414f15056f1004c829df8a877285Cyril Hrubis		return PTS_FAIL;
72d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	}
73d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai	*(int *)pa = 0;
74d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai
75f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao	pid = fork();
76f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao	if (pid == 0) {
770dc076565f772bb1953209fb69ea150b494aaa40robbiew		sigset_t mask;
780dc076565f772bb1953209fb69ea150b494aaa40robbiew		int sig;
790dc076565f772bb1953209fb69ea150b494aaa40robbiew
800dc076565f772bb1953209fb69ea150b494aaa40robbiew		/* child here */
812c28215423293e443469a07ae7011135d058b671Garrett Cooper
82f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		/* try to sync with parent for mq_open */
830dc076565f772bb1953209fb69ea150b494aaa40robbiew		sigemptyset(&mask);
840dc076565f772bb1953209fb69ea150b494aaa40robbiew		sigaddset(&mask, SIGUSR1);
85f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		sigprocmask(SIG_BLOCK, &mask, NULL);
860dc076565f772bb1953209fb69ea150b494aaa40robbiew		sigwait(&mask, &sig);
870dc076565f772bb1953209fb69ea150b494aaa40robbiew
88f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		childqueue = mq_open(qname, O_CREAT | O_EXCL | O_RDWR,
89f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao				     S_IRUSR | S_IWUSR, NULL);
90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (childqueue != (mqd_t) - 1) {
91d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai			++*(int *)pa;
920dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifdef DEBUG
930dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("mq_open() in child succeeded\n");
940dc076565f772bb1953209fb69ea150b494aaa40robbiew		} else {
950dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("mq_open() in child failed\n");
960dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif
97f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		}
980dc076565f772bb1953209fb69ea150b494aaa40robbiew	} else {
990dc076565f772bb1953209fb69ea150b494aaa40robbiew		/* parent here */
1000dc076565f772bb1953209fb69ea150b494aaa40robbiew		int i;
1010dc076565f772bb1953209fb69ea150b494aaa40robbiew
1020dc076565f772bb1953209fb69ea150b494aaa40robbiew		sleep(1);
103f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		kill(pid, SIGUSR1);
1040dc076565f772bb1953209fb69ea150b494aaa40robbiew
105f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		queue = mq_open(qname, O_CREAT | O_EXCL | O_RDWR,
1060dc076565f772bb1953209fb69ea150b494aaa40robbiew				S_IRUSR | S_IWUSR, NULL);
107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (queue != (mqd_t) - 1) {
108d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai			++*(int *)pa;
1090dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifdef DEBUG
1100dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("mq_open() in parent succeeded\n");
1110dc076565f772bb1953209fb69ea150b494aaa40robbiew		} else {
1120dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("mq_open() in parent failed\n");
1130dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif
114f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		}
1150dc076565f772bb1953209fb69ea150b494aaa40robbiew
1160dc076565f772bb1953209fb69ea150b494aaa40robbiew		if (wait(&i) == -1) {
1170dc076565f772bb1953209fb69ea150b494aaa40robbiew			perror("Error waiting for child to exit");
1180dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("Test UNRESOLVED\n");
1190dc076565f772bb1953209fb69ea150b494aaa40robbiew			mq_close(queue);
1200dc076565f772bb1953209fb69ea150b494aaa40robbiew			mq_close(childqueue);
1210dc076565f772bb1953209fb69ea150b494aaa40robbiew			mq_unlink(qname);
122d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai			close(fd);
123d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai			munmap(pa, sizeof(int));
1240dc076565f772bb1953209fb69ea150b494aaa40robbiew			return PTS_UNRESOLVED;
1250dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
1260dc076565f772bb1953209fb69ea150b494aaa40robbiew
1270dc076565f772bb1953209fb69ea150b494aaa40robbiew		mq_close(queue);
1280dc076565f772bb1953209fb69ea150b494aaa40robbiew		mq_close(childqueue);
1290dc076565f772bb1953209fb69ea150b494aaa40robbiew		mq_unlink(qname);
1300dc076565f772bb1953209fb69ea150b494aaa40robbiew
131d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai		succeeded = *(int *)pa;
132d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai		close(fd);
133d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai		munmap(pa, sizeof(int));
134d3f22c05202c3ec296c43ca09907f5adc9600c02Kang Kai
135f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		if (succeeded == 0) {
1360dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("Test FAILED - mq_open() never succeeded\n");
1370dc076565f772bb1953209fb69ea150b494aaa40robbiew			return PTS_FAIL;
1380dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
1390dc076565f772bb1953209fb69ea150b494aaa40robbiew
140f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		if (succeeded > 1) {
1410dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("Test FAILED - mq_open() succeeded twice\n");
1420dc076565f772bb1953209fb69ea150b494aaa40robbiew			return PTS_FAIL;
1430dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
1440dc076565f772bb1953209fb69ea150b494aaa40robbiew
145f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		printf("Test PASSED\n");
146f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao		return PTS_PASS;
1470dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1480dc076565f772bb1953209fb69ea150b494aaa40robbiew
1490dc076565f772bb1953209fb69ea150b494aaa40robbiew	return PTS_UNRESOLVED;
150f0b3793025a1ca87987e778fdb703932e0dc5b3cWanlong Gao}
151