| 1 | /* Receive a message from a message queue with a timeout.  Linux version. | 
| 2 |    Copyright (C) 2017-2021 Free Software Foundation, Inc. | 
| 3 |    This file is part of the GNU C Library. | 
| 4 |  | 
| 5 |    The GNU C Library is free software; you can redistribute it and/or | 
| 6 |    modify it under the terms of the GNU Lesser General Public | 
| 7 |    License as published by the Free Software Foundation; either | 
| 8 |    version 2.1 of the License, or (at your option) any later version. | 
| 9 |  | 
| 10 |    The GNU C Library is distributed in the hope that it will be useful, | 
| 11 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 12 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| 13 |    Lesser General Public License for more details. | 
| 14 |  | 
| 15 |    You should have received a copy of the GNU Lesser General Public | 
| 16 |    License along with the GNU C Library; if not, see | 
| 17 |    <https://www.gnu.org/licenses/>.  */ | 
| 18 |  | 
| 19 | #include <mqueue.h> | 
| 20 | #include <sysdep-cancel.h> | 
| 21 | #include <shlib-compat.h> | 
| 22 |  | 
| 23 | /* Receive the oldest from highest priority messages in message queue | 
| 24 |    MQDES, stop waiting if ABS_TIMEOUT expires.  */ | 
| 25 | ssize_t | 
| 26 | ___mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len, | 
| 27 |                           unsigned int *__restrict msg_prio, | 
| 28 |                           const struct __timespec64 *__restrict abs_timeout) | 
| 29 | { | 
| 30 | #ifndef __NR_mq_timedreceive_time64 | 
| 31 | # define __NR_mq_timedreceive_time64 __NR_mq_timedreceive | 
| 32 | #endif | 
| 33 |  | 
| 34 | #ifdef __ASSUME_TIME64_SYSCALLS | 
| 35 |   return SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len, | 
| 36 | 			 msg_prio, abs_timeout); | 
| 37 | #else | 
| 38 |   bool need_time64 = abs_timeout != NULL | 
| 39 | 		     && !in_time_t_range (abs_timeout->tv_sec); | 
| 40 |   if (need_time64) | 
| 41 |     { | 
| 42 |       int r = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len, | 
| 43 | 			      msg_prio, abs_timeout); | 
| 44 |       if (r == 0 || errno != ENOSYS) | 
| 45 | 	return r; | 
| 46 |       __set_errno (EOVERFLOW); | 
| 47 |       return -1; | 
| 48 |     } | 
| 49 |  | 
| 50 |   struct timespec ts32, *pts32 = NULL; | 
| 51 |   if (abs_timeout != NULL) | 
| 52 |     { | 
| 53 |       ts32 = valid_timespec64_to_timespec (*abs_timeout); | 
| 54 |       pts32 = &ts32; | 
| 55 |     } | 
| 56 |  | 
| 57 |   return SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio, | 
| 58 | 			 pts32); | 
| 59 | #endif | 
| 60 | } | 
| 61 |  | 
| 62 | #if __TIMESIZE == 64 | 
| 63 | versioned_symbol (libc, ___mq_timedreceive_time64, mq_timedreceive, GLIBC_2_34); | 
| 64 | libc_hidden_ver (___mq_timedreceive_time64, __mq_timedreceive) | 
| 65 | # ifndef SHARED | 
| 66 | strong_alias (___mq_timedreceive_time64, __mq_timedreceive) | 
| 67 | # endif | 
| 68 | # if OTHER_SHLIB_COMPAT (librt, GLIBC_2_3_4, GLIBC_2_34) | 
| 69 | compat_symbol (librt, ___mq_timedreceive_time64, mq_timedreceive, GLIBC_2_3_4); | 
| 70 | # endif | 
| 71 |  | 
| 72 | #else /* __TIMESIZE != 64 */ | 
| 73 | libc_hidden_ver (___mq_timedreceive_time64, __mq_timedreceive_time64) | 
| 74 | versioned_symbol (libc, ___mq_timedreceive_time64, __mq_timedreceive_time64, | 
| 75 | 		  GLIBC_2_34); | 
| 76 |  | 
| 77 | ssize_t | 
| 78 | ___mq_timedreceive (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len, | 
| 79 | 		    unsigned int *__restrict msg_prio, | 
| 80 | 		    const struct timespec *__restrict abs_timeout) | 
| 81 | { | 
| 82 |   struct __timespec64 ts64; | 
| 83 |   if (abs_timeout != NULL) | 
| 84 |     ts64 = valid_timespec_to_timespec64 (*abs_timeout); | 
| 85 |  | 
| 86 |   return __mq_timedreceive_time64 (mqdes, msg_ptr, msg_len, msg_prio, | 
| 87 |                                    abs_timeout != NULL ? &ts64 : NULL); | 
| 88 | } | 
| 89 | versioned_symbol (libc, ___mq_timedreceive, mq_timedreceive, GLIBC_2_34); | 
| 90 | libc_hidden_ver (___mq_timedreceive, __mq_timedreceive) | 
| 91 | # ifndef SHARED | 
| 92 | strong_alias (___mq_timedreceive, __mq_timedreceive) | 
| 93 | # endif | 
| 94 | # if OTHER_SHLIB_COMPAT (librt, GLIBC_2_3_4, GLIBC_2_34) | 
| 95 | compat_symbol (librt, ___mq_timedreceive, mq_timedreceive, GLIBC_2_3_4); | 
| 96 | # endif | 
| 97 |  | 
| 98 | #endif /* __TIMESIZE != 64 */ | 
| 99 |  |