From 7b59cdb7a19db2ff19fc7e2108ad754006965975 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 8 Jul 2016 17:55:01 +0200 Subject: Issue #22624: Python 3 requires clock() to build --- Modules/timemodule.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Modules/timemodule.c') diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 0b6d461870..94746444cf 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -1034,6 +1034,7 @@ py_process_time(_Py_clock_info_t *info) } #endif + /* Currently, Python 3 requires clock() to build: see issue #22624 */ return floatclock(info); #endif } -- cgit v1.2.1 From a958773a5c4536bce07440d936c1e41b0ce9471c Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Sun, 11 Sep 2016 22:55:16 -0400 Subject: Closes #25283: Make tm_gmtoff and tm_zone available on all platforms. --- Modules/timemodule.c | 114 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 33 deletions(-) (limited to 'Modules/timemodule.c') diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 94746444cf..ea7d906480 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -250,10 +250,8 @@ static PyStructSequence_Field struct_time_type_fields[] = { {"tm_wday", "day of week, range [0, 6], Monday is 0"}, {"tm_yday", "day of year, range [1, 366]"}, {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, -#ifdef HAVE_STRUCT_TM_TM_ZONE {"tm_zone", "abbreviation of timezone name"}, {"tm_gmtoff", "offset from UTC in seconds"}, -#endif /* HAVE_STRUCT_TM_TM_ZONE */ {0} }; @@ -275,7 +273,11 @@ static PyTypeObject StructTimeType; static PyObject * -tmtotuple(struct tm *p) +tmtotuple(struct tm *p +#ifndef HAVE_STRUCT_TM_TM_ZONE + , const char *zone, int gmtoff +#endif +) { PyObject *v = PyStructSequence_New(&StructTimeType); if (v == NULL) @@ -296,6 +298,10 @@ tmtotuple(struct tm *p) PyStructSequence_SET_ITEM(v, 9, PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape")); SET(10, p->tm_gmtoff); +#else + PyStructSequence_SET_ITEM(v, 9, + PyUnicode_DecodeLocale(zone, "surrogateescape")); + SET(10, gmtoff); #endif /* HAVE_STRUCT_TM_TM_ZONE */ #undef SET if (PyErr_Occurred()) { @@ -348,9 +354,26 @@ time_gmtime(PyObject *self, PyObject *args) return PyErr_SetFromErrno(PyExc_OSError); } buf = *local; +#ifdef HAVE_STRUCT_TM_TM_ZONE return tmtotuple(&buf); +#else + return tmtotuple(&buf, "UTC", 0); +#endif } +#ifndef HAVE_TIMEGM +static time_t +timegm(struct tm *p) +{ + /* XXX: the following implementation will not work for tm_year < 1970. + but it is likely that platforms that don't have timegm do not support + negative timestamps anyways. */ + return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 + + (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 - + ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400; +} +#endif + PyDoc_STRVAR(gmtime_doc, "gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\ tm_sec, tm_wday, tm_yday, tm_isdst)\n\ @@ -391,7 +414,18 @@ time_localtime(PyObject *self, PyObject *args) return NULL; if (pylocaltime(&when, &buf) == -1) return NULL; +#ifdef HAVE_STRUCT_TM_TM_ZONE return tmtotuple(&buf); +#else + { + struct tm local = buf; + char zone[100]; + int gmtoff; + strftime(zone, sizeof(buf), "%Z", &buf); + gmtoff = timegm(&buf) - when; + return tmtotuple(&local, zone, gmtoff); + } +#endif } PyDoc_STRVAR(localtime_doc, @@ -1145,6 +1179,27 @@ PyDoc_STRVAR(get_clock_info_doc, \n\ Get information of the specified clock."); +static void +get_zone(char *zone, int n, struct tm *p) +{ +#ifdef HAVE_STRUCT_TM_TM_ZONE + strncpy(zone, p->tm_zone ? p->tm_zone : " ", n); +#else + tzset(); + strftime(zone, n, "%Z", p); +#endif +} + +static int +get_gmtoff(time_t t, struct tm *p) +{ +#ifdef HAVE_STRUCT_TM_TM_ZONE + return p->tm_gmtoff; +#else + return timegm(p) - t; +#endif +} + static void PyInit_timezone(PyObject *m) { /* This code moved from PyInit_time wholesale to allow calling it from @@ -1177,7 +1232,6 @@ PyInit_timezone(PyObject *m) { otz1 = PyUnicode_DecodeLocale(tzname[1], "surrogateescape"); PyModule_AddObject(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)); #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ -#ifdef HAVE_STRUCT_TM_TM_ZONE { #define YEAR ((time_t)((365 * 24 + 6) * 3600)) time_t t; @@ -1186,13 +1240,13 @@ PyInit_timezone(PyObject *m) { char janname[10], julyname[10]; t = (time((time_t *)0) / YEAR) * YEAR; p = localtime(&t); - janzone = -p->tm_gmtoff; - strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9); + get_zone(janname, 9, p); + janzone = -get_gmtoff(t, p); janname[9] = '\0'; t += YEAR/2; p = localtime(&t); - julyzone = -p->tm_gmtoff; - strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9); + get_zone(julyname, 9, p); + julyzone = -get_gmtoff(t, p); julyname[9] = '\0'; if( janzone < julyzone ) { @@ -1214,8 +1268,6 @@ PyInit_timezone(PyObject *m) { janname, julyname)); } } -#else -#endif /* HAVE_STRUCT_TM_TM_ZONE */ #ifdef __CYGWIN__ tzset(); PyModule_AddIntConstant(m, "timezone", _timezone); @@ -1225,25 +1277,6 @@ PyInit_timezone(PyObject *m) { Py_BuildValue("(zz)", _tzname[0], _tzname[1])); #endif /* __CYGWIN__ */ #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ - -#if defined(HAVE_CLOCK_GETTIME) - PyModule_AddIntMacro(m, CLOCK_REALTIME); -#ifdef CLOCK_MONOTONIC - PyModule_AddIntMacro(m, CLOCK_MONOTONIC); -#endif -#ifdef CLOCK_MONOTONIC_RAW - PyModule_AddIntMacro(m, CLOCK_MONOTONIC_RAW); -#endif -#ifdef CLOCK_HIGHRES - PyModule_AddIntMacro(m, CLOCK_HIGHRES); -#endif -#ifdef CLOCK_PROCESS_CPUTIME_ID - PyModule_AddIntMacro(m, CLOCK_PROCESS_CPUTIME_ID); -#endif -#ifdef CLOCK_THREAD_CPUTIME_ID - PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID); -#endif -#endif /* HAVE_CLOCK_GETTIME */ } @@ -1350,17 +1383,32 @@ PyInit_time(void) /* Set, or reset, module variables like time.timezone */ PyInit_timezone(m); +#if defined(HAVE_CLOCK_GETTIME) + PyModule_AddIntMacro(m, CLOCK_REALTIME); +#ifdef CLOCK_MONOTONIC + PyModule_AddIntMacro(m, CLOCK_MONOTONIC); +#endif +#ifdef CLOCK_MONOTONIC_RAW + PyModule_AddIntMacro(m, CLOCK_MONOTONIC_RAW); +#endif +#ifdef CLOCK_HIGHRES + PyModule_AddIntMacro(m, CLOCK_HIGHRES); +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + PyModule_AddIntMacro(m, CLOCK_PROCESS_CPUTIME_ID); +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID); +#endif +#endif /* HAVE_CLOCK_GETTIME */ + if (!initialized) { if (PyStructSequence_InitType2(&StructTimeType, &struct_time_type_desc) < 0) return NULL; } Py_INCREF(&StructTimeType); -#ifdef HAVE_STRUCT_TM_TM_ZONE PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 11); -#else - PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 9); -#endif PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType); initialized = 1; return m; -- cgit v1.2.1 From c70561b7894365a98df3ca9c8e4e39de9c0f08e3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 13 Sep 2016 22:55:09 -0700 Subject: more granular configure checks for clock_* functions (closes #28081) --- Modules/timemodule.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'Modules/timemodule.c') diff --git a/Modules/timemodule.c b/Modules/timemodule.c index ea7d906480..8194fd9a35 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -160,7 +160,9 @@ PyDoc_STRVAR(clock_gettime_doc, "clock_gettime(clk_id) -> floating point number\n\ \n\ Return the time of the specified clock clk_id."); +#endif /* HAVE_CLOCK_GETTIME */ +#ifdef HAVE_CLOCK_SETTIME static PyObject * time_clock_settime(PyObject *self, PyObject *args) { @@ -191,7 +193,9 @@ PyDoc_STRVAR(clock_settime_doc, "clock_settime(clk_id, time)\n\ \n\ Set the time of the specified clock clk_id."); +#endif /* HAVE_CLOCK_SETTIME */ +#ifdef HAVE_CLOCK_GETRES static PyObject * time_clock_getres(PyObject *self, PyObject *args) { @@ -215,7 +219,7 @@ PyDoc_STRVAR(clock_getres_doc, "clock_getres(clk_id) -> floating point number\n\ \n\ Return the resolution (precision) of the specified clock clk_id."); -#endif /* HAVE_CLOCK_GETTIME */ +#endif /* HAVE_CLOCK_GETRES */ static PyObject * time_sleep(PyObject *self, PyObject *obj) @@ -1287,7 +1291,11 @@ static PyMethodDef time_methods[] = { #endif #ifdef HAVE_CLOCK_GETTIME {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, +#endif +#ifdef HAVE_CLOCK_SETTIME {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, +#endif +#ifdef HAVE_CLOCK_GETRES {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc}, #endif {"sleep", time_sleep, METH_O, sleep_doc}, @@ -1383,8 +1391,9 @@ PyInit_time(void) /* Set, or reset, module variables like time.timezone */ PyInit_timezone(m); -#if defined(HAVE_CLOCK_GETTIME) +#ifdef CLOCK_REALTIME PyModule_AddIntMacro(m, CLOCK_REALTIME); +#endif #ifdef CLOCK_MONOTONIC PyModule_AddIntMacro(m, CLOCK_MONOTONIC); #endif @@ -1400,7 +1409,6 @@ PyInit_time(void) #ifdef CLOCK_THREAD_CPUTIME_ID PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID); #endif -#endif /* HAVE_CLOCK_GETTIME */ if (!initialized) { if (PyStructSequence_InitType2(&StructTimeType, -- cgit v1.2.1 From ada5f796e97b5a38b43571134f846366876ae54d Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Wed, 28 Sep 2016 17:31:35 -0400 Subject: Issue #28148: Stop using localtime() and gmtime() in the time module. Introduced platform independent _PyTime_localtime API that is similar to POSIX localtime_r, but available on all platforms. Patch by Ed Schouten. --- Modules/timemodule.c | 55 +++++++++++++--------------------------------------- 1 file changed, 14 insertions(+), 41 deletions(-) (limited to 'Modules/timemodule.c') diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 8194fd9a35..f0708338e8 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -343,21 +343,14 @@ static PyObject * time_gmtime(PyObject *self, PyObject *args) { time_t when; - struct tm buf, *local; + struct tm buf; if (!parse_time_t_args(args, "|O:gmtime", &when)) return NULL; errno = 0; - local = gmtime(&when); - if (local == NULL) { -#ifdef EINVAL - if (errno == 0) - errno = EINVAL; -#endif - return PyErr_SetFromErrno(PyExc_OSError); - } - buf = *local; + if (_PyTime_gmtime(when, &buf) != 0) + return NULL; #ifdef HAVE_STRUCT_TM_TM_ZONE return tmtotuple(&buf); #else @@ -388,26 +381,6 @@ GMT). When 'seconds' is not passed in, convert the current time instead.\n\ If the platform supports the tm_gmtoff and tm_zone, they are available as\n\ attributes only."); -static int -pylocaltime(time_t *timep, struct tm *result) -{ - struct tm *local; - - assert (timep != NULL); - local = localtime(timep); - if (local == NULL) { - /* unconvertible time */ -#ifdef EINVAL - if (errno == 0) - errno = EINVAL; -#endif - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - *result = *local; - return 0; -} - static PyObject * time_localtime(PyObject *self, PyObject *args) { @@ -416,7 +389,7 @@ time_localtime(PyObject *self, PyObject *args) if (!parse_time_t_args(args, "|O:localtime", &when)) return NULL; - if (pylocaltime(&when, &buf) == -1) + if (_PyTime_localtime(when, &buf) != 0) return NULL; #ifdef HAVE_STRUCT_TM_TM_ZONE return tmtotuple(&buf); @@ -611,7 +584,7 @@ time_strftime(PyObject *self, PyObject *args) if (tup == NULL) { time_t tt = time(NULL); - if (pylocaltime(&tt, &buf) == -1) + if (_PyTime_localtime(tt, &buf) != 0) return NULL; } else if (!gettmarg(tup, &buf) || !checktm(&buf)) @@ -796,7 +769,7 @@ time_asctime(PyObject *self, PyObject *args) return NULL; if (tup == NULL) { time_t tt = time(NULL); - if (pylocaltime(&tt, &buf) == -1) + if (_PyTime_localtime(tt, &buf) != 0) return NULL; } else if (!gettmarg(tup, &buf) || !checktm(&buf)) @@ -818,7 +791,7 @@ time_ctime(PyObject *self, PyObject *args) struct tm buf; if (!parse_time_t_args(args, "|O:ctime", &tt)) return NULL; - if (pylocaltime(&tt, &buf) == -1) + if (_PyTime_localtime(tt, &buf) != 0) return NULL; return _asctime(&buf); } @@ -1239,18 +1212,18 @@ PyInit_timezone(PyObject *m) { { #define YEAR ((time_t)((365 * 24 + 6) * 3600)) time_t t; - struct tm *p; + struct tm p; long janzone, julyzone; char janname[10], julyname[10]; t = (time((time_t *)0) / YEAR) * YEAR; - p = localtime(&t); - get_zone(janname, 9, p); - janzone = -get_gmtoff(t, p); + _PyTime_localtime(t, &p); + get_zone(janname, 9, &p); + janzone = -get_gmtoff(t, &p); janname[9] = '\0'; t += YEAR/2; - p = localtime(&t); - get_zone(julyname, 9, p); - julyzone = -get_gmtoff(t, p); + _PyTime_localtime(t, &p); + get_zone(julyname, 9, &p); + julyzone = -get_gmtoff(t, &p); julyname[9] = '\0'; if( janzone < julyzone ) { -- cgit v1.2.1 From 57c0f2e61c8a5893c37e576a3a03ba5e57c1132c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 20 Nov 2016 09:13:07 +0200 Subject: Replaced outdated macros _PyUnicode_AsString and _PyUnicode_AsStringAndSize with PyUnicode_AsUTF8 and PyUnicode_AsUTF8AndSize. --- Modules/timemodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/timemodule.c') diff --git a/Modules/timemodule.c b/Modules/timemodule.c index f0708338e8..db0ab5805c 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -441,7 +441,7 @@ gettmarg(PyObject *args, struct tm *p) if (Py_TYPE(args) == &StructTimeType) { PyObject *item; item = PyTuple_GET_ITEM(args, 9); - p->tm_zone = item == Py_None ? NULL : _PyUnicode_AsString(item); + p->tm_zone = item == Py_None ? NULL : PyUnicode_AsUTF8(item); item = PyTuple_GET_ITEM(args, 10); p->tm_gmtoff = item == Py_None ? 0 : PyLong_AsLong(item); if (PyErr_Occurred()) -- cgit v1.2.1 From e3044884ae67bbd61f8a6cf1c0413d06132fe0ac Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 14 Dec 2016 11:22:05 -0800 Subject: Fixes maximum usable length of buffer for formatting time zone in localtime(). --- Modules/timemodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/timemodule.c') diff --git a/Modules/timemodule.c b/Modules/timemodule.c index db0ab5805c..ebd44ad525 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -398,7 +398,7 @@ time_localtime(PyObject *self, PyObject *args) struct tm local = buf; char zone[100]; int gmtoff; - strftime(zone, sizeof(buf), "%Z", &buf); + strftime(zone, sizeof(zone), "%Z", &buf); gmtoff = timegm(&buf) - when; return tmtotuple(&local, zone, gmtoff); } -- cgit v1.2.1