1 /* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 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 typedef union send_receive_t { 78 unsigned oth : 3; 79 unsigned grp : 6; 80 unsigned usr : 9; 81 short data; 82 } mode_s; 83 84 struct mqnotify { 85 pid_t pid; 86 struct sigevent notify; 87 }; 88 89 /* TYPE DEFINITIONS */ 90 struct mqarray { 91 UINT32 mq_id : 31; 92 UINT32 unlinkflag : 1; 93 char *mq_name; 94 UINT32 unlink_ref; 95 mode_s mode_data; /* mode data of mqueue */ 96 uid_t euid; /* euid of mqueue */ 97 gid_t egid; /* egid of mqueue */ 98 struct mqnotify mq_notify; 99 LosQueueCB *mqcb; 100 struct mqpersonal *mq_personal; 101 }; 102 103 struct mqpersonal { 104 struct mqarray *mq_posixdes; 105 struct mqpersonal *mq_next; 106 int mq_flags; 107 int mq_mode; /* Mode of mqueue */ 108 UINT32 mq_status; 109 UINT32 mq_refcount; 110 }; 111 112 /** 113 * @ingroup mqueue 114 * Message queue attribute structure 115 */ 116 struct mq_attr { 117 long mq_flags; /**< Message queue flags */ 118 long mq_maxmsg; /**< Maximum number of messages */ 119 long mq_msgsize; /**< Maximum size of a message */ 120 long mq_curmsgs; /**< Number of messages in the current message queue */ 121 }; 122 123 /** 124 * @ingroup mqueue 125 * Handle type of a message queue 126 */ 127 typedef UINTPTR mqd_t; 128 129 /** 130 * @ingroup mqueue 131 * 132 * @par Description: 133 * This API is used to open an existed message queue that has a specified name or create a new message queue. 134 * @attention 135 * <ul> 136 * <li>A message queue does not restrict the read and write permissions.</li> 137 * <li>The length of mqueue name must less than 256.</li> 138 * <li>This operation and closed mqueue scheduling must be used in coordination to release the resource.</li> 139 * <li>The parameter "mode" is not supported.</li> 140 * <li>The "mq_curmsgs" member of the mq_attr structure is not supported.</li> 141 * </ul> 142 * 143 * @param mqName [IN] Message queue name. 144 * @param openFlag [IN] Permission attributes of the message queue. The value range is 145 * [O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NONBLOCK]. 146 * @param mode [IN] Message queue mode (variadic argument). When oflag is O_CREAT, it requires 147 * two additional arguments: mode, which shall be of type mode_t, and attr, 148 * which shall be a pointer to an mq_attr structure. 149 * @param attr [IN] Message queue attribute (variadic argument). 150 * 151 * @retval mqd_t The message queue is successfully opened or created. 152 * @retval (mqd_t)-1 The message queue fails to be opened or created, with any of the following error codes in errno. 153 * 154 * 155 * @par Errors 156 * <ul> 157 * <li><b>ENOENT</b>: O_CREAT flag is not set for oflag, and the message queue specified by name does not exist.</li> 158 * <li><b>EEXIST</b>: Both O_CREAT and O_EXCL are set for oflag, but the message queue 159 * specified by name already exists.</li> 160 * <li><b>EINVAL</b>: invalid parameter.</li> 161 * <li><b>ENFILE</b>: The number of opened message queues exceeds the maximum limit.</li> 162 * <li><b>ENOSPC</b>: insufficient memory.</li> 163 * <li><b>ENAMETOOLONG</b>: The message queue name specified by name is too long.</li> 164 * </ul> 165 * 166 * @par Dependency: 167 * <ul><li>mqueue.h</li></ul> 168 * @see mq_close 169 */ 170 extern mqd_t mq_open(const char *mqName, int openFlag, ...); 171 172 /** 173 * @ingroup mqueue 174 * 175 * @par Description: 176 * This API is used to close a message queue that has a specified descriptor. 177 * @attention 178 * <ul> 179 * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_unlink is called.</li> 180 * </ul> 181 * 182 * @param personal [IN] Message queue descriptor. 183 * 184 * @retval 0 The message queue is successfully closed. 185 * @retval -1 The message queue fails to be closed, with either of the following error codes in errno. 186 * 187 * @par Errors 188 * <ul> 189 * <li><b>EBADF</b>: Invalid message queue descriptor.</li> 190 * <li><b>EAGAIN</b>: Failed to delete the message queue.</li> 191 * <li><b>EFAULT</b>: Failed to free the message queue.</li> 192 * <li><b>EINVAL</b>: Invalid parameter.</li> 193 * </ul> 194 * 195 * @par Dependency: 196 * <ul><li>mqueue.h</li></ul> 197 * @see mq_open 198 */ 199 extern int mq_close(mqd_t personal); 200 201 /** 202 * @ingroup mqueue 203 * 204 * @par Description: 205 * This API is used to remove a message queue that has a specified name. 206 * @attention 207 * <ul> 208 * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_close is called.</li> 209 * <li> The length of mqueue name must less than 256.</li> 210 * </ul> 211 * 212 * @param mqName [IN] Message queue name. 213 * 214 * @retval 0 The message queue is successfully removed. 215 * @retval -1 The message queue fails to be removed, with any of the following error codes in errno. 216 * 217 * @par Errors 218 * <ul> 219 * <li><b>ENOENT</b>: The message queue specified by name does not exist.</li> 220 * <li><b>EAGAIN</b>: Failed to delete the message queue.</li> 221 * <li><b>EBUSY</b>: The message queue to be removed is being used.</li> 222 * <li><b>EINVAL</b>: Invalid parameter.</li> 223 * <li><b>ENAMETOOLONG</b>: The name of mqueue is too long.</li> 224 * </ul> 225 * 226 * @par Dependency: 227 * <ul><li>mqueue.h</li></ul> 228 * @see mq_close 229 */ 230 extern int mq_unlink(const char *mqName); 231 232 /** 233 * @ingroup mqueue 234 * 235 * @par Description: 236 * This API is used to put a message with specified message content and length into 237 * a message queue that has a specified descriptor. 238 * @attention 239 * <ul> 240 * <li> Priority-based message processing is not supported.</li> 241 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 242 * </ul> 243 * 244 * @param personal [IN] Message queue descriptor. 245 * @param msg [IN] Pointer to the message content to be sent. 246 * @param msgLen [IN] Length of the message to be sent. 247 * @param msgPrio [IN] Priority of the message to be sent (the value of this parameter must 248 * be 0 because priority-based message sending is not supported. If the 249 * value is not 0, this API will cease to work.) 250 * 251 * @retval 0 The message is successfully sent. 252 * @retval -1 The message fails to be sent, with any of the following error codes in errno. 253 * 254 * @par Errors 255 * <ul> 256 * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li> 257 * <li><b>EBADF</b>: The message queue is invalid or not writable.</li> 258 * <li><b>EAGAIN</b>: The message queue is full.</li> 259 * <li><b>EINVAL</b>: Invalid parameter.</li> 260 * <li><b>ENOSPC</b>: Insufficient memory.</li> 261 * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li> 262 * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li> 263 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 264 * </ul> 265 * 266 * @par Dependency: 267 * <ul><li>mqueue.h</li></ul> 268 * @see mq_receive 269 */ 270 extern int mq_send(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio); 271 272 /** 273 * @ingroup mqueue 274 * 275 * @par Description: 276 * This API is used to remove the oldest message from the message queue that has a specified descriptor, 277 * and puts it in the buffer pointed to by msg_ptr. 278 * @attention 279 * <ul> 280 * <li> Priority-based message processing is not supported.</li> 281 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 282 * </ul> 283 * 284 * @param personal [IN] Message queue descriptor. 285 * @param msg [IN] Pointer to the message content to be received. 286 * @param msgLen [IN] Length of the message to be received. 287 * @param msgPrio [OUT] Priority of the message to be received 288 * because priority-based message processing is not supported, this parameter is useless). 289 * 290 * @retval 0 The message is successfully received. 291 * @retval -1 The message fails to be received, with any of the following error codes in the errno. 292 * 293 * @par Errors 294 * <ul> 295 * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li> 296 * <li><b>EBADF</b>: The message queue is invalid or not readable.</li> 297 * <li><b>EAGAIN</b>: The message queue is empty.</li> 298 * <li><b>EINVAL</b>: invalid parameter.</li> 299 * <li><b>EMSGSIZE</b>: The message to be received is too long.</li> 300 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 301 * </ul> 302 * 303 * @par Dependency: 304 * <ul><li>mqueue.h</li></ul> 305 * @see mq_send 306 */ 307 extern ssize_t mq_receive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio); 308 309 /** 310 * @ingroup mqueue 311 * 312 * @par Description: 313 * This API is used to obtain or modify attributes of the message queue that has a specified descriptor. 314 * @attention 315 * <ul> 316 * <li> The mq_maxmsg, mq_msgsize, and mq_curmsgs attributes are not modified 317 * in the message queue attribute setting.</li> 318 * </ul> 319 * 320 * @param personal [IN] Message queue descriptor. 321 * @param mqSetAttr [IN] New attribute of the message queue. 322 * @param MqOldAttr [OUT] Old attribute of the message queue. 323 * 324 * @retval 0 The message queue attributes are successfully set or get. 325 * @retval -1 The message queue attributes fail to be set or get, 326 * with either of the following error codes in the errno. 327 * 328 * @par Errors 329 * <ul> 330 * <li><b>EBADF</b>: Invalid message queue.</li> 331 * <li><b>EINVAL</b>: Invalid parameter.</li> 332 * </ul> 333 * 334 * @par Dependency: 335 * <ul><li>mqueue.h</li></ul> 336 * @see sys_mq_getsetattr 337 */ 338 extern int mq_getsetattr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *MqOldAttr); 339 340 /** 341 * @ingroup mqueue 342 * 343 * @par Description: 344 * This API is used to put a message with specified message content and length into 345 * a message queue that has a descriptor at a scheduled time. 346 * @attention 347 * <ul> 348 * <li> Priority-based message processing is not supported.</li> 349 * <li> The expiry time must be later than the current time.</li> 350 * <li> The wait time is a relative time.</li> 351 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 352 * </ul> 353 * 354 * @param mqdes [IN] Message queue descriptor. 355 * @param msg [IN] Pointer to the message content to be sent. 356 * @param msgLen [IN] Length of the message to be sent. 357 * @param msgPrio [IN] Priority of the message to be sent (the value of this parameter must be 0 358 * because priority-based message processing is not supported). 359 * @param absTimeout [IN] Scheduled time at which the message will be sent. If the value is 0, 360 * the message is an instant message. 361 * 362 * @retval 0 The message is successfully sent. 363 * @retval -1 The message fails to be sent, with any of the following error codes in errno. 364 * 365 * @par Errors 366 * <ul> 367 * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li> 368 * <li><b>EBADF</b>: The message queue is invalid or not writable.</li> 369 * <li><b>EAGAIN</b>: The message queue is full.</li> 370 * <li><b>EINVAL</b>: Invalid parameter.</li> 371 * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li> 372 * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li> 373 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 374 * </ul> 375 * 376 * @par Dependency: 377 * <ul><li>mqueue.h</li></ul> 378 * @see mq_receive 379 */ 380 extern int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, 381 unsigned int msgPrio, const struct timespec *absTimeout); 382 383 /** 384 * @ingroup mqueue 385 * 386 * @par Description: 387 * This API is used to obtain a message with specified message content and length from 388 * a message queue message that has a specified descriptor. 389 * @attention 390 * <ul> 391 * <li> Priority-based message processing is not supported.</li> 392 * <li> The expiry time must be later than the current time.</li> 393 * <li> The wait time is a relative time.</li> 394 * <li> The msg_len should be same to the length of string which msg_ptr point to.</li> 395 * </ul> 396 * 397 * @param personal [IN] Message queue descriptor. 398 * @param msg [IN] Pointer to the message content to be received. 399 * @param msgLen [IN] Length of the message to be received. 400 * @param msgPrio [OUT] Priority of the message to be received (because priority-based message 401 * processing is not supported, this parameter is useless ). 402 * @param absTimeout [IN] Scheduled time at which the messagewill be received. If the value is 0, 403 * the message is an instant message. 404 * 405 * @retval 0 The message is successfully received. 406 * @retval -1 The message fails to be received, with any of the following error codes in errno. 407 * 408 * @par Errors 409 * <ul> 410 * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li> 411 * <li><b>EBADF</b>: The message queue is invalid or not readable.</li> 412 * <li><b>EAGAIN</b>: The message queue is empty.</li> 413 * <li><b>EINVAL</b>: invalid parameter.</li> 414 * <li><b>EMSGSIZE</b>: The message to be received is too long.</li> 415 * <li><b>ETIMEDOUT</b>: The operation times out.</li> 416 * </ul> 417 * 418 * @par Dependency: 419 * <ul><li>mqueue.h</li></ul> 420 * @see mq_send 421 */ 422 extern ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, 423 unsigned int *msgPrio, const struct timespec *absTimeout); 424 425 extern void MqueueRefer(int sysFd); 426 extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev); 427 428 #ifdef __cplusplus 429 #if __cplusplus 430 } 431 #endif /* __cplusplus */ 432 #endif /* __cplusplus */ 433 434 #endif 435