1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2017-2019 Petr Vorel pvorel@suse.cz
4 * Copyright (C) 2022 Andrea Cervesato andrea.cervesato@suse.com
5 */
6
7 #ifndef TST_SAFE_POSIX_IPC_H__
8 #define TST_SAFE_POSIX_IPC_H__
9
10 #include <mqueue.h>
11 #include <stdarg.h>
12
13 #define SAFE_MQ_OPEN(pathname, oflags, ...) \
14 safe_mq_open(__FILE__, __LINE__, (pathname), (oflags), ##__VA_ARGS__)
15
16 #define SAFE_MQ_CLOSE(mqdes) \
17 safe_mq_close(__FILE__, __LINE__, (mqdes))
18
19 #define SAFE_MQ_NOTIFY(mqdes, sevp) \
20 safe_mq_notify(__FILE__, __LINE__, (mqdes), (sevp))
21
22 #define SAFE_MQ_SEND(mqdes, msg_ptr, msg_len, msg_prio) \
23 safe_mq_send(__FILE__, __LINE__, (mqdes), (msg_ptr), (msg_len), (msg_prio))
24
25 #define SAFE_MQ_UNLINK(name) \
26 safe_mq_unlink(__FILE__, __LINE__, (name))
27
safe_mq_open(const char * file,const int lineno,const char * pathname,int oflags,...)28 static inline int safe_mq_open(const char *file, const int lineno,
29 const char *pathname, int oflags, ...)
30 {
31 va_list ap;
32 int rval;
33 mode_t mode;
34 struct mq_attr *attr;
35
36 va_start(ap, oflags);
37
38 /* Android's NDK's mode_t is smaller than an int, which results in
39 * SIGILL here when passing the mode_t type.
40 */
41 #ifndef __ANDROID__
42 mode = va_arg(ap, mode_t);
43 #else
44 mode = va_arg(ap, int);
45 #endif
46
47 attr = va_arg(ap, struct mq_attr *);
48
49 va_end(ap);
50
51 rval = mq_open(pathname, oflags, mode, attr);
52
53 if (rval == -1) {
54 tst_brk_(file, lineno, TBROK | TERRNO,
55 "mq_open(%s,%d,%04o,%p) failed", pathname, oflags,
56 mode, attr);
57 } else if (rval < 0) {
58 tst_brk_(file, lineno, TBROK | TERRNO,
59 "Invalid mq_open(%s) return value %d", pathname, rval);
60 }
61
62 return rval;
63 }
64
safe_mq_close(const char * file,const int lineno,mqd_t __mqdes)65 static inline int safe_mq_close(const char *file, const int lineno,
66 mqd_t __mqdes)
67 {
68 int rval;
69
70 rval = mq_close(__mqdes);
71
72 if (rval == -1) {
73 tst_brk_(file, lineno, TBROK | TERRNO,
74 "mq_close(%d) failed", __mqdes);
75 } else if (rval < 0) {
76 tst_brk_(file, lineno, TBROK | TERRNO,
77 "Invalid mq_close(%d) return value %d", __mqdes, rval);
78 }
79
80 return rval;
81 }
82
safe_mq_unlink(const char * file,const int lineno,const char * name)83 static inline int safe_mq_unlink(const char *file, const int lineno,
84 const char* name)
85 {
86 int rval;
87
88 rval = mq_unlink(name);
89
90 if (rval == -1) {
91 tst_brk_(file, lineno, TBROK | TERRNO,
92 "mq_unlink(%s) failed", name);
93 } else if (rval < 0) {
94 tst_brk_(file, lineno, TBROK | TERRNO,
95 "Invalid mq_unlink(%s) return value %d", name, rval);
96 }
97
98 return rval;
99 }
100
safe_mq_notify(const char * file,const int lineno,mqd_t mqdes,const struct sigevent * sevp)101 static inline int safe_mq_notify(const char *file, const int lineno,
102 mqd_t mqdes, const struct sigevent *sevp)
103 {
104 int rval;
105
106 rval = mq_notify(mqdes, sevp);
107
108 if (rval == -1)
109 tst_brk_(file, lineno, TBROK | TERRNO, "mq_notify() failed");
110
111 return rval;
112 }
113
safe_mq_send(const char * file,const int lineno,mqd_t mqdes,const char * msg_ptr,size_t msg_len,unsigned int msg_prio)114 static inline int safe_mq_send(const char *file, const int lineno,
115 mqd_t mqdes, const char *msg_ptr,
116 size_t msg_len, unsigned int msg_prio)
117 {
118 int rval;
119
120 rval = mq_send(mqdes, msg_ptr, msg_len, msg_prio);
121
122 if (rval == -1) {
123 tst_brk_(file, lineno, TBROK | TERRNO,
124 "mq_send(%d,%s,%lu,%d) failed", mqdes, msg_ptr,
125 msg_len, msg_prio);
126 }
127
128 return rval;
129 }
130
131 #endif /* TST_SAFE_POSIX_IPC_H__ */
132