aboutsummaryrefslogtreecommitdiff
path: root/include/tst_safe_posix_ipc.h
blob: 2d3d0928f41b997bab776b399aa21796a63c3280 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2017-2019 Petr Vorel pvorel@suse.cz
 * Copyright (C) 2022 Andrea Cervesato andrea.cervesato@suse.com
 */

#ifndef TST_SAFE_POSIX_IPC_H__
#define TST_SAFE_POSIX_IPC_H__

#include <mqueue.h>
#include <stdarg.h>

#define SAFE_MQ_OPEN(pathname, oflags, ...) \
	safe_mq_open(__FILE__, __LINE__, (pathname), (oflags), ##__VA_ARGS__)

#define SAFE_MQ_CLOSE(mqdes) \
	safe_mq_close(__FILE__, __LINE__, (mqdes))

#define SAFE_MQ_NOTIFY(mqdes, sevp)				\
	safe_mq_notify(__FILE__, __LINE__, (mqdes), (sevp))

#define SAFE_MQ_SEND(mqdes, msg_ptr, msg_len, msg_prio) \
	safe_mq_send(__FILE__, __LINE__, (mqdes), (msg_ptr), (msg_len), (msg_prio))

#define SAFE_MQ_UNLINK(name) \
	safe_mq_unlink(__FILE__, __LINE__, (name))

static inline int safe_mq_open(const char *file, const int lineno,
			       const char *pathname, int oflags, ...)
{
	va_list ap;
	int rval;
	mode_t mode;
	struct mq_attr *attr;

	va_start(ap, oflags);

	/* Android's NDK's mode_t is smaller than an int, which results in
	 * SIGILL here when passing the mode_t type.
	 */
#ifndef __ANDROID__
	mode = va_arg(ap, mode_t);
#else
	mode = va_arg(ap, int);
#endif

	attr = va_arg(ap, struct mq_attr *);

	va_end(ap);

	rval = mq_open(pathname, oflags, mode, attr);

	if (rval == -1) {
		tst_brk_(file, lineno, TBROK | TERRNO,
			"mq_open(%s,%d,%04o,%p) failed", pathname, oflags,
			mode, attr);
	} else if (rval < 0) {
		tst_brk_(file, lineno, TBROK | TERRNO,
			"Invalid mq_open(%s) return value %d", pathname, rval);
	}

	return rval;
}

static inline int safe_mq_close(const char *file, const int lineno,
				mqd_t __mqdes)
{
	int rval;

	rval = mq_close(__mqdes);

	if (rval == -1) {
		tst_brk_(file, lineno, TBROK | TERRNO,
			"mq_close(%d) failed", __mqdes);
	} else if (rval < 0) {
		tst_brk_(file, lineno, TBROK | TERRNO,
			"Invalid mq_close(%d) return value %d", __mqdes, rval);
	}

	return rval;
}

static inline int safe_mq_unlink(const char *file, const int lineno,
				const char* name)
{
	int rval;

	rval = mq_unlink(name);

	if (rval == -1) {
		tst_brk_(file, lineno, TBROK | TERRNO,
			"mq_unlink(%s) failed", name);
	} else if (rval < 0) {
		tst_brk_(file, lineno, TBROK | TERRNO,
			"Invalid mq_unlink(%s) return value %d", name, rval);
	}

	return rval;
}

static inline int safe_mq_notify(const char *file, const int lineno,
			  mqd_t mqdes, const struct sigevent *sevp)
{
	int rval;

	rval = mq_notify(mqdes, sevp);

	if (rval == -1)
		tst_brk_(file, lineno, TBROK | TERRNO, "mq_notify() failed");

	return rval;
}

static inline int safe_mq_send(const char *file, const int lineno,
			mqd_t mqdes, const char *msg_ptr,
			size_t msg_len, unsigned int msg_prio)
{
	int rval;

	rval = mq_send(mqdes, msg_ptr, msg_len, msg_prio);

	if (rval == -1) {
		tst_brk_(file, lineno, TBROK | TERRNO,
			"mq_send(%d,%s,%lu,%d) failed", mqdes, msg_ptr,
			msg_len, msg_prio);
	}

	return rval;
}

#endif /* TST_SAFE_POSIX_IPC_H__ */