8 #include "../kselftest.h"
10 #define MAX_MSG_SIZE 32
15 char mtext
[MAX_MSG_SIZE
];
18 #define TEST_STRING "Test sysv5 msg"
21 #define ANOTHER_TEST_STRING "Yet another test sysv5 msg"
22 #define ANOTHER_MSG_TYPE 26538
30 struct msg1
*messages
;
33 int restore_queue(struct msgque_data
*msgque
)
38 fd
= open("/proc/sys/kernel/msg_next_id", O_WRONLY
);
40 printf("Failed to open /proc/sys/kernel/msg_next_id\n");
43 sprintf(buf
, "%d", msgque
->msq_id
);
45 ret
= write(fd
, buf
, strlen(buf
));
46 if (ret
!= strlen(buf
)) {
47 printf("Failed to write to /proc/sys/kernel/msg_next_id\n");
51 id
= msgget(msgque
->key
, msgque
->mode
| IPC_CREAT
| IPC_EXCL
);
53 printf("Failed to create queue\n");
57 if (id
!= msgque
->msq_id
) {
58 printf("Restored queue has wrong id (%d instead of %d)\n",
64 for (i
= 0; i
< msgque
->qnum
; i
++) {
65 if (msgsnd(msgque
->msq_id
, &msgque
->messages
[i
].mtype
,
66 msgque
->messages
[i
].msize
, IPC_NOWAIT
) != 0) {
67 printf("msgsnd failed (%m)\n");
75 if (msgctl(id
, IPC_RMID
, 0))
76 printf("Failed to destroy queue: %d\n", -errno
);
80 int check_and_destroy_queue(struct msgque_data
*msgque
)
86 ret
= msgrcv(msgque
->msq_id
, &message
.mtype
, MAX_MSG_SIZE
,
91 printf("Failed to read IPC message: %m\n");
95 if (ret
!= msgque
->messages
[cnt
].msize
) {
96 printf("Wrong message size: %d (expected %d)\n", ret
,
97 msgque
->messages
[cnt
].msize
);
101 if (message
.mtype
!= msgque
->messages
[cnt
].mtype
) {
102 printf("Wrong message type\n");
106 if (memcmp(message
.mtext
, msgque
->messages
[cnt
].mtext
, ret
)) {
107 printf("Wrong message content\n");
114 if (cnt
!= msgque
->qnum
) {
115 printf("Wrong message number\n");
122 if (msgctl(msgque
->msq_id
, IPC_RMID
, 0)) {
123 printf("Failed to destroy queue: %d\n", -errno
);
129 int dump_queue(struct msgque_data
*msgque
)
131 struct msqid64_ds ds
;
135 for (kern_id
= 0; kern_id
< 256; kern_id
++) {
136 ret
= msgctl(kern_id
, MSG_STAT
, &ds
);
138 if (errno
== -EINVAL
)
140 printf("Failed to get stats for IPC queue with id %d\n",
145 if (ret
== msgque
->msq_id
)
149 msgque
->messages
= malloc(sizeof(struct msg1
) * ds
.msg_qnum
);
150 if (msgque
->messages
== NULL
) {
151 printf("Failed to get stats for IPC queue\n");
155 msgque
->qnum
= ds
.msg_qnum
;
156 msgque
->mode
= ds
.msg_perm
.mode
;
157 msgque
->qbytes
= ds
.msg_qbytes
;
159 for (i
= 0; i
< msgque
->qnum
; i
++) {
160 ret
= msgrcv(msgque
->msq_id
, &msgque
->messages
[i
].mtype
,
161 MAX_MSG_SIZE
, i
, IPC_NOWAIT
| MSG_COPY
);
163 printf("Failed to copy IPC message: %m (%d)\n", errno
);
166 msgque
->messages
[i
].msize
= ret
;
171 int fill_msgque(struct msgque_data
*msgque
)
175 msgbuf
.mtype
= MSG_TYPE
;
176 memcpy(msgbuf
.mtext
, TEST_STRING
, sizeof(TEST_STRING
));
177 if (msgsnd(msgque
->msq_id
, &msgbuf
.mtype
, sizeof(TEST_STRING
),
179 printf("First message send failed (%m)\n");
183 msgbuf
.mtype
= ANOTHER_MSG_TYPE
;
184 memcpy(msgbuf
.mtext
, ANOTHER_TEST_STRING
, sizeof(ANOTHER_TEST_STRING
));
185 if (msgsnd(msgque
->msq_id
, &msgbuf
.mtype
, sizeof(ANOTHER_TEST_STRING
),
187 printf("Second message send failed (%m)\n");
193 int main(int argc
, char **argv
)
196 struct msgque_data msgque
;
199 printf("Please run the test as root - Exiting.\n");
200 return ksft_exit_fail();
203 msgque
.key
= ftok(argv
[0], 822155650);
204 if (msgque
.key
== -1) {
205 printf("Can't make key: %d\n", -errno
);
206 return ksft_exit_fail();
209 msgque
.msq_id
= msgget(msgque
.key
, IPC_CREAT
| IPC_EXCL
| 0666);
210 if (msgque
.msq_id
== -1) {
212 printf("Can't create queue: %d\n", err
);
216 err
= fill_msgque(&msgque
);
218 printf("Failed to fill queue: %d\n", err
);
222 err
= dump_queue(&msgque
);
224 printf("Failed to dump queue: %d\n", err
);
228 err
= check_and_destroy_queue(&msgque
);
230 printf("Failed to check and destroy queue: %d\n", err
);
234 err
= restore_queue(&msgque
);
236 printf("Failed to restore queue: %d\n", err
);
240 err
= check_and_destroy_queue(&msgque
);
242 printf("Failed to test queue: %d\n", err
);
245 return ksft_exit_pass();
248 if (msgctl(msgque
.msq_id
, IPC_RMID
, 0)) {
249 printf("Failed to destroy queue: %d\n", -errno
);
250 return ksft_exit_fail();
253 return ksft_exit_fail();