• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,%zu,%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