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