2 * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com.
3 * Distributed under the terms of the MIT License.
21 #include "TestUnitUtils.h"
23 #define KEY ((key_t)12345)
26 remove_msg_queue(int msgID
)
28 return msgctl(msgID
, IPC_RMID
, 0);
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
83 status
= remove_msg_queue(msgID
);
84 assert_posix_bool_success(errno
== EINVAL
);
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);
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);
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);
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)");
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);
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);
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)");
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();
203 // Send a simple message
204 TEST("msgsnd(simple message)");
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);
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)");
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);
240 printf("\nAll tests OK\n");