1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz>
4 */
5
6#ifndef MQ_H
7#define MQ_H
8
9#include "tst_test.h"
10#include "tst_sig_proc.h"
11#include "tst_safe_posix_ipc.h"
12
13#define MAX_MSGSIZE	8192
14#define MSG_LENGTH	10
15#define QUEUE_NAME	"/test_mqueue"
16#define QUEUE_NAME_NONBLOCK	"/test_mqueue_nonblock"
17
18static char smsg[MAX_MSGSIZE];
19static struct sigaction act;
20
21static void cleanup_common(void)
22{
23	if (fd_root > 0)
24		SAFE_CLOSE(fd_root);
25
26	if (fd > 0)
27		SAFE_CLOSE(fd);
28
29	if (fd_nonblock > 0)
30		SAFE_CLOSE(fd_nonblock);
31
32	mq_unlink(QUEUE_NAME);
33	mq_unlink(QUEUE_NAME_NONBLOCK);
34}
35
36static void sighandler(int sig LTP_ATTRIBUTE_UNUSED) { }
37
38static void setup_common(void)
39{
40	int i;
41
42	act.sa_handler = sighandler;
43	sigaction(SIGINT, &act, NULL);
44
45	cleanup_common();
46
47	fd_root = SAFE_OPEN("/", O_RDONLY);
48	fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, 0700, NULL);
49	fd_nonblock = SAFE_MQ_OPEN(QUEUE_NAME_NONBLOCK, O_CREAT | O_EXCL | O_RDWR |
50		O_NONBLOCK, 0700, NULL);
51
52	for (i = 0; i < MAX_MSGSIZE; i++)
53		smsg[i] = i;
54}
55
56static void cleanup_queue(mqd_t fd)
57{
58	int i;
59	struct mq_attr mqstat;
60	unsigned int prio;
61	char rmsg[MAX_MSGSIZE];
62
63	memset(&mqstat, 0, sizeof(mqstat));
64	if (mq_getattr(fd, &mqstat) == -1) {
65		tst_brk(TBROK|TERRNO, "mq_getattr() failed");
66		return;
67	}
68
69	for (i = 0; i < mqstat.mq_curmsgs; i++) {
70		tst_res(TINFO, "receive %d/%ld message", i + 1, mqstat.mq_curmsgs);
71		mq_receive(fd, rmsg, MAX_MSGSIZE, &prio);
72	}
73}
74
75#endif /* MQ_H */
76