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