From patchwork Fri Sep 6 14:59:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1159055 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-105081-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="w18s/x4h"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Q11n30Cnz9s3Z for ; Sat, 7 Sep 2019 00:59:57 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=o2DyLp+xTkP9aZKXUlG16COQmsEh+W3 dlcDE45VuISPxXkDkoVMQJrHmzIUfIdFMzMxDERN77KQA0+Lt6jfjuiC/Zm61clP bs2X84KC0LNt91XHCHEnftCwMk5/ZsvgwBJJUlZOkSSdMtirsi7aOeDlNLdC5RCQ EAI4h2OffL2E= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=Z/Dg4szwdeoVGHu+7poOp9oyA/g=; b=w18s/ x4hG99QQ/mXH6PSNGo5iwyFBJVh17XOH402pTMHVlvpQshGnGTXHjAzQIyUlblPX xgXvMNNUp5h2r+Vvi2O4z3No6qb1AkBi6ZFKYXkGcSsSeTWFd1NMdSXbNIjm26sw n4KQYAbwwSUfePBAC3Z92BOfIYpl7pzTpu53rM= Received: (qmail 64660 invoked by alias); 6 Sep 2019 14:59:38 -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 64593 invoked by uid 89); 6 Sep 2019 14:59:38 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 spammy=misleading X-HELO: mail-out.m-online.net From: Lukasz Majewski To: Joseph Myers , Zack Weinberg Cc: Alistair Francis , Arnd Bergmann , Alistair Francis , GNU C Library , Adhemerval Zanella , Florian Weimer , Carlos O'Donell , Stepan Golosunov , Lukasz Majewski Subject: [PATCH v7 2/3] y2038: Provide conversion helpers for struct __timespec64 Date: Fri, 6 Sep 2019 16:59:10 +0200 Message-Id: <20190906145911.30207-3-lukma@denx.de> In-Reply-To: <20190906145911.30207-1-lukma@denx.de> References: <20190906145911.30207-1-lukma@denx.de> Those functions allow easy conversion between Y2038 safe struct __timespec64 and other time related data structures (like struct timeval). * 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. --- Changes for v7: - None Changes for v6: - Remove the #ifdef guard on __ASSUME_TIME64_SYSCALLS as those functions may be needed for fallback execution paths (on e.g. __clock_settime64). Changes for v5: - This code is now only compiled in when __ASSUME_TIME64_SYSCALLS is NOT defined. Previously it was depending on #if __TIMESIZE != 64. Changes for v4: - None Changes for v3: - Remove misleading comments regarding clearing tv_pad values during conversion (as Linux kernel on its own ignores upper 32 bits of tv_nsec). Changes for v3: - Remove timespec64_clear_padding function - as kernel ignores upper 32 bits of tv_nsec when passed via syscall to the Linux kernel Changes for v2: - Add timespec64_clear_padding function --- include/time.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/include/time.h b/include/time.h index 862d29b8f7..7f9d917b5b 100644 --- a/include/time.h +++ b/include/time.h @@ -179,5 +179,88 @@ in_time_t_range (__time64_t t) return s == t; } +/* 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