1 /* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /** 33 * @defgroup mqueue Message queue 34 * @ingroup posix 35 */ 36 37 #ifndef _HWLITEOS_POSIX_MQUEUE_H 38 #define _HWLITEOS_POSIX_MQUEUE_H 39 40 /* INCLUDES */ 41 #include "stdarg.h" 42 #include "stdlib.h" 43 #include "limits.h" 44 #include "los_typedef.h" 45 #include "time.h" 46 #include <sys/types.h> 47 #include <sys/stat.h> 48 #include <unistd.h> 49 50 #include "los_queue_pri.h" 51 52 #ifdef __cplusplus 53 #if __cplusplus 54 extern "C" { 55 #endif /* __cplusplus */ 56 #endif /* __cplusplus */ 57 58 /** 59 * @ingroup mqueue 60 * Maximum number of messages in a message queue 61 */ 62 #define MQ_MAX_MSG_NUM 16 63 64 /** 65 * @ingroup mqueue 66 * Maximum size of a single message in a message queue 67 */ 68 #define MQ_MAX_MSG_LEN 64 69 70 71 /* CONSTANTS */ 72 73 #define MQ_USE_MAGIC 0x89abcdef 74 /* not support prio */ 75 #define MQ_PRIO_MAX 1 76 77 #ifndef MAX_MQ_FD 78 #define MAX_MQ_FD CONFIG_NQUEUE_DESCRIPTORS 79 #endif 80 81 typedef union send_receive_t { 82 unsigned oth : 3; 83 unsigned grp : 6; 84 unsigned usr : 9; 85 short data; 86 } mode_s; 87 88 struct mqnotify { 89 pid_t pid; 90 struct sigevent notify; 91 }; 92 93 /* TYPE DEFINITIONS */ 94 struct mqarray { 95 UINT32 mq_id : 31; 96 UINT32 unlinkflag : 1; 97 char *mq_name; 98 UINT32 unlink_ref; 99 mode_s mode_data; /* mode data of mqueue */ 100 uid_t euid; /* euid of mqueue */ 101 gid_t egid; /* egid of mqueue */ 102 struct mqnotify mq_notify; 103 LosQueueCB *mqcb; 104 struct mqpersonal *mq_personal; 105 }; 106 107 struct mqpersonal { 108 struct mqarray *mq_posixdes; 109 struct mqpersonal *mq_next; 110 int mq_flags; 111 int mq_mode; /* Mode of mqueue */ 112 UINT32 mq_status; 113 UINT32 mq_refcount; 114 }; 115 116 /** 117 * @ingroup mqueue 118 * Message queue attribute structure 119 */ 120 struct mq_attr { 121 long mq_flags; /**< Message queue flags */ 122 long mq_maxmsg; /**< Maximum number of messages */ 123 long mq_msgsize; /**< Maximum size of a message */ 124 long mq_curmsgs; /**< Number of messages in the current message queue */ 125 }; 126 127 /** 128 * @ingroup mqueue 129 * Handle type of a message queue 130 */ 131 typedef UINTPTR mqd_t; 132 133 /** 134 * @ingroup mqueue 135 * 136 * @par Description: 137 * This API is used to open an existed message queue that has a specified name or create a new message queue. 138 * @attention 139 * <ul> 140 * <li>A message queue does not restrict the read and write permissions.</li> 141 * <li>The length of mqueue name must less than 256.</li> 142 * <li>This operation and closed mqueue scheduling must be used in coordination to release the resource.</li> 143 * <li>The parameter "mode" is not supported.</li> 144 * <li>The "mq_curmsgs" member of the mq_attr structure is not supported.</li> 145 * </ul> 146 * 147 * @param mqName [IN] Message queue name. 148 * @param openFlag [IN] Permission attributes of the message queue. The value range is 149 * [O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NONBLOCK]. 150 * @param mode [IN] Message queue mode (variadic argument). When oflag is O_CREAT, it requires 151 * two additional arguments: mode, which shall be of type mode_t, and attr, 152 * which shall be a pointer to an mq_attr structure. 153 * @param attr [IN] Message queue attribute (variadic argument). 154 * 155 * @retval mqd_t The message queue is successfully opened or created. 156 * @retval (mqd_t)-1 The message queue fails to be opened or created, with any of the following error codes in errno. 157 * 158 * 159 * @par Errors 160 * <ul> 161 * <li><b>ENOENT</b>: O_CREAT flag is not set for oflag, and the message queue specified by name does not exist.</li> 162 * <li><b>EEXIST</b>: Both O_CREAT and O_EXCL are set for oflag, but the message queue 163 * specified by name already exists.</li> 164 * <li><b>EINVAL</b>: invalid parameter.</li> 165 * <li><b>ENFILE</b>: The number of opened message queues exceeds the maximum limit.</li> 166 * <li><b>ENOSPC</b>: insufficient memory.</li> 167 * <li><b>ENAMETOOLONG</b>: The message queue name specified by name is too long.</li> 168 * </ul> 169 * 170 * @par Dependency: 171 * <ul><li>mqueue.h</li></ul> 172 * @see mq_close 173 */ 174 extern mqd_t mq_open(const char *mqName, int openFlag, ...); 175 176 /** 177 * @ingroup mqueue 178 * 179 * @par Description: 180 * This API is used to close a message queue that has a specified descriptor. 181 * @attention 182 * <ul> 183 * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_unlink is called.</li> 184 * </ul> 185 * 186 * @param personal [IN] Message queue descriptor. 187 * 188 * @retval 0 The message queue is successfully closed. 189 * @retval -1 The message queue fails to be closed, with either of the following error codes in errno. 190 * 191 * @par Errors 192 * <ul> 193 * <li><b>EBADF</b>: Invalid message queue descriptor.</li> 194 * <li><b>EAGAIN</b>: Failed to delete the message queue.</li> 195 * <li><b>EFAULT</b>: Failed to free the message queue.</li> 196 * <li><b>EINVAL</b>: Invalid parameter.</li> 197 * </ul> 198 * 199 * @par Dependency: 200 * <ul><li>mqueue.h</li></ul> 201 * @see mq_open 202 */ 203 extern int mq_close(mqd_t personal); 204 205 /** 206 * @ingroup mqueue 207 * 208 * @par Description: 209 * This API is used to remove a message queue that has a specified name. 210 * @attention 211 * <ul> 212 * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_close is called.</li> 213 * <li> The length of mqueue name must less than 256.</li> 214 * </ul> 215 * 216 * @param mqName [IN] Message queue name. 217 * 218 * @retval 0 The message queue is successfully removed. 219 * @retval -1 The message queue fails to be removed, with any of the following error codes in errno. 220 * 221 * @par Errors 222 * <ul> 223 * <li><b>ENOENT</b>: The message queue specified by name does not exist.</li> 224 * <li><b>EAGAIN</b>: Failed to delete the message queue.</li> 225 * <li><b>EBUSY</b>: The message queue to be removed is being used.</li> 226 * <li><b>EINVAL</b>: Invalid parameter.</li> 227 * <li><b>ENAMETOOLONG</b>: The name of mqueue is too long.</li> 228 * </ul> 229 * 230 * @par Dependency: 231 * <ul><li>mqueue.h</li></ul> 232 * @see mq_close 233 */ 234 extern int mq_unlink(const char *mqName); 235 236 /** 237 * @ingroup mqueue 238 * 239 * @par Description: 240 * This API is used to put a message with specified message content and length into 241 * a message queue that has a specified descriptor. 242 * @attention 243 * <ul> 244 * <li> Priority-based message processing is not supported.</li> 245 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 246 * </ul> 247 * 248 * @param personal [IN] Message queue descriptor. 249 * @param msg [IN] Pointer to the message content to be sent. 250 * @param msgLen [IN] Length of the message to be sent. 251 * @param msgPrio [IN] Priority of the message to be sent (the value of this parameter must 252 * be 0 because priority-based message sending is not supported. If the 253 * value is not 0, this API will cease to work.) 254 * 255 * @retval 0 The message is successfully sent. 256 * @retval -1 The message fails to be sent, with any of the following error codes in errno. 257 * 258 * @par Errors 259 * <ul> 260 * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li> 261 * <li><b>EBADF</b>: The message queue is invalid or not writable.</li> 262 * <li><b>EAGAIN</b>: The message queue is full.</li> 263 * <li><b>EINVAL</b>: Invalid parameter.</li> 264 * <li><b>ENOSPC</b>: Insufficient memory.</li> 265 * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li> 266 * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li> 267 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 268 * </ul> 269 * 270 * @par Dependency: 271 * <ul><li>mqueue.h</li></ul> 272 * @see mq_receive 273 */ 274 extern int mq_send(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio); 275 276 /** 277 * @ingroup mqueue 278 * 279 * @par Description: 280 * This API is used to remove the oldest message from the message queue that has a specified descriptor, 281 * and puts it in the buffer pointed to by msg_ptr. 282 * @attention 283 * <ul> 284 * <li> Priority-based message processing is not supported.</li> 285 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 286 * </ul> 287 * 288 * @param personal [IN] Message queue descriptor. 289 * @param msg [IN] Pointer to the message content to be received. 290 * @param msgLen [IN] Length of the message to be received. 291 * @param msgPrio [OUT] Priority of the message to be received 292 * because priority-based message processing is not supported, this parameter is useless). 293 * 294 * @retval 0 The message is successfully received. 295 * @retval -1 The message fails to be received, with any of the following error codes in the errno. 296 * 297 * @par Errors 298 * <ul> 299 * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li> 300 * <li><b>EBADF</b>: The message queue is invalid or not readable.</li> 301 * <li><b>EAGAIN</b>: The message queue is empty.</li> 302 * <li><b>EINVAL</b>: invalid parameter.</li> 303 * <li><b>EMSGSIZE</b>: The message to be received is too long.</li> 304 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 305 * </ul> 306 * 307 * @par Dependency: 308 * <ul><li>mqueue.h</li></ul> 309 * @see mq_send 310 */ 311 extern ssize_t mq_receive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio); 312 313 /** 314 * @ingroup mqueue 315 * 316 * @par Description: 317 * This API is used to obtain or modify attributes of the message queue that has a specified descriptor. 318 * @attention 319 * <ul> 320 * <li> The mq_maxmsg, mq_msgsize, and mq_curmsgs attributes are not modified 321 * in the message queue attribute setting.</li> 322 * </ul> 323 * 324 * @param personal [IN] Message queue descriptor. 325 * @param mqSetAttr [IN] New attribute of the message queue. 326 * @param MqOldAttr [OUT] Old attribute of the message queue. 327 * 328 * @retval 0 The message queue attributes are successfully set or get. 329 * @retval -1 The message queue attributes fail to be set or get, 330 * with either of the following error codes in the errno. 331 * 332 * @par Errors 333 * <ul> 334 * <li><b>EBADF</b>: Invalid message queue.</li> 335 * <li><b>EINVAL</b>: Invalid parameter.</li> 336 * </ul> 337 * 338 * @par Dependency: 339 * <ul><li>mqueue.h</li></ul> 340 * @see sys_mq_getsetattr 341 */ 342 extern int mq_getsetattr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *MqOldAttr); 343 344 /** 345 * @ingroup mqueue 346 * 347 * @par Description: 348 * This API is used to put a message with specified message content and length into 349 * a message queue that has a descriptor at a scheduled time. 350 * @attention 351 * <ul> 352 * <li> Priority-based message processing is not supported.</li> 353 * <li> The expiry time must be later than the current time.</li> 354 * <li> The wait time is a relative time.</li> 355 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 356 * </ul> 357 * 358 * @param mqdes [IN] Message queue descriptor. 359 * @param msg [IN] Pointer to the message content to be sent. 360 * @param msgLen [IN] Length of the message to be sent. 361 * @param msgPrio [IN] Priority of the message to be sent (the value of this parameter must be 0 362 * because priority-based message processing is not supported). 363 * @param absTimeout [IN] Scheduled time at which the message will be sent. If the value is 0, 364 * the message is an instant message. 365 * 366 * @retval 0 The message is successfully sent. 367 * @retval -1 The message fails to be sent, with any of the following error codes in errno. 368 * 369 * @par Errors 370 * <ul> 371 * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li> 372 * <li><b>EBADF</b>: The message queue is invalid or not writable.</li> 373 * <li><b>EAGAIN</b>: The message queue is full.</li> 374 * <li><b>EINVAL</b>: Invalid parameter.</li> 375 * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li> 376 * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li> 377 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 378 * </ul> 379 * 380 * @par Dependency: 381 * <ul><li>mqueue.h</li></ul> 382 * @see mq_receive 383 */ 384 extern int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, 385 unsigned int msgPrio, const struct timespec *absTimeout); 386 387 /** 388 * @ingroup mqueue 389 * 390 * @par Description: 391 * This API is used to obtain a message with specified message content and length from 392 * a message queue message that has a specified descriptor. 393 * @attention 394 * <ul> 395 * <li> Priority-based message processing is not supported.</li> 396 * <li> The expiry time must be later than the current time.</li> 397 * <li> The wait time is a relative time.</li> 398 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 399 * </ul> 400 * 401 * @param personal [IN] Message queue descriptor. 402 * @param msg [IN] Pointer to the message content to be received. 403 * @param msgLen [IN] Length of the message to be received. 404 * @param msgPrio [OUT] Priority of the message to be received (because priority-based message 405 * processing is not supported, this parameter is useless ). 406 * @param absTimeout [IN] Scheduled time at which the messagewill be received. If the value is 0, 407 * the message is an instant message. 408 * 409 * @retval 0 The message is successfully received. 410 * @retval -1 The message fails to be received, with any of the following error codes in errno. 411 * 412 * @par Errors 413 * <ul> 414 * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li> 415 * <li><b>EBADF</b>: The message queue is invalid or not readable.</li> 416 * <li><b>EAGAIN</b>: The message queue is empty.</li> 417 * <li><b>EINVAL</b>: invalid parameter.</li> 418 * <li><b>EMSGSIZE</b>: The message to be received is too long.</li> 419 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 420 * </ul> 421 * 422 * @par Dependency: 423 * <ul><li>mqueue.h</li></ul> 424 * @see mq_send 425 */ 426 extern ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, 427 unsigned int *msgPrio, const struct timespec *absTimeout); 428 429 extern void MqueueRefer(int sysFd); 430 extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev); 431 extern VOID OsMqueueCBDestroy(struct mqarray *queueTable); 432 433 #ifdef __cplusplus 434 #if __cplusplus 435 } 436 #endif /* __cplusplus */ 437 #endif /* __cplusplus */ 438 439 #endif 440