1 // SPDX-License-Identifier: GPL-2.0
10 #include "../kselftest.h"
12 #define MAX_MSG_SIZE 32
17 char mtext
[MAX_MSG_SIZE
];
20 #define TEST_STRING "Test sysv5 msg"
23 #define ANOTHER_TEST_STRING "Yet another test sysv5 msg"
24 #define ANOTHER_MSG_TYPE 26538
32 struct msg1
*messages
;
35 int restore_queue(struct msgque_data
*msgque
)
40 fd
= open("/proc/sys/kernel/msg_next_id", O_WRONLY
);
42 printf("Failed to open /proc/sys/kernel/msg_next_id\n");
45 sprintf(buf
, "%d", msgque
->msq_id
);
47 ret
= write(fd
, buf
, strlen(buf
));
48 if (ret
!= strlen(buf
)) {
49 printf("Failed to write to /proc/sys/kernel/msg_next_id\n");
53 id
= msgget(msgque
->key
, msgque
->mode
| IPC_CREAT
| IPC_EXCL
);
55 printf("Failed to create queue\n");
59 if (id
!= msgque
->msq_id
) {
60 printf("Restored queue has wrong id (%d instead of %d)\n",
66 for (i
= 0; i
< msgque
->qnum
; i
++) {
67 if (msgsnd(msgque
->msq_id
, &msgque
->messages
[i
].mtype
,
68 msgque
->messages
[i
].msize
, IPC_NOWAIT
) != 0) {
69 printf("msgsnd failed (%m)\n");
77 if (msgctl(id
, IPC_RMID
, NULL
))
78 printf("Failed to destroy queue: %d\n", -errno
);
82 int check_and_destroy_queue(struct msgque_data
*msgque
)
88 ret
= msgrcv(msgque
->msq_id
, &message
.mtype
, MAX_MSG_SIZE
,
93 printf("Failed to read IPC message: %m\n");
97 if (ret
!= msgque
->messages
[cnt
].msize
) {
98 printf("Wrong message size: %d (expected %d)\n", ret
,
99 msgque
->messages
[cnt
].msize
);
103 if (message
.mtype
!= msgque
->messages
[cnt
].mtype
) {
104 printf("Wrong message type\n");
108 if (memcmp(message
.mtext
, msgque
->messages
[cnt
].mtext
, ret
)) {
109 printf("Wrong message content\n");
116 if (cnt
!= msgque
->qnum
) {
117 printf("Wrong message number\n");
124 if (msgctl(msgque
->msq_id
, IPC_RMID
, NULL
)) {
125 printf("Failed to destroy queue: %d\n", -errno
);
131 int dump_queue(struct msgque_data
*msgque
)
137 for (kern_id
= 0; kern_id
< 256; kern_id
++) {
138 ret
= msgctl(kern_id
, MSG_STAT
, &ds
);
140 if (errno
== -EINVAL
)
142 printf("Failed to get stats for IPC queue with id %d\n",
147 if (ret
== msgque
->msq_id
)
151 msgque
->messages
= malloc(sizeof(struct msg1
) * ds
.msg_qnum
);
152 if (msgque
->messages
== NULL
) {
153 printf("Failed to get stats for IPC queue\n");
157 msgque
->qnum
= ds
.msg_qnum
;
158 msgque
->mode
= ds
.msg_perm
.mode
;
159 msgque
->qbytes
= ds
.msg_qbytes
;
161 for (i
= 0; i
< msgque
->qnum
; i
++) {
162 ret
= msgrcv(msgque
->msq_id
, &msgque
->messages
[i
].mtype
,
163 MAX_MSG_SIZE
, i
, IPC_NOWAIT
| MSG_COPY
);
165 printf("Failed to copy IPC message: %m (%d)\n", errno
);
168 msgque
->messages
[i
].msize
= ret
;
173 int fill_msgque(struct msgque_data
*msgque
)
177 msgbuf
.mtype
= MSG_TYPE
;
178 memcpy(msgbuf
.mtext
, TEST_STRING
, sizeof(TEST_STRING
));
179 if (msgsnd(msgque
->msq_id
, &msgbuf
.mtype
, sizeof(TEST_STRING
),
181 printf("First message send failed (%m)\n");
185 msgbuf
.mtype
= ANOTHER_MSG_TYPE
;
186 memcpy(msgbuf
.mtext
, ANOTHER_TEST_STRING
, sizeof(ANOTHER_TEST_STRING
));
187 if (msgsnd(msgque
->msq_id
, &msgbuf
.mtype
, sizeof(ANOTHER_TEST_STRING
),
189 printf("Second message send failed (%m)\n");
195 int main(int argc
, char **argv
)
198 struct msgque_data msgque
;
201 return ksft_exit_skip(
202 "Please run the test as root - Exiting.\n");
204 msgque
.key
= ftok(argv
[0], 822155650);
205 if (msgque
.key
== -1) {
206 printf("Can't make key: %d\n", -errno
);
207 return ksft_exit_fail();
210 msgque
.msq_id
= msgget(msgque
.key
, IPC_CREAT
| IPC_EXCL
| 0666);
211 if (msgque
.msq_id
== -1) {
213 printf("Can't create queue: %d\n", err
);
217 err
= fill_msgque(&msgque
);
219 printf("Failed to fill queue: %d\n", err
);
223 err
= dump_queue(&msgque
);
225 printf("Failed to dump queue: %d\n", err
);
229 err
= check_and_destroy_queue(&msgque
);
231 printf("Failed to check and destroy queue: %d\n", err
);
235 err
= restore_queue(&msgque
);
237 printf("Failed to restore queue: %d\n", err
);
241 err
= check_and_destroy_queue(&msgque
);
243 printf("Failed to test queue: %d\n", err
);
246 return ksft_exit_pass();
249 if (msgctl(msgque
.msq_id
, IPC_RMID
, NULL
)) {
250 printf("Failed to destroy queue: %d\n", -errno
);
251 return ksft_exit_fail();
254 return ksft_exit_fail();