From patchwork Fri Sep 8 17:49:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert ARIBAUD X-Patchwork-Id: 22766 Received: (qmail 120349 invoked by alias); 8 Sep 2017 17:49:28 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 120331 invoked by uid 89); 8 Sep 2017 17:49:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy= X-HELO: smtp6-g21.free.fr From: "Albert ARIBAUD (3ADEV)" To: libc-alpha@sourceware.org Cc: "Albert ARIBAUD (3ADEV)" Subject: [RFC PATCH 50/52] Y2038: add function select Date: Fri, 8 Sep 2017 19:49:07 +0200 Message-Id: <20170908174909.28192-1-albert.aribaud@3adev.fr> In-Reply-To: <20170907224219.12483-50-albert.aribaud@3adev.fr> References: <20170907224219.12483-50-albert.aribaud@3adev.fr> Signed-off-by: Albert ARIBAUD (3ADEV) --- include/sys/select.h | 5 +++ sysdeps/unix/sysv/linux/select.c | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/include/sys/select.h b/include/sys/select.h index 3eb76faf9d..df10085e72 100644 --- a/include/sys/select.h +++ b/include/sys/select.h @@ -24,5 +24,10 @@ extern int __pselect_t64 (int __nfds, fd_set *__readfds, const struct __timespec64 *__timeout, const __sigset_t *__sigmask); +extern int __select_t64 (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, + struct __timeval64 *__restrict __timeout); + #endif #endif diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c index be4a456a51..3e6140621c 100644 --- a/sysdeps/unix/sysv/linux/select.c +++ b/sysdeps/unix/sysv/linux/select.c @@ -33,6 +33,8 @@ # define __NR_select __NR__newselect #endif +extern int __y2038_linux_support; + int __select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) @@ -69,3 +71,67 @@ libc_hidden_def (__select) weak_alias (__select, select) weak_alias (__select, __libc_select) + +/* 64-bit time version */ + +extern int __y2038_linux_support; + +int +__select_t64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct __timeval64 *timeout) +{ + struct timeval tval32, *timeout32 = NULL; +#ifndef __NR_select + int result; + struct timespec ts32, *tsp32 = NULL; +#endif + + if (__y2038_linux_support) + { + /* TODO: implement using Linux kernel system call */ + } + + if (timeout != NULL) + { + if (timeout->tv_sec > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } + tval32.tv_sec = timeout->tv_sec; + tval32.tv_usec = timeout->tv_usec; + timeout32 = &tval32; + } + +#ifdef __NR_select + return SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, + timeout32); +#else + if (timeout) + { + if (timeout->tv_sec > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } + ts32.tv_sec = timeout->tv_sec; + ts32.tv_nsec = timeout->tv_usec * 1000; + tsp32 = &ts32; + } + + result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp32, + NULL); + + if (timeout) + { + /* Linux by default will update the timeout after a pselect6 syscall + (though the pselect() glibc call suppresses this behavior). + Since select() on Linux has the same behavior as the pselect6 + syscall, we update the timeout here. */ + timeout->tv_sec = ts32.tv_sec; + timeout->tv_usec = ts32.tv_nsec / 1000; + } + + return result; +#endif +}