From patchwork Tue Jun 25 00:08:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 33371 Received: (qmail 17480 invoked by alias); 25 Jun 2019 00:11:22 -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 17421 invoked by uid 89); 25 Jun 2019 00:11:22 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT autolearn=ham version=3.3.1 spammy=lies X-HELO: esa4.hgst.iphmx.com DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1561421481; x=1592957481; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=27MmCYdwHuqFDdi/PTlCfE34+OdgWxHXj0f/B8GoTFM=; b=gt32IPFkDXWlAh8g1bOs+LYynXf9s5gBONY8YTYIP+IMq6LmvE1Pzvvf ORgZBdt70zLbwt2UobchddLt3MCnJjrBQsBJcTSWaCCf9KTW8qMKCrOqR C/qgm4ftjIPLb/WiGmF1qBUq0kA0j2TmtqVqqtrZ6VrYoBkDICQYdsckt HKfzrz/vbGVx+Ama/YNnbfzp1CoORPCgmONZkN2EKGL+OTdmhGfOE0ERf oBpOSVOQ9NzspgXmlK3GBUejNxTDmRGMdark1YXhW9ei7fAj8xcIUpj+p sv5l3lucPshQjDIDP/BuIv5GxfHP8CAgkMRRZTGKcFBLmqddVjeCq6mL/ Q==; IronPort-SDR: whGIo/T7Qtk9wn0OEAGlOXiuSrdYv1yyPTjammQ+SUDVQx3tm/TeyFxsd3GZzM4qf40RHQ9cp2 9EuLaTKbMArUwz7iEGUwAkyUsddje90jL5zZkdFvWUjsTQ5eTqrw5m4k4vnP4BG2eMCcKxovGk 4SYHahuVvLE3G3G14rY+3lr8wTN+DmJkzuVGnOG6ynTv/zqd8UFzoj2UB4HwR6xnmi+wkjRIlq qk0TKdzBmy2JWaTj681fZQvtpA/ysRLnFDlop8RW60pbzJYx7ejyXtpyXdNQQIlvhkOHx7S9hM iyunpk3VO3JxLF2tDeR7oZC8 IronPort-SDR: CkeKgly+DWckstWaPdB1o4HnKoiN+X09aHiY/ZQhPqnDPX8CEFJKkHc/CGwMEF4QxSAFTvD/TS JZNhuvOvWXrTdrCd+nl0TX1RrlJLRRzg5esHMF06QDZFnzvLCHMWOuCEEIZTQlqJpki/5COFqR xJO5OKuuF+tdSqE1Dpav/vrqAOST2ax7fFd2IvuL/Yyv76GvCJdBkvoEAetPtevo5Jmaq7fxo2 P7HgXHkLSQgMrFo8x+yJykZSA/zVWuqnaPCd5AKr7WR25onMLeDkgZ6WzRNU9U/xyNmEFcNtfo rVM= From: Alistair Francis To: libc-alpha@sourceware.org Cc: arnd@arndb.de, adhemerval.zanella@linaro.org, fweimer@redhat.com, palmer@sifive.com, macro@wdc.com, zongbox@gmail.com, zong@andestech.com, alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v2 02/20] y2038: Provide conversion helpers for struct __timespec64 Date: Mon, 24 Jun 2019 17:08:49 -0700 Message-Id: In-Reply-To: References: MIME-Version: 1.0 From: Lukasz Majewski Those functions allow easy conversion between Y2038 safe struct __timespec64 and other time related data structures (like struct timeval). Moreover, those functions are NOT compiled when 64 bit time support is enabled (i.e. the __ASSUME_TIME64_SYSCALLS is defined) and are used only in 32 bit wrappers (like e.g. __clock_settime()). * include/time.h (valid_timeval_to_timespec64): Add. * include/time.h (valid_timespec_to_timespec64): Likewise. * include/time.h (valid_timespec64_to_timespec): Likewise. * include/time.h (valid_timespec64_to_timeval): Likewise. * include/time.h (IS_VALID_NANOSECONDS): Likewise. * include/time.h (timespec_to_timespec64): Likewise. * include/time.h (timespec64_to_timespec): Likewise. * include/time.h (timespec64_to_timeval): Likewise. --- include/time.h | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/include/time.h b/include/time.h index 33d0fcb0fe..1b38d019c8 100644 --- a/include/time.h +++ b/include/time.h @@ -181,5 +181,90 @@ in_time_t_range (__time64_t t) return s == t; } +# ifndef __ASSUME_TIME64_SYSCALLS +/* Convert a known valid struct timeval into a struct __timespec64. */ +static inline void +valid_timeval_to_timespec64 (const struct timeval *tv32, + struct __timespec64 *ts64) +{ + ts64->tv_sec = tv32->tv_sec; + ts64->tv_nsec = tv32->tv_usec * 1000; +} + +/* Convert a known valid struct timespec into a struct __timespec64. */ +static inline void +valid_timespec_to_timespec64 (const struct timespec *ts32, + struct __timespec64 *ts64) +{ + ts64->tv_sec = ts32->tv_sec; + ts64->tv_nsec = ts32->tv_nsec; +} + +/* Convert a known valid struct __timespec64 into a struct timespec. */ +static inline void +valid_timespec64_to_timespec (const struct __timespec64 *ts64, + struct timespec *ts32) +{ + ts32->tv_sec = (time_t) ts64->tv_sec; + ts32->tv_nsec = ts64->tv_nsec; +} + +/* Convert a known valid struct __timespec64 into a struct timeval. */ +static inline void +valid_timespec64_to_timeval (const struct __timespec64 *ts64, + struct timeval *tv32) +{ + tv32->tv_sec = (time_t) ts64->tv_sec; + tv32->tv_usec = ts64->tv_nsec / 1000; +} + +/* Check if a value lies with the valid nanoseconds range. */ +#define IS_VALID_NANOSECONDS(ns) ((ns) >= 0 && (ns) <= 999999999) + +/* Check and convert a struct timespec into a struct __timespec64. */ +static inline bool +timespec_to_timespec64 (const struct timespec *ts32, + struct __timespec64 *ts64) +{ + /* Check that ts32 holds a valid count of nanoseconds. */ + if (! IS_VALID_NANOSECONDS (ts32->tv_nsec)) + return false; + /* All ts32 fields can fit in ts64, so copy them. */ + valid_timespec_to_timespec64 (ts32, ts64); + return true; +} + +/* Check and convert a struct __timespec64 into a struct timespec. */ +static inline bool +timespec64_to_timespec (const struct __timespec64 *ts64, + struct timespec *ts32) +{ + /* Check that tv_nsec holds a valid count of nanoseconds. */ + if (! IS_VALID_NANOSECONDS (ts64->tv_nsec)) + return false; + /* Check that tv_sec can fit in a __time_t. */ + if (! in_time_t_range (ts64->tv_sec)) + return false; + /* All ts64 fields can fit in ts32, so copy them. */ + valid_timespec64_to_timespec (ts64, ts32); + return true; +} + +/* Check and convert a struct __timespec64 into a struct timeval. */ +static inline bool +timespec64_to_timeval (const struct __timespec64 *ts64, + struct timeval *tv32) +{ + /* Check that tv_nsec holds a valid count of nanoseconds. */ + if (! IS_VALID_NANOSECONDS (ts64->tv_nsec)) + return false; + /* Check that tv_sec can fit in a __time_t. */ + if (! in_time_t_range (ts64->tv_sec)) + return false; + /* All ts64 fields can fit in tv32, so copy them. */ + valid_timespec64_to_timeval (ts64, tv32); + return true; +} +# endif #endif #endif