• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Time module */
2 
3 #include "Python.h"
4 #include "pycore_fileutils.h"     // _Py_BEGIN_SUPPRESS_IPH
5 #include "pycore_moduleobject.h"  // _PyModule_GetState()
6 #include "pycore_namespace.h"     // _PyNamespace_New()
7 #include "pycore_runtime.h"       // _Py_ID()
8 #include "pycore_time.h"          // _PyTimeFraction
9 
10 #include <time.h>                 // clock()
11 #ifdef HAVE_SYS_TIMES_H
12 #  include <sys/times.h>          // times()
13 #endif
14 #ifdef HAVE_SYS_TYPES_H
15 #  include <sys/types.h>
16 #endif
17 #if defined(HAVE_SYS_RESOURCE_H)
18 #  include <sys/resource.h>       // getrusage(RUSAGE_SELF)
19 #endif
20 #ifdef QUICKWIN
21 # include <io.h>
22 #endif
23 #if defined(HAVE_PTHREAD_H)
24 #  include <pthread.h>            // pthread_getcpuclockid()
25 #endif
26 #if defined(_AIX)
27 #   include <sys/thread.h>
28 #endif
29 #if defined(__WATCOMC__) && !defined(__QNX__)
30 #  include <i86.h>
31 #else
32 #  ifdef MS_WINDOWS
33 #    ifndef WIN32_LEAN_AND_MEAN
34 #      define WIN32_LEAN_AND_MEAN
35 #    endif
36 #    include <windows.h>
37 #  endif /* MS_WINDOWS */
38 #endif /* !__WATCOMC__ || __QNX__ */
39 
40 #ifdef _Py_MEMORY_SANITIZER
41 #  include <sanitizer/msan_interface.h>
42 #endif
43 
44 #ifdef _MSC_VER
45 #  define _Py_timezone _timezone
46 #  define _Py_daylight _daylight
47 #  define _Py_tzname _tzname
48 #else
49 #  define _Py_timezone timezone
50 #  define _Py_daylight daylight
51 #  define _Py_tzname tzname
52 #endif
53 
54 #if defined(__APPLE__ ) && defined(__has_builtin)
55 #  if __has_builtin(__builtin_available)
56 #    define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
57 #  endif
58 #endif
59 #ifndef HAVE_CLOCK_GETTIME_RUNTIME
60 #  define HAVE_CLOCK_GETTIME_RUNTIME 1
61 #endif
62 
63 
64 #define SEC_TO_NS (1000 * 1000 * 1000)
65 
66 
67 /*[clinic input]
68 module time
69 [clinic start generated code]*/
70 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a668a08771581f36]*/
71 
72 
73 /* Forward declarations */
74 static int pysleep(PyTime_t timeout);
75 
76 
77 typedef struct {
78     PyTypeObject *struct_time_type;
79 // gh-115714: Don't use times() on WASI.
80 #if defined(HAVE_TIMES) && !defined(__wasi__)
81     // times() clock frequency in hertz
82     _PyTimeFraction times_base;
83 #endif
84 #ifdef HAVE_CLOCK
85     // clock() frequency in hertz
86     _PyTimeFraction clock_base;
87 #endif
88 } time_module_state;
89 
90 static inline time_module_state*
get_time_state(PyObject * module)91 get_time_state(PyObject *module)
92 {
93     void *state = _PyModule_GetState(module);
94     assert(state != NULL);
95     return (time_module_state *)state;
96 }
97 
98 
99 static PyObject*
_PyFloat_FromPyTime(PyTime_t t)100 _PyFloat_FromPyTime(PyTime_t t)
101 {
102     double d = PyTime_AsSecondsDouble(t);
103     return PyFloat_FromDouble(d);
104 }
105 
106 
107 static PyObject *
time_time(PyObject * self,PyObject * unused)108 time_time(PyObject *self, PyObject *unused)
109 {
110     PyTime_t t;
111     if (PyTime_Time(&t) < 0) {
112         return NULL;
113     }
114     return _PyFloat_FromPyTime(t);
115 }
116 
117 
118 PyDoc_STRVAR(time_doc,
119 "time() -> floating-point number\n\
120 \n\
121 Return the current time in seconds since the Epoch.\n\
122 Fractions of a second may be present if the system clock provides them.");
123 
124 static PyObject *
time_time_ns(PyObject * self,PyObject * unused)125 time_time_ns(PyObject *self, PyObject *unused)
126 {
127     PyTime_t t;
128     if (PyTime_Time(&t) < 0) {
129         return NULL;
130     }
131     return _PyTime_AsLong(t);
132 }
133 
134 PyDoc_STRVAR(time_ns_doc,
135 "time_ns() -> int\n\
136 \n\
137 Return the current time in nanoseconds since the Epoch.");
138 
139 #ifdef HAVE_CLOCK
140 
141 #ifndef CLOCKS_PER_SEC
142 #  ifdef CLK_TCK
143 #    define CLOCKS_PER_SEC CLK_TCK
144 #  else
145 #    define CLOCKS_PER_SEC 1000000
146 #  endif
147 #endif
148 
149 static int
py_clock(time_module_state * state,PyTime_t * tp,_Py_clock_info_t * info)150 py_clock(time_module_state *state, PyTime_t *tp, _Py_clock_info_t *info)
151 {
152     _PyTimeFraction *base = &state->clock_base;
153 
154     if (info) {
155         info->implementation = "clock()";
156         info->resolution = _PyTimeFraction_Resolution(base);
157         info->monotonic = 1;
158         info->adjustable = 0;
159     }
160 
161     clock_t ticks = clock();
162     if (ticks == (clock_t)-1) {
163         PyErr_SetString(PyExc_RuntimeError,
164                         "the processor time used is not available "
165                         "or its value cannot be represented");
166         return -1;
167     }
168     *tp = _PyTimeFraction_Mul(ticks, base);
169     return 0;
170 }
171 #endif /* HAVE_CLOCK */
172 
173 
174 #ifdef HAVE_CLOCK_GETTIME
175 
176 #ifdef __APPLE__
177 /*
178  * The clock_* functions will be removed from the module
179  * dict entirely when the C API is not available.
180  */
181 #pragma clang diagnostic push
182 #pragma clang diagnostic ignored "-Wunguarded-availability"
183 #endif
184 
185 static int
time_clockid_converter(PyObject * obj,clockid_t * p)186 time_clockid_converter(PyObject *obj, clockid_t *p)
187 {
188 #ifdef _AIX
189     long long clk_id = PyLong_AsLongLong(obj);
190 #else
191     int clk_id = PyLong_AsInt(obj);
192 #endif
193     if (clk_id == -1 && PyErr_Occurred()) {
194         PyErr_Format(PyExc_TypeError,
195                      "clk_id should be integer, not %s",
196                      _PyType_Name(Py_TYPE(obj)));
197         return 0;
198     }
199 
200     // Make sure that we picked the right type (check sizes type)
201     Py_BUILD_ASSERT(sizeof(clk_id) == sizeof(*p));
202     *p = (clockid_t)clk_id;
203     return 1;
204 }
205 
206 /*[python input]
207 
208 class clockid_t_converter(CConverter):
209     type = "clockid_t"
210     converter = 'time_clockid_converter'
211 
212 [python start generated code]*/
213 /*[python end generated code: output=da39a3ee5e6b4b0d input=53867111501f46c8]*/
214 
215 
216 /*[clinic input]
217 time.clock_gettime
218 
219     clk_id: clockid_t
220     /
221 
222 Return the time of the specified clock clk_id as a float.
223 [clinic start generated code]*/
224 
225 static PyObject *
time_clock_gettime_impl(PyObject * module,clockid_t clk_id)226 time_clock_gettime_impl(PyObject *module, clockid_t clk_id)
227 /*[clinic end generated code: output=832b9ebc03328020 input=7e89fcc42ca15e5d]*/
228 {
229     struct timespec tp;
230     int ret = clock_gettime(clk_id, &tp);
231     if (ret != 0) {
232         PyErr_SetFromErrno(PyExc_OSError);
233         return NULL;
234     }
235     return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
236 }
237 
238 /*[clinic input]
239 time.clock_gettime_ns
240 
241     clk_id: clockid_t
242     /
243 
244 Return the time of the specified clock clk_id as nanoseconds (int).
245 [clinic start generated code]*/
246 
247 static PyObject *
time_clock_gettime_ns_impl(PyObject * module,clockid_t clk_id)248 time_clock_gettime_ns_impl(PyObject *module, clockid_t clk_id)
249 /*[clinic end generated code: output=4a045c3a36e60044 input=aabc248db8c8e3e5]*/
250 {
251     struct timespec ts;
252     int ret = clock_gettime(clk_id, &ts);
253     if (ret != 0) {
254         PyErr_SetFromErrno(PyExc_OSError);
255         return NULL;
256     }
257 
258     PyTime_t t;
259     if (_PyTime_FromTimespec(&t, &ts) < 0) {
260         return NULL;
261     }
262     return _PyTime_AsLong(t);
263 }
264 #endif   /* HAVE_CLOCK_GETTIME */
265 
266 #ifdef HAVE_CLOCK_SETTIME
267 static PyObject *
time_clock_settime(PyObject * self,PyObject * args)268 time_clock_settime(PyObject *self, PyObject *args)
269 {
270     int clk_id;
271     PyObject *obj;
272     PyTime_t t;
273     struct timespec tp;
274     int ret;
275 
276     if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj))
277         return NULL;
278 
279     if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0)
280         return NULL;
281 
282     if (_PyTime_AsTimespec(t, &tp) == -1)
283         return NULL;
284 
285     ret = clock_settime((clockid_t)clk_id, &tp);
286     if (ret != 0) {
287         PyErr_SetFromErrno(PyExc_OSError);
288         return NULL;
289     }
290     Py_RETURN_NONE;
291 }
292 
293 PyDoc_STRVAR(clock_settime_doc,
294 "clock_settime(clk_id, time)\n\
295 \n\
296 Set the time of the specified clock clk_id.");
297 
298 static PyObject *
time_clock_settime_ns(PyObject * self,PyObject * args)299 time_clock_settime_ns(PyObject *self, PyObject *args)
300 {
301     int clk_id;
302     PyObject *obj;
303     PyTime_t t;
304     struct timespec ts;
305     int ret;
306 
307     if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) {
308         return NULL;
309     }
310 
311     if (_PyTime_FromLong(&t, obj) < 0) {
312         return NULL;
313     }
314     if (_PyTime_AsTimespec(t, &ts) == -1) {
315         return NULL;
316     }
317 
318     ret = clock_settime((clockid_t)clk_id, &ts);
319     if (ret != 0) {
320         PyErr_SetFromErrno(PyExc_OSError);
321         return NULL;
322     }
323     Py_RETURN_NONE;
324 }
325 
326 PyDoc_STRVAR(clock_settime_ns_doc,
327 "clock_settime_ns(clk_id, time)\n\
328 \n\
329 Set the time of the specified clock clk_id with nanoseconds.");
330 #endif   /* HAVE_CLOCK_SETTIME */
331 
332 #ifdef HAVE_CLOCK_GETRES
333 static PyObject *
time_clock_getres(PyObject * self,PyObject * args)334 time_clock_getres(PyObject *self, PyObject *args)
335 {
336     int ret;
337     int clk_id;
338     struct timespec tp;
339 
340     if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id))
341         return NULL;
342 
343     ret = clock_getres((clockid_t)clk_id, &tp);
344     if (ret != 0) {
345         PyErr_SetFromErrno(PyExc_OSError);
346         return NULL;
347     }
348 
349     return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
350 }
351 
352 PyDoc_STRVAR(clock_getres_doc,
353 "clock_getres(clk_id) -> floating-point number\n\
354 \n\
355 Return the resolution (precision) of the specified clock clk_id.");
356 
357 #ifdef __APPLE__
358 #pragma clang diagnostic pop
359 #endif
360 
361 #endif   /* HAVE_CLOCK_GETRES */
362 
363 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
364 static PyObject *
time_pthread_getcpuclockid(PyObject * self,PyObject * args)365 time_pthread_getcpuclockid(PyObject *self, PyObject *args)
366 {
367     unsigned long thread_id;
368     int err;
369     clockid_t clk_id;
370     if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) {
371         return NULL;
372     }
373     err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id);
374     if (err) {
375         errno = err;
376         PyErr_SetFromErrno(PyExc_OSError);
377         return NULL;
378     }
379 #ifdef _Py_MEMORY_SANITIZER
380     __msan_unpoison(&clk_id, sizeof(clk_id));
381 #endif
382     return PyLong_FromLong(clk_id);
383 }
384 
385 PyDoc_STRVAR(pthread_getcpuclockid_doc,
386 "pthread_getcpuclockid(thread_id) -> int\n\
387 \n\
388 Return the clk_id of a thread's CPU time clock.");
389 #endif /* HAVE_PTHREAD_GETCPUCLOCKID */
390 
391 static PyObject *
time_sleep(PyObject * self,PyObject * timeout_obj)392 time_sleep(PyObject *self, PyObject *timeout_obj)
393 {
394     if (PySys_Audit("time.sleep", "O", timeout_obj) < 0) {
395         return NULL;
396     }
397 
398     PyTime_t timeout;
399     if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT))
400         return NULL;
401     if (timeout < 0) {
402         PyErr_SetString(PyExc_ValueError,
403                         "sleep length must be non-negative");
404         return NULL;
405     }
406     if (pysleep(timeout) != 0) {
407         return NULL;
408     }
409     Py_RETURN_NONE;
410 }
411 
412 PyDoc_STRVAR(sleep_doc,
413 "sleep(seconds)\n\
414 \n\
415 Delay execution for a given number of seconds.  The argument may be\n\
416 a floating-point number for subsecond precision.");
417 
418 static PyStructSequence_Field struct_time_type_fields[] = {
419     {"tm_year", "year, for example, 1993"},
420     {"tm_mon", "month of year, range [1, 12]"},
421     {"tm_mday", "day of month, range [1, 31]"},
422     {"tm_hour", "hours, range [0, 23]"},
423     {"tm_min", "minutes, range [0, 59]"},
424     {"tm_sec", "seconds, range [0, 61])"},
425     {"tm_wday", "day of week, range [0, 6], Monday is 0"},
426     {"tm_yday", "day of year, range [1, 366]"},
427     {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"},
428     {"tm_zone", "abbreviation of timezone name"},
429     {"tm_gmtoff", "offset from UTC in seconds"},
430     {0}
431 };
432 
433 static PyStructSequence_Desc struct_time_type_desc = {
434     "time.struct_time",
435     "The time value as returned by gmtime(), localtime(), and strptime(), and\n"
436     " accepted by asctime(), mktime() and strftime().  May be considered as a\n"
437     " sequence of 9 integers.\n\n"
438     " Note that several fields' values are not the same as those defined by\n"
439     " the C language standard for struct tm.  For example, the value of the\n"
440     " field tm_year is the actual year, not year - 1900.  See individual\n"
441     " fields' descriptions for details.",
442     struct_time_type_fields,
443     9,
444 };
445 
446 #if defined(MS_WINDOWS)
447 #ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
448   #define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002
449 #endif
450 
451 static DWORD timer_flags = (DWORD)-1;
452 #endif
453 
454 static PyObject *
tmtotuple(time_module_state * state,struct tm * p,const char * zone,time_t gmtoff)455 tmtotuple(time_module_state *state, struct tm *p
456 #ifndef HAVE_STRUCT_TM_TM_ZONE
457         , const char *zone, time_t gmtoff
458 #endif
459 )
460 {
461     PyObject *v = PyStructSequence_New(state->struct_time_type);
462     if (v == NULL)
463         return NULL;
464 
465 #define SET_ITEM(INDEX, CALL)                       \
466     do {                                            \
467         PyObject *obj = (CALL);                     \
468         if (obj == NULL) {                          \
469             Py_DECREF(v);                           \
470             return NULL;                            \
471         }                                           \
472         PyStructSequence_SET_ITEM(v, (INDEX), obj); \
473     } while (0)
474 
475 #define SET(INDEX, VAL) \
476     SET_ITEM((INDEX), PyLong_FromLong((long) (VAL)))
477 
478     SET(0, p->tm_year + 1900);
479     SET(1, p->tm_mon + 1);         /* Want January == 1 */
480     SET(2, p->tm_mday);
481     SET(3, p->tm_hour);
482     SET(4, p->tm_min);
483     SET(5, p->tm_sec);
484     SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
485     SET(7, p->tm_yday + 1);        /* Want January, 1 == 1 */
486     SET(8, p->tm_isdst);
487 #ifdef HAVE_STRUCT_TM_TM_ZONE
488     SET_ITEM(9, PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape"));
489     SET(10, p->tm_gmtoff);
490 #else
491     SET_ITEM(9, PyUnicode_DecodeLocale(zone, "surrogateescape"));
492     SET_ITEM(10, _PyLong_FromTime_t(gmtoff));
493 #endif /* HAVE_STRUCT_TM_TM_ZONE */
494 
495 #undef SET
496 #undef SET_ITEM
497 
498     return v;
499 }
500 
501 /* Parse arg tuple that can contain an optional float-or-None value;
502    format needs to be "|O:name".
503    Returns non-zero on success (parallels PyArg_ParseTuple).
504 */
505 static int
parse_time_t_args(PyObject * args,const char * format,time_t * pwhen)506 parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
507 {
508     PyObject *ot = NULL;
509     time_t whent;
510 
511     if (!PyArg_ParseTuple(args, format, &ot))
512         return 0;
513     if (ot == NULL || ot == Py_None) {
514         whent = time(NULL);
515     }
516     else {
517         if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1)
518             return 0;
519     }
520     *pwhen = whent;
521     return 1;
522 }
523 
524 static PyObject *
time_gmtime(PyObject * module,PyObject * args)525 time_gmtime(PyObject *module, PyObject *args)
526 {
527     time_t when;
528     struct tm buf;
529 
530     if (!parse_time_t_args(args, "|O:gmtime", &when))
531         return NULL;
532 
533     errno = 0;
534     if (_PyTime_gmtime(when, &buf) != 0)
535         return NULL;
536 
537     time_module_state *state = get_time_state(module);
538 #ifdef HAVE_STRUCT_TM_TM_ZONE
539     return tmtotuple(state, &buf);
540 #else
541     return tmtotuple(state, &buf, "UTC", 0);
542 #endif
543 }
544 
545 #ifndef HAVE_TIMEGM
546 static time_t
timegm(struct tm * p)547 timegm(struct tm *p)
548 {
549     /* XXX: the following implementation will not work for tm_year < 1970.
550        but it is likely that platforms that don't have timegm do not support
551        negative timestamps anyways. */
552     return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 +
553         (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 -
554         ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400;
555 }
556 #endif
557 
558 PyDoc_STRVAR(gmtime_doc,
559 "gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\
560                        tm_sec, tm_wday, tm_yday, tm_isdst)\n\
561 \n\
562 Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
563 GMT).  When 'seconds' is not passed in, convert the current time instead.\n\
564 \n\
565 If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
566 attributes only.");
567 
568 static PyObject *
time_localtime(PyObject * module,PyObject * args)569 time_localtime(PyObject *module, PyObject *args)
570 {
571     time_t when;
572     struct tm buf;
573 
574     if (!parse_time_t_args(args, "|O:localtime", &when))
575         return NULL;
576     if (_PyTime_localtime(when, &buf) != 0)
577         return NULL;
578 
579     time_module_state *state = get_time_state(module);
580 #ifdef HAVE_STRUCT_TM_TM_ZONE
581     return tmtotuple(state, &buf);
582 #else
583     {
584         struct tm local = buf;
585         char zone[100];
586         time_t gmtoff;
587         strftime(zone, sizeof(zone), "%Z", &buf);
588         gmtoff = timegm(&buf) - when;
589         return tmtotuple(state, &local, zone, gmtoff);
590     }
591 #endif
592 }
593 
594 #if defined(__linux__) && !defined(__GLIBC__)
595 static const char *utc_string = NULL;
596 #endif
597 
598 PyDoc_STRVAR(localtime_doc,
599 "localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
600                           tm_sec,tm_wday,tm_yday,tm_isdst)\n\
601 \n\
602 Convert seconds since the Epoch to a time tuple expressing local time.\n\
603 When 'seconds' is not passed in, convert the current time instead.");
604 
605 /* Convert 9-item tuple to tm structure.  Return 1 on success, set
606  * an exception and return 0 on error.
607  */
608 static int
gettmarg(time_module_state * state,PyObject * args,struct tm * p,const char * format)609 gettmarg(time_module_state *state, PyObject *args,
610          struct tm *p, const char *format)
611 {
612     int y;
613 
614     memset((void *) p, '\0', sizeof(struct tm));
615 
616     if (!PyTuple_Check(args)) {
617         PyErr_SetString(PyExc_TypeError,
618                         "Tuple or struct_time argument required");
619         return 0;
620     }
621 
622     if (!PyArg_ParseTuple(args, format,
623                           &y, &p->tm_mon, &p->tm_mday,
624                           &p->tm_hour, &p->tm_min, &p->tm_sec,
625                           &p->tm_wday, &p->tm_yday, &p->tm_isdst))
626         return 0;
627 
628     if (y < INT_MIN + 1900) {
629         PyErr_SetString(PyExc_OverflowError, "year out of range");
630         return 0;
631     }
632 
633     p->tm_year = y - 1900;
634     p->tm_mon--;
635     p->tm_wday = (p->tm_wday + 1) % 7;
636     p->tm_yday--;
637 #ifdef HAVE_STRUCT_TM_TM_ZONE
638     if (Py_IS_TYPE(args, state->struct_time_type)) {
639         PyObject *item;
640         item = PyStructSequence_GET_ITEM(args, 9);
641         if (item != Py_None) {
642             p->tm_zone = (char *)PyUnicode_AsUTF8(item);
643             if (p->tm_zone == NULL) {
644                 return 0;
645             }
646 #if defined(__linux__) && !defined(__GLIBC__)
647             // Make an attempt to return the C library's own timezone strings to
648             // it. musl refuses to process a tm_zone field unless it produced
649             // it. See issue #34672.
650             if (utc_string && strcmp(p->tm_zone, utc_string) == 0) {
651                 p->tm_zone = utc_string;
652             }
653             else if (tzname[0] && strcmp(p->tm_zone, tzname[0]) == 0) {
654                 p->tm_zone = tzname[0];
655             }
656             else if (tzname[1] && strcmp(p->tm_zone, tzname[1]) == 0) {
657                 p->tm_zone = tzname[1];
658             }
659 #endif
660         }
661         item = PyStructSequence_GET_ITEM(args, 10);
662         if (item != Py_None) {
663             p->tm_gmtoff = PyLong_AsLong(item);
664             if (PyErr_Occurred())
665                 return 0;
666         }
667     }
668 #endif /* HAVE_STRUCT_TM_TM_ZONE */
669     return 1;
670 }
671 
672 /* Check values of the struct tm fields before it is passed to strftime() and
673  * asctime().  Return 1 if all values are valid, otherwise set an exception
674  * and returns 0.
675  */
676 static int
checktm(struct tm * buf)677 checktm(struct tm* buf)
678 {
679     /* Checks added to make sure strftime() and asctime() does not crash Python by
680        indexing blindly into some array for a textual representation
681        by some bad index (fixes bug #897625 and #6608).
682 
683        Also support values of zero from Python code for arguments in which
684        that is out of range by forcing that value to the lowest value that
685        is valid (fixed bug #1520914).
686 
687        Valid ranges based on what is allowed in struct tm:
688 
689        - tm_year: [0, max(int)] (1)
690        - tm_mon: [0, 11] (2)
691        - tm_mday: [1, 31]
692        - tm_hour: [0, 23]
693        - tm_min: [0, 59]
694        - tm_sec: [0, 60]
695        - tm_wday: [0, 6] (1)
696        - tm_yday: [0, 365] (2)
697        - tm_isdst: [-max(int), max(int)]
698 
699        (1) gettmarg() handles bounds-checking.
700        (2) Python's acceptable range is one greater than the range in C,
701        thus need to check against automatic decrement by gettmarg().
702     */
703     if (buf->tm_mon == -1)
704         buf->tm_mon = 0;
705     else if (buf->tm_mon < 0 || buf->tm_mon > 11) {
706         PyErr_SetString(PyExc_ValueError, "month out of range");
707         return 0;
708     }
709     if (buf->tm_mday == 0)
710         buf->tm_mday = 1;
711     else if (buf->tm_mday < 0 || buf->tm_mday > 31) {
712         PyErr_SetString(PyExc_ValueError, "day of month out of range");
713         return 0;
714     }
715     if (buf->tm_hour < 0 || buf->tm_hour > 23) {
716         PyErr_SetString(PyExc_ValueError, "hour out of range");
717         return 0;
718     }
719     if (buf->tm_min < 0 || buf->tm_min > 59) {
720         PyErr_SetString(PyExc_ValueError, "minute out of range");
721         return 0;
722     }
723     if (buf->tm_sec < 0 || buf->tm_sec > 61) {
724         PyErr_SetString(PyExc_ValueError, "seconds out of range");
725         return 0;
726     }
727     /* tm_wday does not need checking of its upper-bound since taking
728     ``% 7`` in gettmarg() automatically restricts the range. */
729     if (buf->tm_wday < 0) {
730         PyErr_SetString(PyExc_ValueError, "day of week out of range");
731         return 0;
732     }
733     if (buf->tm_yday == -1)
734         buf->tm_yday = 0;
735     else if (buf->tm_yday < 0 || buf->tm_yday > 365) {
736         PyErr_SetString(PyExc_ValueError, "day of year out of range");
737         return 0;
738     }
739     return 1;
740 }
741 
742 #ifdef MS_WINDOWS
743    /* wcsftime() doesn't format correctly time zones, see issue #10653 */
744 #  undef HAVE_WCSFTIME
745 #endif
746 #define STRFTIME_FORMAT_CODES \
747 "Commonly used format codes:\n\
748 \n\
749 %Y  Year with century as a decimal number.\n\
750 %m  Month as a decimal number [01,12].\n\
751 %d  Day of the month as a decimal number [01,31].\n\
752 %H  Hour (24-hour clock) as a decimal number [00,23].\n\
753 %M  Minute as a decimal number [00,59].\n\
754 %S  Second as a decimal number [00,61].\n\
755 %z  Time zone offset from UTC.\n\
756 %a  Locale's abbreviated weekday name.\n\
757 %A  Locale's full weekday name.\n\
758 %b  Locale's abbreviated month name.\n\
759 %B  Locale's full month name.\n\
760 %c  Locale's appropriate date and time representation.\n\
761 %I  Hour (12-hour clock) as a decimal number [01,12].\n\
762 %p  Locale's equivalent of either AM or PM.\n\
763 \n\
764 Other codes may be available on your platform.  See documentation for\n\
765 the C library strftime function.\n"
766 
767 #ifdef HAVE_STRFTIME
768 #ifdef HAVE_WCSFTIME
769 #define time_char wchar_t
770 #define format_time wcsftime
771 #define time_strlen wcslen
772 #else
773 #define time_char char
774 #define format_time strftime
775 #define time_strlen strlen
776 #endif
777 
778 static PyObject *
time_strftime1(time_char ** outbuf,size_t * bufsize,time_char * format,size_t fmtlen,struct tm * tm)779 time_strftime1(time_char **outbuf, size_t *bufsize,
780                time_char *format, size_t fmtlen,
781                struct tm *tm)
782 {
783     size_t buflen;
784 #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME)
785     /* check that the format string contains only valid directives */
786     for (const time_char *f = strchr(format, '%');
787         f != NULL;
788         f = strchr(f + 2, '%'))
789     {
790         if (f[1] == '#')
791             ++f; /* not documented by python, */
792         if (f[1] == '\0')
793             break;
794         if ((f[1] == 'y') && tm->tm_year < 0) {
795             PyErr_SetString(PyExc_ValueError,
796                             "format %y requires year >= 1900 on Windows");
797             return NULL;
798         }
799     }
800 #elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME)
801     for (const time_char *f = wcschr(format, '%');
802         f != NULL;
803         f = wcschr(f + 2, '%'))
804     {
805         if (f[1] == L'\0')
806             break;
807         /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0))
808            returns "0/" instead of "99" */
809         if (f[1] == L'y' && tm->tm_year < 0) {
810             PyErr_SetString(PyExc_ValueError,
811                             "format %y requires year >= 1900 on AIX");
812             return NULL;
813         }
814     }
815 #endif
816 
817     /* I hate these functions that presume you know how big the output
818      * will be ahead of time...
819      */
820     while (1) {
821         if (*bufsize > PY_SSIZE_T_MAX/sizeof(time_char)) {
822             PyErr_NoMemory();
823             return NULL;
824         }
825         *outbuf = (time_char *)PyMem_Realloc(*outbuf,
826                                              *bufsize*sizeof(time_char));
827         if (*outbuf == NULL) {
828             PyErr_NoMemory();
829             return NULL;
830         }
831 #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
832         errno = 0;
833 #endif
834         _Py_BEGIN_SUPPRESS_IPH
835         buflen = format_time(*outbuf, *bufsize, format, tm);
836         _Py_END_SUPPRESS_IPH
837 #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
838         /* VisualStudio .NET 2005 does this properly */
839         if (buflen == 0 && errno == EINVAL) {
840             PyErr_SetString(PyExc_ValueError, "Invalid format string");
841             return NULL;
842         }
843 #endif
844         if (buflen == 0 && *bufsize < 256 * fmtlen) {
845             *bufsize += *bufsize;
846             continue;
847         }
848         /* If the buffer is 256 times as long as the format,
849            it's probably not failing for lack of room!
850            More likely, the format yields an empty result,
851            e.g. an empty format, or %Z when the timezone
852            is unknown. */
853 #ifdef HAVE_WCSFTIME
854         return PyUnicode_FromWideChar(*outbuf, buflen);
855 #else
856         return PyUnicode_DecodeLocaleAndSize(*outbuf, buflen, "surrogateescape");
857 #endif
858     }
859 }
860 
861 static PyObject *
time_strftime(PyObject * module,PyObject * args)862 time_strftime(PyObject *module, PyObject *args)
863 {
864     PyObject *tup = NULL;
865     struct tm buf;
866     PyObject *format_arg;
867     Py_ssize_t format_size;
868     time_char *format, *outbuf = NULL;
869     size_t fmtlen, bufsize = 1024;
870 
871     memset((void *) &buf, '\0', sizeof(buf));
872 
873     if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup))
874         return NULL;
875 
876     time_module_state *state = get_time_state(module);
877     if (tup == NULL) {
878         time_t tt = time(NULL);
879         if (_PyTime_localtime(tt, &buf) != 0)
880             return NULL;
881     }
882     else if (!gettmarg(state, tup, &buf,
883                        "iiiiiiiii;strftime(): illegal time tuple argument") ||
884              !checktm(&buf))
885     {
886         return NULL;
887     }
888 
889 // Some platforms only support a limited range of years.
890 //
891 // Android works with negative years on the emulator, but fails on some
892 // physical devices (#123017).
893 #if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) \
894     || defined(__VXWORKS__) || defined(__ANDROID__)
895     if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
896         PyErr_SetString(PyExc_ValueError,
897                         "strftime() requires year in [1; 9999]");
898         return NULL;
899     }
900 #endif
901 
902     /* Normalize tm_isdst just in case someone foolishly implements %Z
903        based on the assumption that tm_isdst falls within the range of
904        [-1, 1] */
905     if (buf.tm_isdst < -1)
906         buf.tm_isdst = -1;
907     else if (buf.tm_isdst > 1)
908         buf.tm_isdst = 1;
909 
910     format_size = PyUnicode_GET_LENGTH(format_arg);
911     if ((size_t)format_size > PY_SSIZE_T_MAX/sizeof(time_char) - 1) {
912         PyErr_NoMemory();
913         return NULL;
914     }
915     format = PyMem_Malloc((format_size + 1)*sizeof(time_char));
916     if (format == NULL) {
917         PyErr_NoMemory();
918         return NULL;
919     }
920     _PyUnicodeWriter writer;
921     _PyUnicodeWriter_Init(&writer);
922     writer.overallocate = 1;
923     Py_ssize_t i = 0;
924     while (i < format_size) {
925         fmtlen = 0;
926         for (; i < format_size; i++) {
927             Py_UCS4 c = PyUnicode_READ_CHAR(format_arg, i);
928             if (!c || c > 127) {
929                 break;
930             }
931             format[fmtlen++] = (char)c;
932         }
933         if (fmtlen) {
934             format[fmtlen] = 0;
935             PyObject *unicode = time_strftime1(&outbuf, &bufsize,
936                                                format, fmtlen, &buf);
937             if (unicode == NULL) {
938                 goto error;
939             }
940             if (_PyUnicodeWriter_WriteStr(&writer, unicode) < 0) {
941                 Py_DECREF(unicode);
942                 goto error;
943             }
944             Py_DECREF(unicode);
945         }
946 
947         Py_ssize_t start = i;
948         for (; i < format_size; i++) {
949             Py_UCS4 c = PyUnicode_READ_CHAR(format_arg, i);
950             if (c == '%') {
951                 break;
952             }
953         }
954         if (start < i) {
955             if (_PyUnicodeWriter_WriteSubstring(&writer, format_arg, start, i) < 0) {
956                 goto error;
957             }
958         }
959     }
960 
961     PyMem_Free(outbuf);
962     PyMem_Free(format);
963     return _PyUnicodeWriter_Finish(&writer);
964 error:
965     PyMem_Free(outbuf);
966     PyMem_Free(format);
967     _PyUnicodeWriter_Dealloc(&writer);
968     return NULL;
969 }
970 
971 #undef time_char
972 #undef format_time
973 PyDoc_STRVAR(strftime_doc,
974 "strftime(format[, tuple]) -> string\n\
975 \n\
976 Convert a time tuple to a string according to a format specification.\n\
977 See the library reference manual for formatting codes. When the time tuple\n\
978 is not present, current time as returned by localtime() is used.\n\
979 \n" STRFTIME_FORMAT_CODES);
980 #endif /* HAVE_STRFTIME */
981 
982 static PyObject *
time_strptime(PyObject * self,PyObject * args)983 time_strptime(PyObject *self, PyObject *args)
984 {
985     PyObject *func, *result;
986 
987     func = _PyImport_GetModuleAttrString("_strptime", "_strptime_time");
988     if (!func) {
989         return NULL;
990     }
991 
992     result = PyObject_Call(func, args, NULL);
993     Py_DECREF(func);
994     return result;
995 }
996 
997 
998 PyDoc_STRVAR(strptime_doc,
999 "strptime(string, format) -> struct_time\n\
1000 \n\
1001 Parse a string to a time tuple according to a format specification.\n\
1002 See the library reference manual for formatting codes (same as\n\
1003 strftime()).\n\
1004 \n" STRFTIME_FORMAT_CODES);
1005 
1006 static PyObject *
_asctime(struct tm * timeptr)1007 _asctime(struct tm *timeptr)
1008 {
1009     /* Inspired by Open Group reference implementation available at
1010      * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */
1011     static const char wday_name[7][4] = {
1012         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
1013     };
1014     static const char mon_name[12][4] = {
1015         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1016         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1017     };
1018     return PyUnicode_FromFormat(
1019         "%s %s%3d %.2d:%.2d:%.2d %d",
1020         wday_name[timeptr->tm_wday],
1021         mon_name[timeptr->tm_mon],
1022         timeptr->tm_mday, timeptr->tm_hour,
1023         timeptr->tm_min, timeptr->tm_sec,
1024         1900 + timeptr->tm_year);
1025 }
1026 
1027 static PyObject *
time_asctime(PyObject * module,PyObject * args)1028 time_asctime(PyObject *module, PyObject *args)
1029 {
1030     PyObject *tup = NULL;
1031     struct tm buf;
1032 
1033     if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
1034         return NULL;
1035 
1036     time_module_state *state = get_time_state(module);
1037     if (tup == NULL) {
1038         time_t tt = time(NULL);
1039         if (_PyTime_localtime(tt, &buf) != 0)
1040             return NULL;
1041     }
1042     else if (!gettmarg(state, tup, &buf,
1043                        "iiiiiiiii;asctime(): illegal time tuple argument") ||
1044              !checktm(&buf))
1045     {
1046         return NULL;
1047     }
1048     return _asctime(&buf);
1049 }
1050 
1051 PyDoc_STRVAR(asctime_doc,
1052 "asctime([tuple]) -> string\n\
1053 \n\
1054 Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
1055 When the time tuple is not present, current time as returned by localtime()\n\
1056 is used.");
1057 
1058 static PyObject *
time_ctime(PyObject * self,PyObject * args)1059 time_ctime(PyObject *self, PyObject *args)
1060 {
1061     time_t tt;
1062     struct tm buf;
1063     if (!parse_time_t_args(args, "|O:ctime", &tt))
1064         return NULL;
1065     if (_PyTime_localtime(tt, &buf) != 0)
1066         return NULL;
1067     return _asctime(&buf);
1068 }
1069 
1070 PyDoc_STRVAR(ctime_doc,
1071 "ctime(seconds) -> string\n\
1072 \n\
1073 Convert a time in seconds since the Epoch to a string in local time.\n\
1074 This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
1075 not present, current time as returned by localtime() is used.");
1076 
1077 #ifdef HAVE_MKTIME
1078 static PyObject *
time_mktime(PyObject * module,PyObject * tm_tuple)1079 time_mktime(PyObject *module, PyObject *tm_tuple)
1080 {
1081     struct tm tm;
1082     time_t tt;
1083 
1084     time_module_state *state = get_time_state(module);
1085     if (!gettmarg(state, tm_tuple, &tm,
1086                   "iiiiiiiii;mktime(): illegal time tuple argument"))
1087     {
1088         return NULL;
1089     }
1090 
1091 #if defined(_AIX) || (defined(__VXWORKS__) && !defined(_WRS_CONFIG_LP64))
1092     /* bpo-19748: AIX mktime() valid range is 00:00:00 UTC, January 1, 1970
1093        to 03:14:07 UTC, January 19, 2038. Thanks to the workaround below,
1094        it is possible to support years in range [1902; 2037] */
1095     if (tm.tm_year < 2 || tm.tm_year > 137) {
1096         /* bpo-19748: On AIX, mktime() does not report overflow error
1097            for timestamp < -2^31 or timestamp > 2**31-1. VxWorks has the
1098            same issue when working in 32 bit mode. */
1099         PyErr_SetString(PyExc_OverflowError,
1100                         "mktime argument out of range");
1101         return NULL;
1102     }
1103 #endif
1104 
1105 #ifdef _AIX
1106     /* bpo-34373: AIX mktime() has an integer overflow for years in range
1107        [1902; 1969]. Workaround the issue by using a year greater or equal than
1108        1970 (tm_year >= 70): mktime() behaves correctly in that case
1109        (ex: properly report errors). tm_year and tm_wday are adjusted after
1110        mktime() call. */
1111     int orig_tm_year = tm.tm_year;
1112     int delta_days = 0;
1113     while (tm.tm_year < 70) {
1114         /* Use 4 years to account properly leap years */
1115         tm.tm_year += 4;
1116         delta_days -= (366 + (365 * 3));
1117     }
1118 #endif
1119 
1120     tm.tm_wday = -1;  /* sentinel; original value ignored */
1121     tt = mktime(&tm);
1122 
1123     /* Return value of -1 does not necessarily mean an error, but tm_wday
1124      * cannot remain set to -1 if mktime succeeded. */
1125     if (tt == (time_t)(-1)
1126         /* Return value of -1 does not necessarily mean an error, but
1127          * tm_wday cannot remain set to -1 if mktime succeeded. */
1128         && tm.tm_wday == -1)
1129     {
1130         PyErr_SetString(PyExc_OverflowError,
1131                         "mktime argument out of range");
1132         return NULL;
1133     }
1134 
1135 #ifdef _AIX
1136     if (delta_days != 0) {
1137         tm.tm_year = orig_tm_year;
1138         if (tm.tm_wday != -1) {
1139             tm.tm_wday = (tm.tm_wday + delta_days) % 7;
1140         }
1141         tt += delta_days * (24 * 3600);
1142     }
1143 #endif
1144 
1145     return PyFloat_FromDouble((double)tt);
1146 }
1147 
1148 PyDoc_STRVAR(mktime_doc,
1149 "mktime(tuple) -> floating-point number\n\
1150 \n\
1151 Convert a time tuple in local time to seconds since the Epoch.\n\
1152 Note that mktime(gmtime(0)) will not generally return zero for most\n\
1153 time zones; instead the returned value will either be equal to that\n\
1154 of the timezone or altzone attributes on the time module.");
1155 #endif /* HAVE_MKTIME */
1156 
1157 #ifdef HAVE_WORKING_TZSET
1158 static int init_timezone(PyObject *module);
1159 
1160 static PyObject *
time_tzset(PyObject * self,PyObject * unused)1161 time_tzset(PyObject *self, PyObject *unused)
1162 {
1163     PyObject* m;
1164 
1165     m = PyImport_ImportModule("time");
1166     if (m == NULL) {
1167         return NULL;
1168     }
1169 
1170 #if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
1171     tzset();
1172 #endif
1173 
1174     /* Reset timezone, altzone, daylight and tzname */
1175     if (init_timezone(m) < 0) {
1176          return NULL;
1177     }
1178     Py_DECREF(m);
1179     if (PyErr_Occurred())
1180         return NULL;
1181 
1182     Py_RETURN_NONE;
1183 }
1184 
1185 PyDoc_STRVAR(tzset_doc,
1186 "tzset()\n\
1187 \n\
1188 Initialize, or reinitialize, the local timezone to the value stored in\n\
1189 os.environ['TZ']. The TZ environment variable should be specified in\n\
1190 standard Unix timezone format as documented in the tzset man page\n\
1191 (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
1192 fall back to UTC. If the TZ environment variable is not set, the local\n\
1193 timezone is set to the systems best guess of wallclock time.\n\
1194 Changing the TZ environment variable without calling tzset *may* change\n\
1195 the local timezone used by methods such as localtime, but this behaviour\n\
1196 should not be relied on.");
1197 #endif /* HAVE_WORKING_TZSET */
1198 
1199 
1200 static PyObject *
time_monotonic(PyObject * self,PyObject * unused)1201 time_monotonic(PyObject *self, PyObject *unused)
1202 {
1203     PyTime_t t;
1204     if (PyTime_Monotonic(&t) < 0) {
1205         return NULL;
1206     }
1207     return _PyFloat_FromPyTime(t);
1208 }
1209 
1210 PyDoc_STRVAR(monotonic_doc,
1211 "monotonic() -> float\n\
1212 \n\
1213 Monotonic clock, cannot go backward.");
1214 
1215 static PyObject *
time_monotonic_ns(PyObject * self,PyObject * unused)1216 time_monotonic_ns(PyObject *self, PyObject *unused)
1217 {
1218     PyTime_t t;
1219     if (PyTime_Monotonic(&t) < 0) {
1220         return NULL;
1221     }
1222     return _PyTime_AsLong(t);
1223 }
1224 
1225 PyDoc_STRVAR(monotonic_ns_doc,
1226 "monotonic_ns() -> int\n\
1227 \n\
1228 Monotonic clock, cannot go backward, as nanoseconds.");
1229 
1230 
1231 static PyObject *
time_perf_counter(PyObject * self,PyObject * unused)1232 time_perf_counter(PyObject *self, PyObject *unused)
1233 {
1234     PyTime_t t;
1235     if (PyTime_PerfCounter(&t) < 0) {
1236         return NULL;
1237     }
1238     return _PyFloat_FromPyTime(t);
1239 }
1240 
1241 PyDoc_STRVAR(perf_counter_doc,
1242 "perf_counter() -> float\n\
1243 \n\
1244 Performance counter for benchmarking.");
1245 
1246 
1247 static PyObject *
time_perf_counter_ns(PyObject * self,PyObject * unused)1248 time_perf_counter_ns(PyObject *self, PyObject *unused)
1249 {
1250     PyTime_t t;
1251     if (PyTime_PerfCounter(&t) < 0) {
1252         return NULL;
1253     }
1254     return _PyTime_AsLong(t);
1255 }
1256 
1257 PyDoc_STRVAR(perf_counter_ns_doc,
1258 "perf_counter_ns() -> int\n\
1259 \n\
1260 Performance counter for benchmarking as nanoseconds.");
1261 
1262 
1263 // gh-115714: Don't use times() on WASI.
1264 #if defined(HAVE_TIMES) && !defined(__wasi__)
1265 static int
process_time_times(time_module_state * state,PyTime_t * tp,_Py_clock_info_t * info)1266 process_time_times(time_module_state *state, PyTime_t *tp,
1267                    _Py_clock_info_t *info)
1268 {
1269     _PyTimeFraction *base = &state->times_base;
1270 
1271     struct tms process;
1272     if (times(&process) == (clock_t)-1) {
1273         return 0;
1274     }
1275 
1276     if (info) {
1277         info->implementation = "times()";
1278         info->resolution = _PyTimeFraction_Resolution(base);
1279         info->monotonic = 1;
1280         info->adjustable = 0;
1281     }
1282 
1283     PyTime_t ns;
1284     ns = _PyTimeFraction_Mul(process.tms_utime, base);
1285     ns += _PyTimeFraction_Mul(process.tms_stime, base);
1286     *tp = ns;
1287     return 1;
1288 }
1289 #endif
1290 
1291 
1292 static int
py_process_time(time_module_state * state,PyTime_t * tp,_Py_clock_info_t * info)1293 py_process_time(time_module_state *state, PyTime_t *tp,
1294                 _Py_clock_info_t *info)
1295 {
1296 #if defined(MS_WINDOWS)
1297     HANDLE process;
1298     FILETIME creation_time, exit_time, kernel_time, user_time;
1299     ULARGE_INTEGER large;
1300     PyTime_t ktime, utime;
1301     BOOL ok;
1302 
1303     process = GetCurrentProcess();
1304     ok = GetProcessTimes(process, &creation_time, &exit_time,
1305                          &kernel_time, &user_time);
1306     if (!ok) {
1307         PyErr_SetFromWindowsErr(0);
1308         return -1;
1309     }
1310 
1311     if (info) {
1312         info->implementation = "GetProcessTimes()";
1313         info->resolution = 1e-7;
1314         info->monotonic = 1;
1315         info->adjustable = 0;
1316     }
1317 
1318     large.u.LowPart = kernel_time.dwLowDateTime;
1319     large.u.HighPart = kernel_time.dwHighDateTime;
1320     ktime = large.QuadPart;
1321 
1322     large.u.LowPart = user_time.dwLowDateTime;
1323     large.u.HighPart = user_time.dwHighDateTime;
1324     utime = large.QuadPart;
1325 
1326     /* ktime and utime have a resolution of 100 nanoseconds */
1327     *tp = (ktime + utime) * 100;
1328     return 0;
1329 #else
1330 
1331     /* clock_gettime */
1332 // gh-115714: Don't use CLOCK_PROCESS_CPUTIME_ID on WASI.
1333 /* CLOCK_PROF is defined on NetBSD, but not supported.
1334  * CLOCK_PROCESS_CPUTIME_ID is broken on NetBSD for the same reason as
1335  * CLOCK_THREAD_CPUTIME_ID (see comment below).
1336  */
1337 #if defined(HAVE_CLOCK_GETTIME) \
1338     && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF)) \
1339     && !defined(__wasi__) \
1340     && !defined(__NetBSD__)
1341     struct timespec ts;
1342 
1343     if (HAVE_CLOCK_GETTIME_RUNTIME) {
1344 
1345 #ifdef CLOCK_PROF
1346         const clockid_t clk_id = CLOCK_PROF;
1347         const char *function = "clock_gettime(CLOCK_PROF)";
1348 #else
1349         const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
1350         const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
1351 #endif
1352 
1353         if (clock_gettime(clk_id, &ts) == 0) {
1354             if (info) {
1355                 struct timespec res;
1356                 info->implementation = function;
1357                 info->monotonic = 1;
1358                 info->adjustable = 0;
1359                 if (clock_getres(clk_id, &res)) {
1360                     PyErr_SetFromErrno(PyExc_OSError);
1361                     return -1;
1362                 }
1363                 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1364             }
1365 
1366             if (_PyTime_FromTimespec(tp, &ts) < 0) {
1367                 return -1;
1368             }
1369             return 0;
1370         }
1371     }
1372 #endif
1373 
1374     /* getrusage(RUSAGE_SELF) */
1375 #if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRUSAGE)
1376     struct rusage ru;
1377 
1378     if (getrusage(RUSAGE_SELF, &ru) == 0) {
1379         PyTime_t utime, stime;
1380 
1381         if (info) {
1382             info->implementation = "getrusage(RUSAGE_SELF)";
1383             info->monotonic = 1;
1384             info->adjustable = 0;
1385             info->resolution = 1e-6;
1386         }
1387 
1388         if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) {
1389             return -1;
1390         }
1391         if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) {
1392             return -1;
1393         }
1394 
1395         PyTime_t total = utime + stime;
1396         *tp = total;
1397         return 0;
1398     }
1399 #endif
1400 
1401     /* times() */
1402 // gh-115714: Don't use times() on WASI.
1403 #if defined(HAVE_TIMES) && !defined(__wasi__)
1404     int res = process_time_times(state, tp, info);
1405     if (res < 0) {
1406         return -1;
1407     }
1408     if (res == 1) {
1409         return 0;
1410     }
1411     // times() failed, ignore failure
1412 #endif
1413 
1414     /* clock(). Python 3 requires clock() to build (see gh-66814) */
1415     return py_clock(state, tp, info);
1416 #endif
1417 }
1418 
1419 static PyObject *
time_process_time(PyObject * module,PyObject * unused)1420 time_process_time(PyObject *module, PyObject *unused)
1421 {
1422     time_module_state *state = get_time_state(module);
1423     PyTime_t t;
1424     if (py_process_time(state, &t, NULL) < 0) {
1425         return NULL;
1426     }
1427     return _PyFloat_FromPyTime(t);
1428 }
1429 
1430 PyDoc_STRVAR(process_time_doc,
1431 "process_time() -> float\n\
1432 \n\
1433 Process time for profiling: sum of the kernel and user-space CPU time.");
1434 
1435 static PyObject *
time_process_time_ns(PyObject * module,PyObject * unused)1436 time_process_time_ns(PyObject *module, PyObject *unused)
1437 {
1438     time_module_state *state = get_time_state(module);
1439     PyTime_t t;
1440     if (py_process_time(state, &t, NULL) < 0) {
1441         return NULL;
1442     }
1443     return _PyTime_AsLong(t);
1444 }
1445 
1446 PyDoc_STRVAR(process_time_ns_doc,
1447 "process_time() -> int\n\
1448 \n\
1449 Process time for profiling as nanoseconds:\n\
1450 sum of the kernel and user-space CPU time.");
1451 
1452 
1453 #if defined(MS_WINDOWS)
1454 #define HAVE_THREAD_TIME
1455 static int
_PyTime_GetThreadTimeWithInfo(PyTime_t * tp,_Py_clock_info_t * info)1456 _PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1457 {
1458     HANDLE thread;
1459     FILETIME creation_time, exit_time, kernel_time, user_time;
1460     ULARGE_INTEGER large;
1461     PyTime_t ktime, utime;
1462     BOOL ok;
1463 
1464     thread =  GetCurrentThread();
1465     ok = GetThreadTimes(thread, &creation_time, &exit_time,
1466                         &kernel_time, &user_time);
1467     if (!ok) {
1468         PyErr_SetFromWindowsErr(0);
1469         return -1;
1470     }
1471 
1472     if (info) {
1473         info->implementation = "GetThreadTimes()";
1474         info->resolution = 1e-7;
1475         info->monotonic = 1;
1476         info->adjustable = 0;
1477     }
1478 
1479     large.u.LowPart = kernel_time.dwLowDateTime;
1480     large.u.HighPart = kernel_time.dwHighDateTime;
1481     ktime = large.QuadPart;
1482 
1483     large.u.LowPart = user_time.dwLowDateTime;
1484     large.u.HighPart = user_time.dwHighDateTime;
1485     utime = large.QuadPart;
1486 
1487     /* ktime and utime have a resolution of 100 nanoseconds */
1488     *tp = (ktime + utime) * 100;
1489     return 0;
1490 }
1491 
1492 #elif defined(_AIX)
1493 #define HAVE_THREAD_TIME
1494 static int
_PyTime_GetThreadTimeWithInfo(PyTime_t * tp,_Py_clock_info_t * info)1495 _PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1496 {
1497     /* bpo-40192: On AIX, thread_cputime() is preferred: it has nanosecond
1498        resolution, whereas clock_gettime(CLOCK_THREAD_CPUTIME_ID)
1499        has a resolution of 10 ms. */
1500     thread_cputime_t tc;
1501     if (thread_cputime(-1, &tc) != 0) {
1502         PyErr_SetFromErrno(PyExc_OSError);
1503         return -1;
1504     }
1505 
1506     if (info) {
1507         info->implementation = "thread_cputime()";
1508         info->monotonic = 1;
1509         info->adjustable = 0;
1510         info->resolution = 1e-9;
1511     }
1512     *tp = (tc.stime + tc.utime);
1513     return 0;
1514 }
1515 
1516 #elif defined(__sun) && defined(__SVR4)
1517 #define HAVE_THREAD_TIME
1518 static int
_PyTime_GetThreadTimeWithInfo(PyTime_t * tp,_Py_clock_info_t * info)1519 _PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1520 {
1521     /* bpo-35455: On Solaris, CLOCK_THREAD_CPUTIME_ID clock is not always
1522        available; use gethrvtime() to substitute this functionality. */
1523     if (info) {
1524         info->implementation = "gethrvtime()";
1525         info->resolution = 1e-9;
1526         info->monotonic = 1;
1527         info->adjustable = 0;
1528     }
1529     *tp = gethrvtime();
1530     return 0;
1531 }
1532 
1533 /* CLOCK_THREAD_CPUTIME_ID is broken on NetBSD: the result of clock_gettime()
1534  * includes the sleeping time, that defeats the purpose of the clock.
1535  * Also, clock_getres() does not support it.
1536  * https://github.com/python/cpython/issues/123978
1537  * https://gnats.netbsd.org/57512
1538  */
1539 #elif defined(HAVE_CLOCK_GETTIME) && \
1540       defined(CLOCK_THREAD_CPUTIME_ID) && \
1541       !defined(__EMSCRIPTEN__) && !defined(__wasi__) && \
1542       !defined(__NetBSD__)
1543 #define HAVE_THREAD_TIME
1544 
1545 #if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability)
1546 static int
1547 _PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1548      __attribute__((availability(macos, introduced=10.12)))
1549      __attribute__((availability(ios, introduced=10.0)))
1550      __attribute__((availability(tvos, introduced=10.0)))
1551      __attribute__((availability(watchos, introduced=3.0)));
1552 #endif
1553 
1554 static int
_PyTime_GetThreadTimeWithInfo(PyTime_t * tp,_Py_clock_info_t * info)1555 _PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1556 {
1557     struct timespec ts;
1558     const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID;
1559     const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)";
1560 
1561     if (clock_gettime(clk_id, &ts)) {
1562         PyErr_SetFromErrno(PyExc_OSError);
1563         return -1;
1564     }
1565     if (info) {
1566         struct timespec res;
1567         info->implementation = function;
1568         info->monotonic = 1;
1569         info->adjustable = 0;
1570         if (clock_getres(clk_id, &res)) {
1571             PyErr_SetFromErrno(PyExc_OSError);
1572             return -1;
1573         }
1574         info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1575     }
1576 
1577     if (_PyTime_FromTimespec(tp, &ts) < 0) {
1578         return -1;
1579     }
1580     return 0;
1581 }
1582 #endif
1583 
1584 #ifdef HAVE_THREAD_TIME
1585 #ifdef __APPLE__
1586 /*
1587  * The clock_* functions will be removed from the module
1588  * dict entirely when the C API is not available.
1589  */
1590 #pragma clang diagnostic push
1591 #pragma clang diagnostic ignored "-Wunguarded-availability"
1592 #endif
1593 
1594 static PyObject *
time_thread_time(PyObject * self,PyObject * unused)1595 time_thread_time(PyObject *self, PyObject *unused)
1596 {
1597     PyTime_t t;
1598     if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
1599         return NULL;
1600     }
1601     return _PyFloat_FromPyTime(t);
1602 }
1603 
1604 PyDoc_STRVAR(thread_time_doc,
1605 "thread_time() -> float\n\
1606 \n\
1607 Thread time for profiling: sum of the kernel and user-space CPU time.");
1608 
1609 static PyObject *
time_thread_time_ns(PyObject * self,PyObject * unused)1610 time_thread_time_ns(PyObject *self, PyObject *unused)
1611 {
1612     PyTime_t t;
1613     if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
1614         return NULL;
1615     }
1616     return _PyTime_AsLong(t);
1617 }
1618 
1619 PyDoc_STRVAR(thread_time_ns_doc,
1620 "thread_time() -> int\n\
1621 \n\
1622 Thread time for profiling as nanoseconds:\n\
1623 sum of the kernel and user-space CPU time.");
1624 
1625 #ifdef __APPLE__
1626 #pragma clang diagnostic pop
1627 #endif
1628 
1629 #endif
1630 
1631 
1632 static PyObject *
time_get_clock_info(PyObject * module,PyObject * args)1633 time_get_clock_info(PyObject *module, PyObject *args)
1634 {
1635     char *name;
1636     _Py_clock_info_t info;
1637     PyObject *obj = NULL, *dict, *ns;
1638     PyTime_t t;
1639 
1640     if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) {
1641         return NULL;
1642     }
1643 
1644 #ifdef Py_DEBUG
1645     info.implementation = NULL;
1646     info.monotonic = -1;
1647     info.adjustable = -1;
1648     info.resolution = -1.0;
1649 #else
1650     info.implementation = "";
1651     info.monotonic = 0;
1652     info.adjustable = 0;
1653     info.resolution = 1.0;
1654 #endif
1655 
1656     if (strcmp(name, "time") == 0) {
1657         if (_PyTime_TimeWithInfo(&t, &info) < 0) {
1658             return NULL;
1659         }
1660     }
1661     else if (strcmp(name, "monotonic") == 0) {
1662         if (_PyTime_MonotonicWithInfo(&t, &info) < 0) {
1663             return NULL;
1664         }
1665     }
1666     else if (strcmp(name, "perf_counter") == 0) {
1667         if (_PyTime_PerfCounterWithInfo(&t, &info) < 0) {
1668             return NULL;
1669         }
1670     }
1671     else if (strcmp(name, "process_time") == 0) {
1672         time_module_state *state = get_time_state(module);
1673         if (py_process_time(state, &t, &info) < 0) {
1674             return NULL;
1675         }
1676     }
1677 #ifdef HAVE_THREAD_TIME
1678     else if (strcmp(name, "thread_time") == 0) {
1679 
1680 #ifdef __APPLE__
1681         if (HAVE_CLOCK_GETTIME_RUNTIME) {
1682 #endif
1683             if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) {
1684                 return NULL;
1685             }
1686 #ifdef __APPLE__
1687         } else {
1688             PyErr_SetString(PyExc_ValueError, "unknown clock");
1689             return NULL;
1690         }
1691 #endif
1692     }
1693 #endif
1694     else {
1695         PyErr_SetString(PyExc_ValueError, "unknown clock");
1696         return NULL;
1697     }
1698 
1699     dict = PyDict_New();
1700     if (dict == NULL) {
1701         return NULL;
1702     }
1703 
1704     assert(info.implementation != NULL);
1705     obj = PyUnicode_FromString(info.implementation);
1706     if (obj == NULL) {
1707         goto error;
1708     }
1709     if (PyDict_SetItemString(dict, "implementation", obj) == -1) {
1710         goto error;
1711     }
1712     Py_CLEAR(obj);
1713 
1714     assert(info.monotonic != -1);
1715     obj = PyBool_FromLong(info.monotonic);
1716     if (obj == NULL) {
1717         goto error;
1718     }
1719     if (PyDict_SetItemString(dict, "monotonic", obj) == -1) {
1720         goto error;
1721     }
1722     Py_CLEAR(obj);
1723 
1724     assert(info.adjustable != -1);
1725     obj = PyBool_FromLong(info.adjustable);
1726     if (obj == NULL) {
1727         goto error;
1728     }
1729     if (PyDict_SetItemString(dict, "adjustable", obj) == -1) {
1730         goto error;
1731     }
1732     Py_CLEAR(obj);
1733 
1734     assert(info.resolution > 0.0);
1735     assert(info.resolution <= 1.0);
1736     obj = PyFloat_FromDouble(info.resolution);
1737     if (obj == NULL) {
1738         goto error;
1739     }
1740     if (PyDict_SetItemString(dict, "resolution", obj) == -1) {
1741         goto error;
1742     }
1743     Py_CLEAR(obj);
1744 
1745     ns = _PyNamespace_New(dict);
1746     Py_DECREF(dict);
1747     return ns;
1748 
1749 error:
1750     Py_DECREF(dict);
1751     Py_XDECREF(obj);
1752     return NULL;
1753 }
1754 
1755 PyDoc_STRVAR(get_clock_info_doc,
1756 "get_clock_info(name: str) -> dict\n\
1757 \n\
1758 Get information of the specified clock.");
1759 
1760 #ifndef HAVE_DECL_TZNAME
1761 static void
get_zone(char * zone,int n,struct tm * p)1762 get_zone(char *zone, int n, struct tm *p)
1763 {
1764 #ifdef HAVE_STRUCT_TM_TM_ZONE
1765     strncpy(zone, p->tm_zone ? p->tm_zone : "   ", n);
1766 #else
1767     tzset();
1768     strftime(zone, n, "%Z", p);
1769 #endif
1770 }
1771 
1772 static time_t
get_gmtoff(time_t t,struct tm * p)1773 get_gmtoff(time_t t, struct tm *p)
1774 {
1775 #ifdef HAVE_STRUCT_TM_TM_ZONE
1776     return p->tm_gmtoff;
1777 #else
1778     return timegm(p) - t;
1779 #endif
1780 }
1781 #endif // !HAVE_DECL_TZNAME
1782 
1783 static int
init_timezone(PyObject * m)1784 init_timezone(PyObject *m)
1785 {
1786 #define ADD_INT(NAME, VALUE) do {                       \
1787     if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) {  \
1788         return -1;                                      \
1789     }                                                   \
1790 } while (0)
1791 
1792     assert(!PyErr_Occurred());
1793 
1794     /* This code moved from PyInit_time wholesale to allow calling it from
1795     time_tzset. In the future, some parts of it can be moved back
1796     (for platforms that don't HAVE_WORKING_TZSET, when we know what they
1797     are), and the extraneous calls to tzset(3) should be removed.
1798     I haven't done this yet, as I don't want to change this code as
1799     little as possible when introducing the time.tzset and time.tzsetwall
1800     methods. This should simply be a method of doing the following once,
1801     at the top of this function and removing the call to tzset() from
1802     time_tzset():
1803 
1804         #ifdef HAVE_TZSET
1805         tzset()
1806         #endif
1807 
1808     And I'm lazy and hate C so nyer.
1809      */
1810 #ifdef HAVE_DECL_TZNAME
1811     PyObject *otz0, *otz1;
1812 #if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
1813     tzset();
1814 #endif
1815     ADD_INT("timezone", _Py_timezone);
1816 #ifdef HAVE_ALTZONE
1817     ADD_INT("altzone", altzone);
1818 #else
1819     ADD_INT("altzone", _Py_timezone-3600);
1820 #endif
1821     ADD_INT("daylight", _Py_daylight);
1822 #ifdef MS_WINDOWS
1823     TIME_ZONE_INFORMATION tzinfo = {0};
1824     GetTimeZoneInformation(&tzinfo);
1825     otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1);
1826     if (otz0 == NULL) {
1827         return -1;
1828     }
1829     otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1);
1830     if (otz1 == NULL) {
1831         Py_DECREF(otz0);
1832         return -1;
1833     }
1834 #else
1835     otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape");
1836     if (otz0 == NULL) {
1837         return -1;
1838     }
1839     otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape");
1840     if (otz1 == NULL) {
1841         Py_DECREF(otz0);
1842         return -1;
1843     }
1844 #endif // MS_WINDOWS
1845     if (PyModule_Add(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)) < 0) {
1846         return -1;
1847     }
1848 #else // !HAVE_DECL_TZNAME
1849     static const time_t YEAR = (365 * 24 + 6) * 3600;
1850     time_t t;
1851     struct tm p;
1852     time_t janzone_t, julyzone_t;
1853     char janname[10], julyname[10];
1854     t = (time((time_t *)0) / YEAR) * YEAR;
1855     _PyTime_localtime(t, &p);
1856     get_zone(janname, 9, &p);
1857     janzone_t = -get_gmtoff(t, &p);
1858     janname[9] = '\0';
1859     t += YEAR/2;
1860     _PyTime_localtime(t, &p);
1861     get_zone(julyname, 9, &p);
1862     julyzone_t = -get_gmtoff(t, &p);
1863     julyname[9] = '\0';
1864 
1865     /* Sanity check, don't check for the validity of timezones.
1866        In practice, it should be more in range -12 hours .. +14 hours. */
1867 #define MAX_TIMEZONE (48 * 3600)
1868     if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE
1869         || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE)
1870     {
1871         PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset");
1872         return -1;
1873     }
1874     int janzone = (int)janzone_t;
1875     int julyzone = (int)julyzone_t;
1876 
1877     PyObject *tzname_obj;
1878     if (janzone < julyzone) {
1879         /* DST is reversed in the southern hemisphere */
1880         ADD_INT("timezone", julyzone);
1881         ADD_INT("altzone", janzone);
1882         ADD_INT("daylight", janzone != julyzone);
1883         tzname_obj = Py_BuildValue("(zz)", julyname, janname);
1884     } else {
1885         ADD_INT("timezone", janzone);
1886         ADD_INT("altzone", julyzone);
1887         ADD_INT("daylight", janzone != julyzone);
1888         tzname_obj = Py_BuildValue("(zz)", janname, julyname);
1889     }
1890     if (PyModule_Add(m, "tzname", tzname_obj) < 0) {
1891         return -1;
1892     }
1893 #endif // !HAVE_DECL_TZNAME
1894 #undef ADD_INT
1895 
1896     if (PyErr_Occurred()) {
1897         return -1;
1898     }
1899     return 0;
1900 }
1901 
1902 
1903 // Include Argument Clinic code after defining converters such as
1904 // time_clockid_converter().
1905 #include "clinic/timemodule.c.h"
1906 
1907 static PyMethodDef time_methods[] = {
1908     {"time",            time_time, METH_NOARGS, time_doc},
1909     {"time_ns",         time_time_ns, METH_NOARGS, time_ns_doc},
1910 #ifdef HAVE_CLOCK_GETTIME
1911     TIME_CLOCK_GETTIME_METHODDEF
1912     TIME_CLOCK_GETTIME_NS_METHODDEF
1913 #endif
1914 #ifdef HAVE_CLOCK_SETTIME
1915     {"clock_settime",   time_clock_settime, METH_VARARGS, clock_settime_doc},
1916     {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc},
1917 #endif
1918 #ifdef HAVE_CLOCK_GETRES
1919     {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
1920 #endif
1921 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
1922     {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc},
1923 #endif
1924     {"sleep",           time_sleep, METH_O, sleep_doc},
1925     {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
1926     {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
1927     {"asctime",         time_asctime, METH_VARARGS, asctime_doc},
1928     {"ctime",           time_ctime, METH_VARARGS, ctime_doc},
1929 #ifdef HAVE_MKTIME
1930     {"mktime",          time_mktime, METH_O, mktime_doc},
1931 #endif
1932 #ifdef HAVE_STRFTIME
1933     {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
1934 #endif
1935     {"strptime",        time_strptime, METH_VARARGS, strptime_doc},
1936 #ifdef HAVE_WORKING_TZSET
1937     {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
1938 #endif
1939     {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
1940     {"monotonic_ns",    time_monotonic_ns, METH_NOARGS, monotonic_ns_doc},
1941     {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
1942     {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc},
1943 #ifdef HAVE_THREAD_TIME
1944     {"thread_time",     time_thread_time, METH_NOARGS, thread_time_doc},
1945     {"thread_time_ns",  time_thread_time_ns, METH_NOARGS, thread_time_ns_doc},
1946 #endif
1947     {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
1948     {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc},
1949     {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},
1950     {NULL,              NULL}           /* sentinel */
1951 };
1952 
1953 
1954 PyDoc_STRVAR(module_doc,
1955 "This module provides various functions to manipulate time values.\n\
1956 \n\
1957 There are two standard representations of time.  One is the number\n\
1958 of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\n\
1959 or a floating-point number (to represent fractions of seconds).\n\
1960 The epoch is the point where the time starts, the return value of time.gmtime(0).\n\
1961 It is January 1, 1970, 00:00:00 (UTC) on all platforms.\n\
1962 \n\
1963 The other representation is a tuple of 9 integers giving local time.\n\
1964 The tuple items are:\n\
1965   year (including century, e.g. 1998)\n\
1966   month (1-12)\n\
1967   day (1-31)\n\
1968   hours (0-23)\n\
1969   minutes (0-59)\n\
1970   seconds (0-59)\n\
1971   weekday (0-6, Monday is 0)\n\
1972   Julian day (day in the year, 1-366)\n\
1973   DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
1974 If the DST flag is 0, the time is given in the regular time zone;\n\
1975 if it is 1, the time is given in the DST time zone;\n\
1976 if it is -1, mktime() should guess based on the date and time.\n");
1977 
1978 
1979 static int
time_exec(PyObject * module)1980 time_exec(PyObject *module)
1981 {
1982     time_module_state *state = get_time_state(module);
1983 #if defined(__APPLE__) && defined(HAVE_CLOCK_GETTIME)
1984     if (HAVE_CLOCK_GETTIME_RUNTIME) {
1985         /* pass: ^^^ cannot use '!' here */
1986     } else {
1987         PyObject* dct = PyModule_GetDict(module);
1988         if (dct == NULL) {
1989             return -1;
1990         }
1991 
1992         if (PyDict_PopString(dct, "clock_gettime", NULL) < 0) {
1993             return -1;
1994         }
1995         if (PyDict_PopString(dct, "clock_gettime_ns", NULL) < 0) {
1996             return -1;
1997         }
1998         if (PyDict_PopString(dct, "clock_settime", NULL) < 0) {
1999             return -1;
2000         }
2001         if (PyDict_PopString(dct, "clock_settime_ns", NULL) < 0) {
2002             return -1;
2003         }
2004         if (PyDict_PopString(dct, "clock_getres", NULL) < 0) {
2005             return -1;
2006         }
2007     }
2008 #endif
2009 #if defined(__APPLE__) && defined(HAVE_THREAD_TIME)
2010     if (HAVE_CLOCK_GETTIME_RUNTIME) {
2011         /* pass: ^^^ cannot use '!' here */
2012     } else {
2013         PyObject* dct = PyModule_GetDict(module);
2014 
2015         if (PyDict_PopString(dct, "thread_time", NULL) < 0) {
2016             return -1;
2017         }
2018         if (PyDict_PopString(dct, "thread_time_ns", NULL) < 0) {
2019             return -1;
2020         }
2021     }
2022 #endif
2023     /* Set, or reset, module variables like time.timezone */
2024     if (init_timezone(module) < 0) {
2025         return -1;
2026     }
2027 
2028 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES)
2029     if (HAVE_CLOCK_GETTIME_RUNTIME) {
2030 
2031 #ifdef CLOCK_REALTIME
2032         if (PyModule_AddIntMacro(module, CLOCK_REALTIME) < 0) {
2033             return -1;
2034         }
2035 #endif
2036 #ifdef CLOCK_MONOTONIC
2037         if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC) < 0) {
2038             return -1;
2039         }
2040 #endif
2041 #ifdef CLOCK_MONOTONIC_RAW
2042         if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW) < 0) {
2043             return -1;
2044         }
2045 #endif
2046 #ifdef CLOCK_HIGHRES
2047         if (PyModule_AddIntMacro(module, CLOCK_HIGHRES) < 0) {
2048             return -1;
2049         }
2050 #endif
2051 #ifdef CLOCK_PROCESS_CPUTIME_ID
2052         if (PyModule_AddIntMacro(module, CLOCK_PROCESS_CPUTIME_ID) < 0) {
2053             return -1;
2054         }
2055 #endif
2056 #ifdef CLOCK_THREAD_CPUTIME_ID
2057         if (PyModule_AddIntMacro(module, CLOCK_THREAD_CPUTIME_ID) < 0) {
2058             return -1;
2059         }
2060 #endif
2061 #ifdef CLOCK_PROF
2062         if (PyModule_AddIntMacro(module, CLOCK_PROF) < 0) {
2063             return -1;
2064         }
2065 #endif
2066 #ifdef CLOCK_BOOTTIME
2067         if (PyModule_AddIntMacro(module, CLOCK_BOOTTIME) < 0) {
2068             return -1;
2069         }
2070 #endif
2071 #ifdef CLOCK_TAI
2072         if (PyModule_AddIntMacro(module, CLOCK_TAI) < 0) {
2073             return -1;
2074         }
2075 #endif
2076 #ifdef CLOCK_UPTIME
2077         if (PyModule_AddIntMacro(module, CLOCK_UPTIME) < 0) {
2078             return -1;
2079         }
2080 #endif
2081 #ifdef CLOCK_UPTIME_RAW
2082         if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW) < 0) {
2083             return -1;
2084         }
2085 #endif
2086 #ifdef CLOCK_MONOTONIC_RAW_APPROX
2087         if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW_APPROX) < 0) {
2088             return -1;
2089         }
2090 #endif
2091 #ifdef CLOCK_UPTIME_RAW_APPROX
2092         if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW_APPROX) < 0) {
2093             return -1;
2094         }
2095 #endif
2096     }
2097 
2098 #endif  /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */
2099 
2100     if (PyModule_AddIntConstant(module, "_STRUCT_TM_ITEMS", 11)) {
2101         return -1;
2102     }
2103 
2104     // struct_time type
2105     state->struct_time_type = PyStructSequence_NewType(&struct_time_type_desc);
2106     if (state->struct_time_type == NULL) {
2107         return -1;
2108     }
2109     if (PyModule_AddType(module, state->struct_time_type)) {
2110         return -1;
2111     }
2112 
2113 #if defined(__linux__) && !defined(__GLIBC__)
2114     struct tm tm;
2115     const time_t zero = 0;
2116     if (gmtime_r(&zero, &tm) != NULL)
2117         utc_string = tm.tm_zone;
2118 #endif
2119 
2120 #if defined(MS_WINDOWS)
2121     if (timer_flags == (DWORD)-1) {
2122         DWORD test_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
2123         HANDLE timer = CreateWaitableTimerExW(NULL, NULL, test_flags,
2124                                               TIMER_ALL_ACCESS);
2125         if (timer == NULL) {
2126             // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is not supported.
2127             timer_flags = 0;
2128         }
2129         else {
2130             // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is supported.
2131             timer_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
2132             CloseHandle(timer);
2133         }
2134     }
2135 #endif
2136 
2137 // gh-115714: Don't use times() on WASI.
2138 #if defined(HAVE_TIMES) && !defined(__wasi__)
2139     long ticks_per_second;
2140     if (_Py_GetTicksPerSecond(&ticks_per_second) < 0) {
2141         PyErr_SetString(PyExc_RuntimeError,
2142                         "cannot read ticks_per_second");
2143         return -1;
2144     }
2145     if (_PyTimeFraction_Set(&state->times_base, SEC_TO_NS,
2146                             ticks_per_second) < 0) {
2147         PyErr_Format(PyExc_OverflowError, "ticks_per_second is too large");
2148         return -1;
2149     }
2150 #endif
2151 
2152 #ifdef HAVE_CLOCK
2153     if (_PyTimeFraction_Set(&state->clock_base, SEC_TO_NS,
2154                             CLOCKS_PER_SEC) < 0) {
2155         PyErr_Format(PyExc_OverflowError, "CLOCKS_PER_SEC is too large");
2156         return -1;
2157     }
2158 #endif
2159 
2160     return 0;
2161 }
2162 
2163 
2164 static int
time_module_traverse(PyObject * module,visitproc visit,void * arg)2165 time_module_traverse(PyObject *module, visitproc visit, void *arg)
2166 {
2167     time_module_state *state = get_time_state(module);
2168     Py_VISIT(state->struct_time_type);
2169     return 0;
2170 }
2171 
2172 
2173 static int
time_module_clear(PyObject * module)2174 time_module_clear(PyObject *module)
2175 {
2176     time_module_state *state = get_time_state(module);
2177     Py_CLEAR(state->struct_time_type);
2178     return 0;
2179 }
2180 
2181 
2182 static void
time_module_free(void * module)2183 time_module_free(void *module)
2184 {
2185     time_module_clear((PyObject *)module);
2186 }
2187 
2188 
2189 static struct PyModuleDef_Slot time_slots[] = {
2190     {Py_mod_exec, time_exec},
2191     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
2192     {Py_mod_gil, Py_MOD_GIL_NOT_USED},
2193     {0, NULL}
2194 };
2195 
2196 static struct PyModuleDef timemodule = {
2197     PyModuleDef_HEAD_INIT,
2198     .m_name = "time",
2199     .m_doc = module_doc,
2200     .m_size = sizeof(time_module_state),
2201     .m_methods = time_methods,
2202     .m_slots = time_slots,
2203     .m_traverse = time_module_traverse,
2204     .m_clear = time_module_clear,
2205     .m_free = time_module_free,
2206 };
2207 
2208 PyMODINIT_FUNC
PyInit_time(void)2209 PyInit_time(void)
2210 {
2211     return PyModuleDef_Init(&timemodule);
2212 }
2213 
2214 
2215 // time.sleep() implementation.
2216 // On error, raise an exception and return -1.
2217 // On success, return 0.
2218 static int
pysleep(PyTime_t timeout)2219 pysleep(PyTime_t timeout)
2220 {
2221     assert(timeout >= 0);
2222 
2223 #ifndef MS_WINDOWS
2224 #ifdef HAVE_CLOCK_NANOSLEEP
2225     struct timespec timeout_abs;
2226 #elif defined(HAVE_NANOSLEEP)
2227     struct timespec timeout_ts;
2228 #else
2229     struct timeval timeout_tv;
2230 #endif
2231     PyTime_t deadline, monotonic;
2232     int err = 0;
2233 
2234     if (PyTime_Monotonic(&monotonic) < 0) {
2235         return -1;
2236     }
2237     deadline = monotonic + timeout;
2238 #ifdef HAVE_CLOCK_NANOSLEEP
2239     if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) {
2240         return -1;
2241     }
2242 #endif
2243 
2244     do {
2245 #ifdef HAVE_CLOCK_NANOSLEEP
2246         // use timeout_abs
2247 #elif defined(HAVE_NANOSLEEP)
2248         if (_PyTime_AsTimespec(timeout, &timeout_ts) < 0) {
2249             return -1;
2250         }
2251 #else
2252         if (_PyTime_AsTimeval(timeout, &timeout_tv, _PyTime_ROUND_CEILING) < 0) {
2253             return -1;
2254         }
2255 #endif
2256 
2257         int ret;
2258         Py_BEGIN_ALLOW_THREADS
2259 #ifdef HAVE_CLOCK_NANOSLEEP
2260         ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL);
2261         err = ret;
2262 #elif defined(HAVE_NANOSLEEP)
2263         ret = nanosleep(&timeout_ts, NULL);
2264         err = errno;
2265 #else
2266         ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout_tv);
2267         err = errno;
2268 #endif
2269         Py_END_ALLOW_THREADS
2270 
2271         if (ret == 0) {
2272             break;
2273         }
2274 
2275         if (err != EINTR) {
2276             errno = err;
2277             PyErr_SetFromErrno(PyExc_OSError);
2278             return -1;
2279         }
2280 
2281         /* sleep was interrupted by SIGINT */
2282         if (PyErr_CheckSignals()) {
2283             return -1;
2284         }
2285 
2286 #ifndef HAVE_CLOCK_NANOSLEEP
2287         if (PyTime_Monotonic(&monotonic) < 0) {
2288             return -1;
2289         }
2290         timeout = deadline - monotonic;
2291         if (timeout < 0) {
2292             break;
2293         }
2294         /* retry with the recomputed delay */
2295 #endif
2296     } while (1);
2297 
2298     return 0;
2299 #else  // MS_WINDOWS
2300     PyTime_t timeout_100ns = _PyTime_As100Nanoseconds(timeout,
2301                                                        _PyTime_ROUND_CEILING);
2302 
2303     // Maintain Windows Sleep() semantics for time.sleep(0)
2304     if (timeout_100ns == 0) {
2305         Py_BEGIN_ALLOW_THREADS
2306         // A value of zero causes the thread to relinquish the remainder of its
2307         // time slice to any other thread that is ready to run. If there are no
2308         // other threads ready to run, the function returns immediately, and
2309         // the thread continues execution.
2310         Sleep(0);
2311         Py_END_ALLOW_THREADS
2312         return 0;
2313     }
2314 
2315     LARGE_INTEGER relative_timeout;
2316     // No need to check for integer overflow, both types are signed
2317     assert(sizeof(relative_timeout) == sizeof(timeout_100ns));
2318     // SetWaitableTimer(): a negative due time indicates relative time
2319     relative_timeout.QuadPart = -timeout_100ns;
2320 
2321     HANDLE timer = CreateWaitableTimerExW(NULL, NULL, timer_flags,
2322                                           TIMER_ALL_ACCESS);
2323     if (timer == NULL) {
2324         PyErr_SetFromWindowsErr(0);
2325         return -1;
2326     }
2327 
2328     if (!SetWaitableTimerEx(timer, &relative_timeout,
2329                             0, // no period; the timer is signaled once
2330                             NULL, NULL, // no completion routine
2331                             NULL,  // no wake context; do not resume from suspend
2332                             0)) // no tolerable delay for timer coalescing
2333     {
2334         PyErr_SetFromWindowsErr(0);
2335         goto error;
2336     }
2337 
2338     // Only the main thread can be interrupted by SIGINT.
2339     // Signal handlers are only executed in the main thread.
2340     if (_PyOS_IsMainThread()) {
2341         HANDLE sigint_event = _PyOS_SigintEvent();
2342 
2343         while (1) {
2344             // Check for pending SIGINT signal before resetting the event
2345             if (PyErr_CheckSignals()) {
2346                 goto error;
2347             }
2348             ResetEvent(sigint_event);
2349 
2350             HANDLE events[] = {timer, sigint_event};
2351             DWORD rc;
2352 
2353             Py_BEGIN_ALLOW_THREADS
2354             rc = WaitForMultipleObjects(Py_ARRAY_LENGTH(events), events,
2355                                         // bWaitAll
2356                                         FALSE,
2357                                         // No wait timeout
2358                                         INFINITE);
2359             Py_END_ALLOW_THREADS
2360 
2361             if (rc == WAIT_FAILED) {
2362                 PyErr_SetFromWindowsErr(0);
2363                 goto error;
2364             }
2365 
2366             if (rc == WAIT_OBJECT_0) {
2367                 // Timer signaled: we are done
2368                 break;
2369             }
2370 
2371             assert(rc == (WAIT_OBJECT_0 + 1));
2372             // The sleep was interrupted by SIGINT: restart sleeping
2373         }
2374     }
2375     else {
2376         DWORD rc;
2377 
2378         Py_BEGIN_ALLOW_THREADS
2379         rc = WaitForSingleObject(timer, INFINITE);
2380         Py_END_ALLOW_THREADS
2381 
2382         if (rc == WAIT_FAILED) {
2383             PyErr_SetFromWindowsErr(0);
2384             goto error;
2385         }
2386 
2387         assert(rc == WAIT_OBJECT_0);
2388         // Timer signaled: we are done
2389     }
2390 
2391     CloseHandle(timer);
2392     return 0;
2393 
2394 error:
2395     CloseHandle(timer);
2396     return -1;
2397 #endif
2398 }
2399