headers/bsd: Add sys/queue.h.
[haiku.git] / src / tests / system / libroot / posix / xsi_msg_queue_test1.cpp
blobf308a256191d94a38f1b336e890be6ba45b9623e
1 /*
2 * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com.
3 * Distributed under the terms of the MIT License.
4 */
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <sys/mman.h>
14 #include <sys/msg.h>
15 #include <sys/stat.h>
16 #include <sys/time.h>
17 #include <sys/wait.h>
19 #include <OS.h>
21 #include "TestUnitUtils.h"
23 #define KEY ((key_t)12345)
25 static status_t
26 remove_msg_queue(int msgID)
28 return msgctl(msgID, IPC_RMID, 0);
31 struct message {
32 long type;
33 char text[20];
37 static void
38 test_msgget()
40 TEST_SET("msgget({IPC_PRIVATE, key})");
42 const char* currentTest = NULL;
44 // Open private set with IPC_PRIVATE
45 TEST("msgget(IPC_PRIVATE) - private");
46 int msgID = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR);
47 assert_posix_bool_success(msgID != -1);
49 // Destroy private msg_queue
50 TEST("msgctl(IPC_RMID) - private");
51 status_t status = remove_msg_queue(msgID);
52 assert_posix_bool_success(status != -1);
54 // Open non-private non-existing set with IPC_CREAT
55 TEST("msgget(KEY, IPC_CREAT) non-existing");
56 msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR
57 | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
58 assert_posix_bool_success(status != -1);
60 // Re-open non-private existing without IPC_CREAT
61 TEST("msgget(KEY) re-open existing without IPC_CREAT");
62 int returnID = msgget(KEY, 0);
63 assert_equals(msgID, returnID);
65 // Re-open non-private existing with IPC_CREAT
66 TEST("msgget(IPC_CREATE) re-open existing with IPC_CREAT");
67 returnID = msgget(KEY, IPC_CREAT | IPC_EXCL);
68 assert_posix_bool_success(errno == EEXIST);
70 // Destroy non-private msg_queue
71 TEST("msgctl(IPC_RMID)");
72 status = remove_msg_queue(msgID);
73 assert_posix_bool_success(status != -1);
75 // Open non-private non-existing without IPC_CREAT
76 TEST("msgget(IPC_CREATE) non-existing without IPC_CREAT");
77 msgID = msgget(KEY, IPC_EXCL | S_IRUSR | S_IWUSR
78 | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
79 assert_posix_bool_success(errno == ENOENT);
81 // Destroy non-existing msg_queue
82 TEST("msgctl()");
83 status = remove_msg_queue(msgID);
84 assert_posix_bool_success(errno == EINVAL);
86 TEST("done");
90 static void
91 test_msgctl()
93 TEST_SET("msgctl({IPC_STAT, IPC_SET, IPC_RMID})");
95 const char* currentTest = NULL;
97 // Open non-private non-existing set with IPC_CREAT
98 TEST("msgget(IPC_CREATE) non-existing");
99 int msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR
100 | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
101 assert_posix_bool_success(msgID != -1);
103 // IPC_SET
104 TEST("msgctl(IPC_SET)");
105 struct msqid_ds msg_queue;
106 memset(&msg_queue, 0, sizeof(struct msqid_ds));
107 msg_queue.msg_perm.uid = getuid() + 3;
108 msg_queue.msg_perm.gid = getgid() + 3;
109 msg_queue.msg_perm.mode = 0666;
110 msg_queue.msg_qbytes = 512;
111 status_t status = msgctl(msgID, IPC_SET, &msg_queue);
112 assert_posix_bool_success(status != 1);
114 // IPC_STAT set
115 TEST("msgctl(IPC_STAT)");
116 memset(&msg_queue, 0, sizeof(struct msqid_ds));
117 status = msgctl(msgID, IPC_STAT, &msg_queue);
118 assert_posix_bool_success(status != 1);
119 TEST("msgctl(IPC_STAT): number of bytes");
120 assert_equals((msglen_t)msg_queue.msg_qbytes, (msglen_t)512);
121 TEST("msgctl(IPC_STAT): uid");
122 assert_equals(msg_queue.msg_perm.uid, getuid() + 3);
123 TEST("msgctl(IPC_STAT): gid");
124 assert_equals(msg_queue.msg_perm.gid, getgid() + 3);
126 // Destroy non-private msg_queue
127 TEST("msgctl(IPC_RMID)");
128 status = remove_msg_queue(msgID);
129 assert_posix_bool_success(status != 1);
131 TEST("done");
135 static void
136 test_msgsnd()
138 TEST_SET("msgsnd({EAGAIN, send})");
140 const char* currentTest = NULL;
142 // Open non-private non-existing set with IPC_CREAT
143 TEST("msgget(IPC_CREATE) non-existing");
144 int msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR
145 | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
146 assert_posix_bool_success(msgID != -1);
148 // Send simple message
149 TEST("msgsnd(simple message)");
150 struct message msg;
151 msg.type = 0;
152 strcpy(msg.text, "Message to send\n");
153 status_t status = msgsnd((key_t)msgID, (void *)&msg, 20, 0);
154 assert_posix_bool_success(status != 1);
156 // IPC_SET
157 TEST("msgctl(IPC_SET) - set limit to 512");
158 struct msqid_ds msg_queue;
159 memset(&msg_queue, 0, sizeof(struct msqid_ds));
160 msg_queue.msg_perm.uid = getuid() + 3;
161 msg_queue.msg_perm.gid = getgid() + 3;
162 msg_queue.msg_perm.mode = 0666;
163 msg_queue.msg_qbytes = 512;
164 status = msgctl(msgID, IPC_SET, &msg_queue);
165 assert_posix_bool_success(status != 1);
167 // Send big message IPC_NOWAIT
168 TEST("msgsnd(IPC_NOWAIT)");
169 msgsnd((key_t)msgID, (void *)&msg, 500, IPC_NOWAIT);
170 assert_posix_bool_success(errno == EAGAIN);
172 // Destroy non-private msg_queue
173 TEST("msgctl(IPC_RMID)");
174 status = remove_msg_queue(msgID);
175 assert_posix_bool_success(status != 1);
177 TEST("done");
181 static void
182 test_msgrcv()
184 TEST_SET("msgrcv({IPC_STAT, IPC_SET, IPC_RMID})");
186 const char* currentTest = NULL;
188 // Open non-private non-existing set with IPC_CREAT
189 TEST("msgget(IPC_CREATE) non-existing");
190 int msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR
191 | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
192 assert_posix_bool_success(msgID != -1);
194 // Receive simple message
195 TEST("msgrcv(IPC_NOWAIT)");
196 struct message msg;
197 memset(&msg, 0, sizeof(struct message));
198 msgrcv((key_t)msgID, (void *)&msg, 20, 0, IPC_NOWAIT);
199 assert_posix_bool_success(errno == ENOMSG);
201 pid_t child = fork();
202 if (child == 0) {
203 // Send a simple message
204 TEST("msgsnd(simple message)");
205 struct message smsg;
206 msg.type = 0;
207 strcpy(msg.text, "Message to send\n");
208 status_t status = msgsnd((key_t)msgID, (void *)&smsg, 20, 0);
209 assert_posix_bool_success(status != 1);
210 exit(0);
213 wait_for_child(child);
214 TEST("msgrcv(E2BIG)");
215 msgrcv((key_t)msgID, (void *)&msg, 10, 0, IPC_NOWAIT);
216 assert_posix_bool_success(errno == E2BIG);
218 TEST("msgrcv(MSG_NOERROR)");
219 status_t status
220 = msgrcv((key_t)msgID, (void *)&msg, 10, 0, IPC_NOWAIT | MSG_NOERROR);
221 assert_posix_bool_success(status != -1);
223 // Destroy non-private msg_queue
224 TEST("msgctl(IPC_RMID)");
225 status = remove_msg_queue(msgID);
226 assert_posix_bool_success(status != 1);
228 TEST("done");
233 main()
235 test_msgget();
236 test_msgctl();
237 test_msgsnd();
238 test_msgrcv();
240 printf("\nAll tests OK\n");