Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/811197/?format=api
{ "id": 811197, "url": "http://patchwork.ozlabs.org/api/patches/811197/?format=api", "web_url": "http://patchwork.ozlabs.org/project/glibc/patch/20170907224219.12483-4-albert.aribaud@3adev.fr/", "project": { "id": 41, "url": "http://patchwork.ozlabs.org/api/projects/41/?format=api", "name": "GNU C Library", "link_name": "glibc", "list_id": "libc-alpha.sourceware.org", "list_email": "libc-alpha@sourceware.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20170907224219.12483-4-albert.aribaud@3adev.fr>", "list_archive_url": null, "date": "2017-09-07T22:41:30", "name": "[RFC,03/52] Y2038: add functions using struct tm", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "bc0dd56f471b1dadf22bd66122a2edefa338a47d", "submitter": { "id": 65557, "url": "http://patchwork.ozlabs.org/api/people/65557/?format=api", "name": "Albert ARIBAUD (3ADEV)", "email": "albert.aribaud@3adev.fr" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/glibc/patch/20170907224219.12483-4-albert.aribaud@3adev.fr/mbox/", "series": [ { "id": 2074, "url": "http://patchwork.ozlabs.org/api/series/2074/?format=api", "web_url": "http://patchwork.ozlabs.org/project/glibc/list/?series=2074", "date": "2017-09-07T22:41:27", "name": "Make GLIBC Y2038-proof", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/2074/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/811197/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/811197/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<libc-alpha-return-84321-incoming=patchwork.ozlabs.org@sourceware.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "mailing list libc-alpha@sourceware.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=sourceware.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=libc-alpha-return-84321-incoming=patchwork.ozlabs.org@sourceware.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dkim=pass (1024-bit key;\n\tsecure) header.d=sourceware.org header.i=@sourceware.org\n\theader.b=\"O0PXN/wd\"; dkim-atps=neutral", "sourceware.org; auth=none" ], "Received": [ "from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xpFpf2Pxbz9sCZ\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 8 Sep 2017 08:43:06 +1000 (AEST)", "(qmail 59252 invoked by alias); 7 Sep 2017 22:42:44 -0000", "(qmail 59109 invoked by uid 89); 7 Sep 2017 22:42:44 -0000" ], "DomainKey-Signature": "a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:from:to:cc:subject:date:message-id:in-reply-to\n\t:references; q=dns; s=default; b=DA/r7u1vgK0JvFzbMj2y2XB1vCqc//l\n\tMV2/hyMTYpkN3jPG/mMH2mKB+oBeZi+lF+o9pwwgjSwM1QydAWCHFKh6z634ZHak\n\tblkF5uy9ug4vzQVVRyjeGNd+dlrdJONmIm0vFLeJmH9Rf5vkyDFdhqwCYJhAuekI\n\tRWWj87rKFMpI=", "DKIM-Signature": "v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:from:to:cc:subject:date:message-id:in-reply-to\n\t:references; s=default; bh=enql6Ra+WyRz4G9DEfnkDSfI3Ck=; b=O0PXN\n\t/wd/cYbFA6DvsmwWazaQ2iZJTnCqmn3Na1bnkxlKXl8g8UhZBz7nXDTckvpVs3rL\n\tUQP86lI+05AxsJFSgCZBIzRTTkkQ68axnXFWBZoQJyz82YEitnkQn6Thn40Sufpy\n\tQmO9foTx4SI9pvgypfvB1QdD3Hh0iZ54AJvUsw=", "Mailing-List": "contact libc-alpha-help@sourceware.org; run by ezmlm", "Precedence": "bulk", "List-Id": "<libc-alpha.sourceware.org>", "List-Unsubscribe": "<mailto:libc-alpha-unsubscribe-incoming=patchwork.ozlabs.org@sourceware.org>", "List-Subscribe": "<mailto:libc-alpha-subscribe@sourceware.org>", "List-Archive": "<http://sourceware.org/ml/libc-alpha/>", "List-Post": "<mailto:libc-alpha@sourceware.org>", "List-Help": "<mailto:libc-alpha-help@sourceware.org>,\n\t<http://sourceware.org/ml/#faqs>", "Sender": "libc-alpha-owner@sourceware.org", "X-Virus-Found": "No", "X-Spam-SWARE-Status": "No, score=-26.6 required=5.0 tests=BAYES_00, GIT_PATCH_0,\n\tGIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3,\n\tKAM_LAZY_DOMAIN_SECURITY,\n\tRCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=east,\n\tjanuary", "X-HELO": "smtp6-g21.free.fr", "From": "\"Albert ARIBAUD (3ADEV)\" <albert.aribaud@3adev.fr>", "To": "libc-alpha@sourceware.org", "Cc": "\"Albert ARIBAUD (3ADEV)\" <albert.aribaud@3adev.fr>", "Subject": "[RFC PATCH 03/52] Y2038: add functions using struct tm", "Date": "Fri, 8 Sep 2017 00:41:30 +0200", "Message-Id": "<20170907224219.12483-4-albert.aribaud@3adev.fr>", "In-Reply-To": "<20170907224219.12483-3-albert.aribaud@3adev.fr>", "References": "<20170907224219.12483-1-albert.aribaud@3adev.fr>\n\t<20170907224219.12483-2-albert.aribaud@3adev.fr>\n\t<20170907224219.12483-3-albert.aribaud@3adev.fr>" }, "content": "This consists in the following implementation additions:\n\n([file] 32-bit implementation -> [file] 64-bit addition)\n\ntime/ctime.c ctime() -> __ctime64()\ntime/ctime_r.c ctime_r() -> __ctime64_r()\ntime/gmtime.c gmtime() -> __gmtime64()\ntime/gmtime.c gmtime_r() -> __gmtime64_r()\ntime/localtime.c localtime() -> __localtime64()\ntime/localtime.c localtime_r() -> __localtime64_r()\n\nwhich require the following internal function additions\n\ntime/offtime.c __offtime() -> __offtime64()\ntime/tzset.c __tz_convert() -> __tz64_convert()\n\nand internal function (32-bit-time-compatible) changes\n\ntime/tzfile.c __tzfile_compute()\ntime/tzset.c tzset_internal()\ntime/tzset.c compute_change()\n\nSigned-off-by: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>\n---\n include/time.h | 26 ++++++++++++---\n sysdeps/unix/sysv/linux/arm/Versions | 3 ++\n time/ctime.c | 10 ++++++\n time/ctime_r.c | 9 +++++\n time/gmtime.c | 15 +++++++++\n time/localtime.c | 17 ++++++++++\n time/offtime.c | 64 ++++++++++++++++++++++++++++++++++++\n time/tzfile.c | 4 +--\n time/tzset.c | 64 +++++++++++++++++++++++++++++++++---\n 9 files changed, 201 insertions(+), 11 deletions(-)", "diff": "diff --git a/include/time.h b/include/time.h\nindex 9956b82eb8..d2b1080fd6 100644\n--- a/include/time.h\n+++ b/include/time.h\n@@ -8,6 +8,8 @@ extern __typeof (strftime_l) __strftime_l;\n libc_hidden_proto (__strftime_l)\n extern __typeof (strptime_l) __strptime_l;\n \n+extern struct tm *__localtime64 (const __time64_t *__timer);\n+\n libc_hidden_proto (time)\n libc_hidden_proto (asctime)\n libc_hidden_proto (mktime)\n@@ -39,13 +41,13 @@ extern int __use_tzfile attribute_hidden;\n \n extern void __tzfile_read (const char *file, size_t extra,\n \t\t\t char **extrap);\n-extern void __tzfile_compute (time_t timer, int use_localtime,\n+extern void __tzfile_compute (__time64_t timer, int use_localtime,\n \t\t\t long int *leap_correct, int *leap_hit,\n \t\t\t struct tm *tp);\n extern void __tzfile_default (const char *std, const char *dst,\n \t\t\t long int stdoff, long int dstoff);\n extern void __tzset_parse_tz (const char *tz);\n-extern void __tz_compute (time_t timer, struct tm *tm, int use_localtime)\n+extern void __tz_compute (__time64_t timer, struct tm *tm, int use_localtime)\n __THROW internal_function;\n \n /* Subroutine of `mktime'. Return the `time_t' representation of TP and\n@@ -58,23 +60,37 @@ extern time_t __mktime_internal (struct tm *__tp,\n extern struct tm *__localtime_r (const time_t *__timer,\n \t\t\t\t struct tm *__tp) attribute_hidden;\n \n-extern struct tm *__gmtime_r (const time_t *__restrict __timer,\n+extern struct tm *__localtime64_r (const __time64_t *__timer,\n+\t\t\t\t struct tm *__tp) attribute_hidden;\n+\n+extern struct tm *__gmtime_r (const __time_t *__restrict __timer,\n \t\t\t struct tm *__restrict __tp);\n libc_hidden_proto (__gmtime_r)\n \n+extern struct tm *__gmtime64_r (const __time64_t *__restrict __timer,\n+\t\t\t struct tm *__restrict __tp);\n+\n /* Compute the `struct tm' representation of *T,\n offset OFFSET seconds east of UTC,\n and store year, yday, mon, mday, wday, hour, min, sec into *TP.\n Return nonzero if successful. */\n-extern int __offtime (const time_t *__timer,\n+extern int __offtime (const __time_t *__timer,\n \t\t long int __offset,\n \t\t struct tm *__tp);\n \n+extern int __offtime64 (const __time64_t *__timer,\n+\t\t long int __offset,\n+\t\t struct tm *__tp);\n+\n extern char *__asctime_r (const struct tm *__tp, char *__buf);\n extern void __tzset (void);\n \n /* Prototype for the internal function to get information based on TZ. */\n-extern struct tm *__tz_convert (const time_t *timer, int use_localtime, struct tm *tp);\n+extern struct tm *__tz_convert (const __time_t *timer, int use_localtime,\n+\t\t\t struct tm *tp);\n+\n+extern struct tm *__tz_convert64 (const __time64_t *timer,\n+\t\t\t\t int use_localtime, struct tm *tp);\n \n extern int __nanosleep (const struct timespec *__requested_time,\n \t\t\tstruct timespec *__remaining);\ndiff --git a/sysdeps/unix/sysv/linux/arm/Versions b/sysdeps/unix/sysv/linux/arm/Versions\nindex d3655768c8..dd6a160c75 100644\n--- a/sysdeps/unix/sysv/linux/arm/Versions\n+++ b/sysdeps/unix/sysv/linux/arm/Versions\n@@ -22,5 +22,8 @@ libc {\n \n GLIBC_Y2038 {\n __difftime64;\n+ __ctime64; __ctime64_r;\n+ __gmtime64; __gmtime64_r;\n+ __localtime64; __localtime64_r;\n }\n }\ndiff --git a/time/ctime.c b/time/ctime.c\nindex 7baca1bb57..a5150c1845 100644\n--- a/time/ctime.c\n+++ b/time/ctime.c\n@@ -26,3 +26,13 @@ ctime (const time_t *t)\n In particular, ctime and asctime must yield the same pointer. */\n return asctime (localtime (t));\n }\n+\n+/* Return a string as returned by asctime which\n+ is the representation of *T in that form. */\n+char *\n+__ctime64 (const __time64_t *t)\n+{\n+ /* Apply the same rule as ctime:\n+ make ctime64 (t) is equivalent to asctime (localtime64 (t)). */\n+ return asctime (__localtime64 (t));\n+}\ndiff --git a/time/ctime_r.c b/time/ctime_r.c\nindex ecd7731038..74d856f17e 100644\n--- a/time/ctime_r.c\n+++ b/time/ctime_r.c\n@@ -27,3 +27,12 @@ ctime_r (const time_t *t, char *buf)\n struct tm tm;\n return __asctime_r (__localtime_r (t, &tm), buf);\n }\n+\n+/* Return a string as returned by asctime which is the representation\n+ of *T in that form. Reentrant Y2038-proof version. */\n+char *\n+__ctime64_r (const __time64_t *t, char *buf)\n+{\n+ struct tm tm;\n+ return __asctime_r (__localtime64_r (t, &tm), buf);\n+}\ndiff --git a/time/gmtime.c b/time/gmtime.c\nindex 049d551cdf..7662c1d1f7 100644\n--- a/time/gmtime.c\n+++ b/time/gmtime.c\n@@ -35,3 +35,18 @@ gmtime (const time_t *t)\n {\n return __tz_convert (t, 0, &_tmbuf);\n }\n+\n+/* Return the `struct tm' representation of 64-bit-time *T\n+ in UTC, using *TP to store the result. */\n+struct tm *\n+__gmtime64_r (const __time64_t *t, struct tm *tp)\n+{\n+ return __tz_convert64 (t, 0, tp);\n+}\n+\n+/* Return the `struct tm' representation of 64-bit-time *T in UTC.\t*/\n+struct tm *\n+__gmtime64 (const __time64_t *t)\n+{\n+ return __tz_convert64 (t, 0, &_tmbuf);\n+}\ndiff --git a/time/localtime.c b/time/localtime.c\nindex 07dd67ca71..fd2d997e60 100644\n--- a/time/localtime.c\n+++ b/time/localtime.c\n@@ -39,3 +39,20 @@ localtime (const time_t *t)\n return __tz_convert (t, 1, &_tmbuf);\n }\n libc_hidden_def (localtime)\n+\n+/* 64-bit-time versions */\n+\n+/* Return the `struct tm' representation of *T in local time,\n+ using *TP to store the result. */\n+struct tm *\n+__localtime64_r (const __time64_t *t, struct tm *tp)\n+{\n+ return __tz_convert64 (t, 1, tp);\n+}\n+\n+/* Return the `struct tm' representation of *T in local time. */\n+struct tm *\n+__localtime64 (const __time64_t *t)\n+{\n+ return __tz_convert64 (t, 1, &_tmbuf);\n+}\ndiff --git a/time/offtime.c b/time/offtime.c\nindex 75a28fed84..84237db440 100644\n--- a/time/offtime.c\n+++ b/time/offtime.c\n@@ -84,3 +84,67 @@ __offtime (const time_t *t, long int offset, struct tm *tp)\n tp->tm_mday = days + 1;\n return 1;\n }\n+\n+/* Compute the `struct tm' representation of 64-bit-time *T,\n+ offset OFFSET seconds east of UTC,\n+ and store year, yday, mon, mday, wday, hour, min, sec into *TP.\n+ Return nonzero if successful. */\n+int\n+__offtime64 (const __time64_t *t, long int offset, struct tm *tp)\n+{\n+ __time64_t days, rem, y;\n+ const unsigned short int *ip;\n+\n+ days = *t / SECS_PER_DAY;\n+ rem = *t % SECS_PER_DAY;\n+ rem += offset;\n+ while (rem < 0)\n+ {\n+ rem += SECS_PER_DAY;\n+ --days;\n+ }\n+ while (rem >= SECS_PER_DAY)\n+ {\n+ rem -= SECS_PER_DAY;\n+ ++days;\n+ }\n+ tp->tm_hour = rem / SECS_PER_HOUR;\n+ rem %= SECS_PER_HOUR;\n+ tp->tm_min = rem / 60;\n+ tp->tm_sec = rem % 60;\n+ /* January 1, 1970 was a Thursday. */\n+ tp->tm_wday = (4 + days) % 7;\n+ if (tp->tm_wday < 0)\n+ tp->tm_wday += 7;\n+ y = 1970;\n+\n+#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))\n+#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))\n+\n+ while (days < 0 || days >= (__isleap (y) ? 366 : 365))\n+ {\n+ /* Guess a corrected year, assuming 365 days per year. */\n+ __time64_t yg = y + days / 365 - (days % 365 < 0);\n+\n+ /* Adjust DAYS and Y to match the guessed year. */\n+ days -= ((yg - y) * 365\n+\t + LEAPS_THRU_END_OF (yg - 1)\n+\t - LEAPS_THRU_END_OF (y - 1));\n+ y = yg;\n+ }\n+ tp->tm_year = y - 1900;\n+ if (tp->tm_year != y - 1900)\n+ {\n+ /* The year cannot be represented due to overflow. */\n+ __set_errno (EOVERFLOW);\n+ return 0;\n+ }\n+ tp->tm_yday = days;\n+ ip = __mon_yday[__isleap(y)];\n+ for (y = 11; days < (long int) ip[y]; --y)\n+ continue;\n+ days -= ip[y];\n+ tp->tm_mon = y;\n+ tp->tm_mday = days + 1;\n+ return 1;\n+}\ndiff --git a/time/tzfile.c b/time/tzfile.c\nindex d41246980b..9da9d0b38b 100644\n--- a/time/tzfile.c\n+++ b/time/tzfile.c\n@@ -630,7 +630,7 @@ __tzfile_default (const char *std, const char *dst,\n }\n \f\n void\n-__tzfile_compute (time_t timer, int use_localtime,\n+__tzfile_compute (__time64_t timer, int use_localtime,\n \t\t long int *leap_correct, int *leap_hit,\n \t\t struct tm *tp)\n {\n@@ -685,7 +685,7 @@ __tzfile_compute (time_t timer, int use_localtime,\n \n \t /* Convert to broken down structure. If this fails do not\n \t use the string. */\n-\t if (__glibc_unlikely (! __offtime (&timer, 0, tp)))\n+\t if (__glibc_unlikely (! __offtime64 (&timer, 0, tp)))\n \t goto use_last;\n \n \t /* Use the rules from the TZ string to compute the change. */\ndiff --git a/time/tzset.c b/time/tzset.c\nindex cf5fe969b6..ee462107e1 100644\n--- a/time/tzset.c\n+++ b/time/tzset.c\n@@ -55,7 +55,7 @@ typedef struct\n \n /* We cache the computed time of change for a\n given year so we don't have to recompute it. */\n- time_t change;\t/* When to change to this zone. */\n+ __time64_t change;\t/* When to change to this zone. */\n int computed_for;\t/* Year above is computed for. */\n } tz_rule;\n \n@@ -417,7 +417,7 @@ tzset_internal (int always)\n tz_rules[0].name = tz_rules[1].name = \"UTC\";\n if (J0 != 0)\n \ttz_rules[0].type = tz_rules[1].type = J0;\n- tz_rules[0].change = tz_rules[1].change = (time_t) -1;\n+ tz_rules[0].change = tz_rules[1].change = (__time64_t) -1;\n update_vars ();\n return;\n }\n@@ -516,10 +516,11 @@ compute_change (tz_rule *rule, int year)\n \n \n /* Figure out the correct timezone for TM and set `__tzname',\n- `__timezone', and `__daylight' accordingly. */\n+ `__timezone', and `__daylight' accordingly.\n+ NOTE: this takes a __time64_t value, so passing a __time_t value is OK. */\n void\n internal_function\n-__tz_compute (time_t timer, struct tm *tm, int use_localtime)\n+__tz_compute (__time64_t timer, struct tm *tm, int use_localtime)\n {\n compute_change (&tz_rules[0], 1900 + tm->tm_year);\n compute_change (&tz_rules[1], 1900 + tm->tm_year);\n@@ -620,6 +621,61 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)\n }\n \n \n+/* Return the `struct tm' representation of *TIMER in the local timezone.\n+ Use local time if USE_LOCALTIME is nonzero, UTC otherwise. */\n+struct tm *\n+__tz_convert64 (const __time64_t *timer, int use_localtime, struct tm *tp)\n+{\n+ long int leap_correction;\n+ int leap_extra_secs;\n+\n+ if (timer == NULL)\n+ {\n+ __set_errno (EINVAL);\n+ return NULL;\n+ }\n+\n+ __libc_lock_lock (tzset_lock);\n+\n+ /* Update internal database according to current TZ setting.\n+ POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.\n+ This is a good idea since this allows at least a bit more parallelism. */\n+ tzset_internal (tp == &_tmbuf && use_localtime);\n+\n+ if (__use_tzfile)\n+ __tzfile_compute (*timer, use_localtime, &leap_correction,\n+\t\t &leap_extra_secs, tp);\n+ else\n+ {\n+ if (! __offtime64 (timer, 0, tp))\n+\ttp = NULL;\n+ else\n+\t__tz_compute (*timer, tp, use_localtime);\n+ leap_correction = 0L;\n+ leap_extra_secs = 0;\n+ }\n+\n+ __libc_lock_unlock (tzset_lock);\n+\n+ if (tp)\n+ {\n+ if (! use_localtime)\n+\t{\n+\t tp->tm_isdst = 0;\n+\t tp->tm_zone = \"GMT\";\n+\t tp->tm_gmtoff = 0L;\n+\t}\n+\n+ if (__offtime64 (timer, tp->tm_gmtoff - leap_correction, tp))\n+ tp->tm_sec += leap_extra_secs;\n+ else\n+\ttp = NULL;\n+ }\n+\n+ return tp;\n+}\n+\n+\n libc_freeres_fn (free_mem)\n {\n while (tzstring_list != NULL)\n", "prefixes": [ "RFC", "03/52" ] }