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 28static 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 65static 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 83static 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 101static 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 114static 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