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 O_NONBLOCK is set and the message queue is full, mq_timedsend()
11 * will just return an error message and the message will not be queued.
12 *
13 * Test by sending messages with increasing priority number until a failure
14 * is received.  Then test that the message just sent (highest priority) is
15 * not the one received.
16 *
17 * 3/13/03 - Added fix from Gregoire Pichon for specifying an attr
18 *           with a mq_msgsize >= BUFFER.
19 *
20 */
21
22#include <stdio.h>
23#include <mqueue.h>
24#include <fcntl.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <unistd.h>
28#include <string.h>
29#include <stdint.h>
30#include <errno.h>
31#include <time.h>
32#include "posixtest.h"
33
34#define NAMESIZE 50
35#define MESSAGESIZE 50
36#define MSGSTR "0123456789"
37#define BUFFER 40
38#define MAXMSG 5
39
40int main()
41{
42        char qname[NAMESIZE], msgrcd[BUFFER];
43        char msgptr[MESSAGESIZE];
44	struct timespec ts;
45	struct mq_attr attr;
46        mqd_t queue;
47	int unresolved=0, failure=0, spri=1, i, maxreached=0;
48	unsigned pri;
49
50        sprintf(qname, "/mq_timedsend_7-1_%d", getpid());
51
52	attr.mq_msgsize = BUFFER;
53	attr.mq_maxmsg = MAXMSG;
54        queue = mq_open(qname, O_CREAT | O_RDWR | O_NONBLOCK,
55			S_IRUSR | S_IWUSR, &attr);
56        if (queue == (mqd_t)-1) {
57                perror("mq_open() did not return success");
58                return PTS_UNRESOLVED;
59        }
60
61	ts.tv_sec=time(NULL);
62	ts.tv_nsec=0;
63	for (i=0; i<MAXMSG+1; i++) {
64		sprintf(msgptr, "message %d", i);
65		ts.tv_sec++;
66        	if (mq_timedsend(queue, msgptr, strlen(msgptr), spri++, &ts)
67									== -1) {
68			maxreached=1;
69			if (errno != EAGAIN) {
70				printf("mq_timedsend() didn't fail w/EAGAIN\n");
71				failure=1;
72			}
73			break;
74        	}
75	}
76
77        if (mq_receive(queue, msgrcd, BUFFER, &pri) == -1) {
78		perror("mq_receive() returned failure");
79		unresolved=1;
80	} else {
81		if ((strcmp(msgptr, msgrcd) == 0) && (maxreached!=0)) {
82			printf("Error: Received message that caused EAGAIN\n");
83			failure = 1;
84		}
85	}
86
87        if (mq_close(queue) != 0) {
88		perror("mq_close() did not return success");
89		unresolved=1;
90        }
91
92        if (mq_unlink(qname) != 0) {
93		perror("mq_unlink() did not return success");
94		unresolved=1;
95        }
96
97	if (maxreached==0) {
98		printf("Test inconclusive:  Couldn't fill message queue\n");
99		return PTS_UNRESOLVED;
100	}
101	if (failure==1) {
102		printf("Test FAILED\n");
103		return PTS_FAIL;
104	}
105
106	if (unresolved==1) {
107		printf("Test UNRESOLVED\n");
108		return PTS_UNRESOLVED;
109	}
110
111        printf("Test PASSED\n");
112        return PTS_PASS;
113}
114
115