8 #define MAX_MSG_SIZE 32
13 char mtext
[MAX_MSG_SIZE
];
16 #define TEST_STRING "Test sysv5 msg"
19 #define ANOTHER_TEST_STRING "Yet another test sysv5 msg"
20 #define ANOTHER_MSG_TYPE 26538
28 struct msg1
*messages
;
31 int restore_queue(struct msgque_data
*msgque
)
36 fd
= open("/proc/sys/kernel/msg_next_id", O_WRONLY
);
38 printf("Failed to open /proc/sys/kernel/msg_next_id\n");
41 sprintf(buf
, "%d", msgque
->msq_id
);
43 ret
= write(fd
, buf
, strlen(buf
));
44 if (ret
!= strlen(buf
)) {
45 printf("Failed to write to /proc/sys/kernel/msg_next_id\n");
49 id
= msgget(msgque
->key
, msgque
->mode
| IPC_CREAT
| IPC_EXCL
);
51 printf("Failed to create queue\n");
55 if (id
!= msgque
->msq_id
) {
56 printf("Restored queue has wrong id (%d instead of %d)\n",
62 for (i
= 0; i
< msgque
->qnum
; i
++) {
63 if (msgsnd(msgque
->msq_id
, &msgque
->messages
[i
].mtype
,
64 msgque
->messages
[i
].msize
, IPC_NOWAIT
) != 0) {
65 printf("msgsnd failed (%m)\n");
73 if (msgctl(id
, IPC_RMID
, 0))
74 printf("Failed to destroy queue: %d\n", -errno
);
78 int check_and_destroy_queue(struct msgque_data
*msgque
)
84 ret
= msgrcv(msgque
->msq_id
, &message
.mtype
, MAX_MSG_SIZE
,
89 printf("Failed to read IPC message: %m\n");
93 if (ret
!= msgque
->messages
[cnt
].msize
) {
94 printf("Wrong message size: %d (expected %d)\n", ret
,
95 msgque
->messages
[cnt
].msize
);
99 if (message
.mtype
!= msgque
->messages
[cnt
].mtype
) {
100 printf("Wrong message type\n");
104 if (memcmp(message
.mtext
, msgque
->messages
[cnt
].mtext
, ret
)) {
105 printf("Wrong message content\n");
112 if (cnt
!= msgque
->qnum
) {
113 printf("Wrong message number\n");
120 if (msgctl(msgque
->msq_id
, IPC_RMID
, 0)) {
121 printf("Failed to destroy queue: %d\n", -errno
);
127 int dump_queue(struct msgque_data
*msgque
)
129 struct msqid64_ds ds
;
133 for (kern_id
= 0; kern_id
< 256; kern_id
++) {
134 ret
= msgctl(kern_id
, MSG_STAT
, &ds
);
136 if (errno
== -EINVAL
)
138 printf("Failed to get stats for IPC queue with id %d\n",
143 if (ret
== msgque
->msq_id
)
147 msgque
->messages
= malloc(sizeof(struct msg1
) * ds
.msg_qnum
);
148 if (msgque
->messages
== NULL
) {
149 printf("Failed to get stats for IPC queue\n");
153 msgque
->qnum
= ds
.msg_qnum
;
154 msgque
->mode
= ds
.msg_perm
.mode
;
155 msgque
->qbytes
= ds
.msg_qbytes
;
157 for (i
= 0; i
< msgque
->qnum
; i
++) {
158 ret
= msgrcv(msgque
->msq_id
, &msgque
->messages
[i
].mtype
,
159 MAX_MSG_SIZE
, i
, IPC_NOWAIT
| MSG_COPY
);
161 printf("Failed to copy IPC message: %m (%d)\n", errno
);
164 msgque
->messages
[i
].msize
= ret
;
169 int fill_msgque(struct msgque_data
*msgque
)
173 msgbuf
.mtype
= MSG_TYPE
;
174 memcpy(msgbuf
.mtext
, TEST_STRING
, sizeof(TEST_STRING
));
175 if (msgsnd(msgque
->msq_id
, &msgbuf
.mtype
, sizeof(TEST_STRING
),
177 printf("First message send failed (%m)\n");
181 msgbuf
.mtype
= ANOTHER_MSG_TYPE
;
182 memcpy(msgbuf
.mtext
, ANOTHER_TEST_STRING
, sizeof(ANOTHER_TEST_STRING
));
183 if (msgsnd(msgque
->msq_id
, &msgbuf
.mtype
, sizeof(ANOTHER_TEST_STRING
),
185 printf("Second message send failed (%m)\n");
191 int main(int argc
, char **argv
)
194 struct msgque_data msgque
;
196 msgque
.key
= ftok(argv
[0], 822155650);
197 if (msgque
.key
== -1) {
198 printf("Can't make key\n");
202 msgque
.msq_id
= msgget(msgque
.key
, IPC_CREAT
| IPC_EXCL
| 0666);
203 if (msgque
.msq_id
== -1) {
204 printf("Can't create queue\n");
208 err
= fill_msgque(&msgque
);
210 printf("Failed to fill queue\n");
214 err
= dump_queue(&msgque
);
216 printf("Failed to dump queue\n");
220 err
= check_and_destroy_queue(&msgque
);
222 printf("Failed to check and destroy queue\n");
226 err
= restore_queue(&msgque
);
228 printf("Failed to restore queue\n");
232 err
= check_and_destroy_queue(&msgque
);
234 printf("Failed to test queue\n");
240 if (msgctl(msgque
.msq_id
, IPC_RMID
, 0)) {
241 printf("Failed to destroy queue: %d\n", -errno
);