1 /* Time module */
2
3 #include "Python.h"
4
5 #include <ctype.h>
6
7 #ifdef HAVE_SYS_TIMES_H
8 #include <sys/times.h>
9 #endif
10
11 #ifdef HAVE_SYS_TYPES_H
12 #include <sys/types.h>
13 #endif
14
15 #if defined(HAVE_SYS_RESOURCE_H)
16 #include <sys/resource.h>
17 #endif
18
19 #ifdef QUICKWIN
20 #include <io.h>
21 #endif
22
23 #if defined(HAVE_PTHREAD_H)
24 # include <pthread.h>
25 #endif
26
27 #if defined(__WATCOMC__) && !defined(__QNX__)
28 #include <i86.h>
29 #else
30 #ifdef MS_WINDOWS
31 #define WIN32_LEAN_AND_MEAN
32 #include <windows.h>
33 #include "pythread.h"
34 #endif /* MS_WINDOWS */
35 #endif /* !__WATCOMC__ || __QNX__ */
36
37 #ifdef _Py_MEMORY_SANITIZER
38 # include <sanitizer/msan_interface.h>
39 #endif
40
41 #ifdef _MSC_VER
42 #define _Py_timezone _timezone
43 #define _Py_daylight _daylight
44 #define _Py_tzname _tzname
45 #else
46 #define _Py_timezone timezone
47 #define _Py_daylight daylight
48 #define _Py_tzname tzname
49 #endif
50
51 #define SEC_TO_NS (1000 * 1000 * 1000)
52
53 /* Forward declarations */
54 static int pysleep(_PyTime_t);
55
56
57 static PyObject*
_PyFloat_FromPyTime(_PyTime_t t)58 _PyFloat_FromPyTime(_PyTime_t t)
59 {
60 double d = _PyTime_AsSecondsDouble(t);
61 return PyFloat_FromDouble(d);
62 }
63
64
65 static PyObject *
time_time(PyObject * self,PyObject * unused)66 time_time(PyObject *self, PyObject *unused)
67 {
68 _PyTime_t t = _PyTime_GetSystemClock();
69 return _PyFloat_FromPyTime(t);
70 }
71
72
73 PyDoc_STRVAR(time_doc,
74 "time() -> floating point number\n\
75 \n\
76 Return the current time in seconds since the Epoch.\n\
77 Fractions of a second may be present if the system clock provides them.");
78
79 static PyObject *
time_time_ns(PyObject * self,PyObject * unused)80 time_time_ns(PyObject *self, PyObject *unused)
81 {
82 _PyTime_t t = _PyTime_GetSystemClock();
83 return _PyTime_AsNanosecondsObject(t);
84 }
85
86 PyDoc_STRVAR(time_ns_doc,
87 "time_ns() -> int\n\
88 \n\
89 Return the current time in nanoseconds since the Epoch.");
90
91 #if defined(HAVE_CLOCK)
92
93 #ifndef CLOCKS_PER_SEC
94 # ifdef CLK_TCK
95 # define CLOCKS_PER_SEC CLK_TCK
96 # else
97 # define CLOCKS_PER_SEC 1000000
98 # endif
99 #endif
100
101 static int
_PyTime_GetClockWithInfo(_PyTime_t * tp,_Py_clock_info_t * info)102 _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
103 {
104 static int initialized = 0;
105 clock_t ticks;
106
107 if (!initialized) {
108 initialized = 1;
109
110 /* must sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC)
111 above cannot overflow */
112 if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) {
113 PyErr_SetString(PyExc_OverflowError,
114 "CLOCKS_PER_SEC is too large");
115 return -1;
116 }
117 }
118
119 if (info) {
120 info->implementation = "clock()";
121 info->resolution = 1.0 / (double)CLOCKS_PER_SEC;
122 info->monotonic = 1;
123 info->adjustable = 0;
124 }
125
126 ticks = clock();
127 if (ticks == (clock_t)-1) {
128 PyErr_SetString(PyExc_RuntimeError,
129 "the processor time used is not available "
130 "or its value cannot be represented");
131 return -1;
132 }
133 *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC);
134 return 0;
135 }
136 #endif /* HAVE_CLOCK */
137
138 static PyObject*
perf_counter(_Py_clock_info_t * info)139 perf_counter(_Py_clock_info_t *info)
140 {
141 _PyTime_t t;
142 if (_PyTime_GetPerfCounterWithInfo(&t, info) < 0) {
143 return NULL;
144 }
145 return _PyFloat_FromPyTime(t);
146 }
147
148 #if defined(MS_WINDOWS) || defined(HAVE_CLOCK)
149 #define PYCLOCK
150 static PyObject*
pyclock(_Py_clock_info_t * info)151 pyclock(_Py_clock_info_t *info)
152 {
153 if (PyErr_WarnEx(PyExc_DeprecationWarning,
154 "time.clock has been deprecated in Python 3.3 and will "
155 "be removed from Python 3.8: "
156 "use time.perf_counter or time.process_time "
157 "instead", 1) < 0) {
158 return NULL;
159 }
160
161 #ifdef MS_WINDOWS
162 return perf_counter(info);
163 #else
164 _PyTime_t t;
165 if (_PyTime_GetClockWithInfo(&t, info) < 0) {
166 return NULL;
167 }
168 return _PyFloat_FromPyTime(t);
169 #endif
170 }
171
172 static PyObject *
time_clock(PyObject * self,PyObject * unused)173 time_clock(PyObject *self, PyObject *unused)
174 {
175 return pyclock(NULL);
176 }
177
178 PyDoc_STRVAR(clock_doc,
179 "clock() -> floating point number\n\
180 \n\
181 Return the CPU time or real time since the start of the process or since\n\
182 the first call to clock(). This has as much precision as the system\n\
183 records.");
184 #endif
185
186 #ifdef HAVE_CLOCK_GETTIME
187 static PyObject *
time_clock_gettime(PyObject * self,PyObject * args)188 time_clock_gettime(PyObject *self, PyObject *args)
189 {
190 int ret;
191 int clk_id;
192 struct timespec tp;
193
194 if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
195 return NULL;
196 }
197
198 ret = clock_gettime((clockid_t)clk_id, &tp);
199 if (ret != 0) {
200 PyErr_SetFromErrno(PyExc_OSError);
201 return NULL;
202 }
203 return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
204 }
205
206 PyDoc_STRVAR(clock_gettime_doc,
207 "clock_gettime(clk_id) -> float\n\
208 \n\
209 Return the time of the specified clock clk_id.");
210
211 static PyObject *
time_clock_gettime_ns(PyObject * self,PyObject * args)212 time_clock_gettime_ns(PyObject *self, PyObject *args)
213 {
214 int ret;
215 int clk_id;
216 struct timespec ts;
217 _PyTime_t t;
218
219 if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
220 return NULL;
221 }
222
223 ret = clock_gettime((clockid_t)clk_id, &ts);
224 if (ret != 0) {
225 PyErr_SetFromErrno(PyExc_OSError);
226 return NULL;
227 }
228 if (_PyTime_FromTimespec(&t, &ts) < 0) {
229 return NULL;
230 }
231 return _PyTime_AsNanosecondsObject(t);
232 }
233
234 PyDoc_STRVAR(clock_gettime_ns_doc,
235 "clock_gettime_ns(clk_id) -> int\n\
236 \n\
237 Return the time of the specified clock clk_id as nanoseconds.");
238 #endif /* HAVE_CLOCK_GETTIME */
239
240 #ifdef HAVE_CLOCK_SETTIME
241 static PyObject *
time_clock_settime(PyObject * self,PyObject * args)242 time_clock_settime(PyObject *self, PyObject *args)
243 {
244 int clk_id;
245 PyObject *obj;
246 _PyTime_t t;
247 struct timespec tp;
248 int ret;
249
250 if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj))
251 return NULL;
252
253 if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0)
254 return NULL;
255
256 if (_PyTime_AsTimespec(t, &tp) == -1)
257 return NULL;
258
259 ret = clock_settime((clockid_t)clk_id, &tp);
260 if (ret != 0) {
261 PyErr_SetFromErrno(PyExc_OSError);
262 return NULL;
263 }
264 Py_RETURN_NONE;
265 }
266
267 PyDoc_STRVAR(clock_settime_doc,
268 "clock_settime(clk_id, time)\n\
269 \n\
270 Set the time of the specified clock clk_id.");
271
272 static PyObject *
time_clock_settime_ns(PyObject * self,PyObject * args)273 time_clock_settime_ns(PyObject *self, PyObject *args)
274 {
275 int clk_id;
276 PyObject *obj;
277 _PyTime_t t;
278 struct timespec ts;
279 int ret;
280
281 if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) {
282 return NULL;
283 }
284
285 if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
286 return NULL;
287 }
288 if (_PyTime_AsTimespec(t, &ts) == -1) {
289 return NULL;
290 }
291
292 ret = clock_settime((clockid_t)clk_id, &ts);
293 if (ret != 0) {
294 PyErr_SetFromErrno(PyExc_OSError);
295 return NULL;
296 }
297 Py_RETURN_NONE;
298 }
299
300 PyDoc_STRVAR(clock_settime_ns_doc,
301 "clock_settime_ns(clk_id, time)\n\
302 \n\
303 Set the time of the specified clock clk_id with nanoseconds.");
304 #endif /* HAVE_CLOCK_SETTIME */
305
306 #ifdef HAVE_CLOCK_GETRES
307 static PyObject *
time_clock_getres(PyObject * self,PyObject * args)308 time_clock_getres(PyObject *self, PyObject *args)
309 {
310 int ret;
311 int clk_id;
312 struct timespec tp;
313
314 if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id))
315 return NULL;
316
317 ret = clock_getres((clockid_t)clk_id, &tp);
318 if (ret != 0) {
319 PyErr_SetFromErrno(PyExc_OSError);
320 return NULL;
321 }
322
323 return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
324 }
325
326 PyDoc_STRVAR(clock_getres_doc,
327 "clock_getres(clk_id) -> floating point number\n\
328 \n\
329 Return the resolution (precision) of the specified clock clk_id.");
330 #endif /* HAVE_CLOCK_GETRES */
331
332 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
333 static PyObject *
time_pthread_getcpuclockid(PyObject * self,PyObject * args)334 time_pthread_getcpuclockid(PyObject *self, PyObject *args)
335 {
336 unsigned long thread_id;
337 int err;
338 clockid_t clk_id;
339 if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) {
340 return NULL;
341 }
342 err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id);
343 if (err) {
344 errno = err;
345 PyErr_SetFromErrno(PyExc_OSError);
346 return NULL;
347 }
348 #ifdef _Py_MEMORY_SANITIZER
349 __msan_unpoison(&clk_id, sizeof(clk_id));
350 #endif
351 return PyLong_FromLong(clk_id);
352 }
353
354 PyDoc_STRVAR(pthread_getcpuclockid_doc,
355 "pthread_getcpuclockid(thread_id) -> int\n\
356 \n\
357 Return the clk_id of a thread's CPU time clock.");
358 #endif /* HAVE_PTHREAD_GETCPUCLOCKID */
359
360 static PyObject *
time_sleep(PyObject * self,PyObject * obj)361 time_sleep(PyObject *self, PyObject *obj)
362 {
363 _PyTime_t secs;
364 if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_TIMEOUT))
365 return NULL;
366 if (secs < 0) {
367 PyErr_SetString(PyExc_ValueError,
368 "sleep length must be non-negative");
369 return NULL;
370 }
371 if (pysleep(secs) != 0)
372 return NULL;
373 Py_RETURN_NONE;
374 }
375
376 PyDoc_STRVAR(sleep_doc,
377 "sleep(seconds)\n\
378 \n\
379 Delay execution for a given number of seconds. The argument may be\n\
380 a floating point number for subsecond precision.");
381
382 static PyStructSequence_Field struct_time_type_fields[] = {
383 {"tm_year", "year, for example, 1993"},
384 {"tm_mon", "month of year, range [1, 12]"},
385 {"tm_mday", "day of month, range [1, 31]"},
386 {"tm_hour", "hours, range [0, 23]"},
387 {"tm_min", "minutes, range [0, 59]"},
388 {"tm_sec", "seconds, range [0, 61])"},
389 {"tm_wday", "day of week, range [0, 6], Monday is 0"},
390 {"tm_yday", "day of year, range [1, 366]"},
391 {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"},
392 {"tm_zone", "abbreviation of timezone name"},
393 {"tm_gmtoff", "offset from UTC in seconds"},
394 {0}
395 };
396
397 static PyStructSequence_Desc struct_time_type_desc = {
398 "time.struct_time",
399 "The time value as returned by gmtime(), localtime(), and strptime(), and\n"
400 " accepted by asctime(), mktime() and strftime(). May be considered as a\n"
401 " sequence of 9 integers.\n\n"
402 " Note that several fields' values are not the same as those defined by\n"
403 " the C language standard for struct tm. For example, the value of the\n"
404 " field tm_year is the actual year, not year - 1900. See individual\n"
405 " fields' descriptions for details.",
406 struct_time_type_fields,
407 9,
408 };
409
410 static int initialized;
411 static PyTypeObject StructTimeType;
412
413
414 static PyObject *
tmtotuple(struct tm * p,const char * zone,time_t gmtoff)415 tmtotuple(struct tm *p
416 #ifndef HAVE_STRUCT_TM_TM_ZONE
417 , const char *zone, time_t gmtoff
418 #endif
419 )
420 {
421 PyObject *v = PyStructSequence_New(&StructTimeType);
422 if (v == NULL)
423 return NULL;
424
425 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
426
427 SET(0, p->tm_year + 1900);
428 SET(1, p->tm_mon + 1); /* Want January == 1 */
429 SET(2, p->tm_mday);
430 SET(3, p->tm_hour);
431 SET(4, p->tm_min);
432 SET(5, p->tm_sec);
433 SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
434 SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */
435 SET(8, p->tm_isdst);
436 #ifdef HAVE_STRUCT_TM_TM_ZONE
437 PyStructSequence_SET_ITEM(v, 9,
438 PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape"));
439 SET(10, p->tm_gmtoff);
440 #else
441 PyStructSequence_SET_ITEM(v, 9,
442 PyUnicode_DecodeLocale(zone, "surrogateescape"));
443 PyStructSequence_SET_ITEM(v, 10, _PyLong_FromTime_t(gmtoff));
444 #endif /* HAVE_STRUCT_TM_TM_ZONE */
445 #undef SET
446 if (PyErr_Occurred()) {
447 Py_XDECREF(v);
448 return NULL;
449 }
450
451 return v;
452 }
453
454 /* Parse arg tuple that can contain an optional float-or-None value;
455 format needs to be "|O:name".
456 Returns non-zero on success (parallels PyArg_ParseTuple).
457 */
458 static int
parse_time_t_args(PyObject * args,const char * format,time_t * pwhen)459 parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
460 {
461 PyObject *ot = NULL;
462 time_t whent;
463
464 if (!PyArg_ParseTuple(args, format, &ot))
465 return 0;
466 if (ot == NULL || ot == Py_None) {
467 whent = time(NULL);
468 }
469 else {
470 if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1)
471 return 0;
472 }
473 *pwhen = whent;
474 return 1;
475 }
476
477 static PyObject *
time_gmtime(PyObject * self,PyObject * args)478 time_gmtime(PyObject *self, PyObject *args)
479 {
480 time_t when;
481 struct tm buf;
482
483 if (!parse_time_t_args(args, "|O:gmtime", &when))
484 return NULL;
485
486 errno = 0;
487 if (_PyTime_gmtime(when, &buf) != 0)
488 return NULL;
489 #ifdef HAVE_STRUCT_TM_TM_ZONE
490 return tmtotuple(&buf);
491 #else
492 return tmtotuple(&buf, "UTC", 0);
493 #endif
494 }
495
496 #ifndef HAVE_TIMEGM
497 static time_t
timegm(struct tm * p)498 timegm(struct tm *p)
499 {
500 /* XXX: the following implementation will not work for tm_year < 1970.
501 but it is likely that platforms that don't have timegm do not support
502 negative timestamps anyways. */
503 return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 +
504 (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 -
505 ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400;
506 }
507 #endif
508
509 PyDoc_STRVAR(gmtime_doc,
510 "gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\
511 tm_sec, tm_wday, tm_yday, tm_isdst)\n\
512 \n\
513 Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
514 GMT). When 'seconds' is not passed in, convert the current time instead.\n\
515 \n\
516 If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
517 attributes only.");
518
519 static PyObject *
time_localtime(PyObject * self,PyObject * args)520 time_localtime(PyObject *self, PyObject *args)
521 {
522 time_t when;
523 struct tm buf;
524
525 if (!parse_time_t_args(args, "|O:localtime", &when))
526 return NULL;
527 if (_PyTime_localtime(when, &buf) != 0)
528 return NULL;
529 #ifdef HAVE_STRUCT_TM_TM_ZONE
530 return tmtotuple(&buf);
531 #else
532 {
533 struct tm local = buf;
534 char zone[100];
535 time_t gmtoff;
536 strftime(zone, sizeof(zone), "%Z", &buf);
537 gmtoff = timegm(&buf) - when;
538 return tmtotuple(&local, zone, gmtoff);
539 }
540 #endif
541 }
542
543 PyDoc_STRVAR(localtime_doc,
544 "localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
545 tm_sec,tm_wday,tm_yday,tm_isdst)\n\
546 \n\
547 Convert seconds since the Epoch to a time tuple expressing local time.\n\
548 When 'seconds' is not passed in, convert the current time instead.");
549
550 /* Convert 9-item tuple to tm structure. Return 1 on success, set
551 * an exception and return 0 on error.
552 */
553 static int
gettmarg(PyObject * args,struct tm * p,const char * format)554 gettmarg(PyObject *args, struct tm *p, const char *format)
555 {
556 int y;
557
558 memset((void *) p, '\0', sizeof(struct tm));
559
560 if (!PyTuple_Check(args)) {
561 PyErr_SetString(PyExc_TypeError,
562 "Tuple or struct_time argument required");
563 return 0;
564 }
565
566 if (!PyArg_ParseTuple(args, format,
567 &y, &p->tm_mon, &p->tm_mday,
568 &p->tm_hour, &p->tm_min, &p->tm_sec,
569 &p->tm_wday, &p->tm_yday, &p->tm_isdst))
570 return 0;
571
572 if (y < INT_MIN + 1900) {
573 PyErr_SetString(PyExc_OverflowError, "year out of range");
574 return 0;
575 }
576
577 p->tm_year = y - 1900;
578 p->tm_mon--;
579 p->tm_wday = (p->tm_wday + 1) % 7;
580 p->tm_yday--;
581 #ifdef HAVE_STRUCT_TM_TM_ZONE
582 if (Py_TYPE(args) == &StructTimeType) {
583 PyObject *item;
584 item = PyTuple_GET_ITEM(args, 9);
585 p->tm_zone = item == Py_None ? NULL : (char*)PyUnicode_AsUTF8(item);
586 item = PyTuple_GET_ITEM(args, 10);
587 p->tm_gmtoff = item == Py_None ? 0 : PyLong_AsLong(item);
588 if (PyErr_Occurred())
589 return 0;
590 }
591 #endif /* HAVE_STRUCT_TM_TM_ZONE */
592 return 1;
593 }
594
595 /* Check values of the struct tm fields before it is passed to strftime() and
596 * asctime(). Return 1 if all values are valid, otherwise set an exception
597 * and returns 0.
598 */
599 static int
checktm(struct tm * buf)600 checktm(struct tm* buf)
601 {
602 /* Checks added to make sure strftime() and asctime() does not crash Python by
603 indexing blindly into some array for a textual representation
604 by some bad index (fixes bug #897625 and #6608).
605
606 Also support values of zero from Python code for arguments in which
607 that is out of range by forcing that value to the lowest value that
608 is valid (fixed bug #1520914).
609
610 Valid ranges based on what is allowed in struct tm:
611
612 - tm_year: [0, max(int)] (1)
613 - tm_mon: [0, 11] (2)
614 - tm_mday: [1, 31]
615 - tm_hour: [0, 23]
616 - tm_min: [0, 59]
617 - tm_sec: [0, 60]
618 - tm_wday: [0, 6] (1)
619 - tm_yday: [0, 365] (2)
620 - tm_isdst: [-max(int), max(int)]
621
622 (1) gettmarg() handles bounds-checking.
623 (2) Python's acceptable range is one greater than the range in C,
624 thus need to check against automatic decrement by gettmarg().
625 */
626 if (buf->tm_mon == -1)
627 buf->tm_mon = 0;
628 else if (buf->tm_mon < 0 || buf->tm_mon > 11) {
629 PyErr_SetString(PyExc_ValueError, "month out of range");
630 return 0;
631 }
632 if (buf->tm_mday == 0)
633 buf->tm_mday = 1;
634 else if (buf->tm_mday < 0 || buf->tm_mday > 31) {
635 PyErr_SetString(PyExc_ValueError, "day of month out of range");
636 return 0;
637 }
638 if (buf->tm_hour < 0 || buf->tm_hour > 23) {
639 PyErr_SetString(PyExc_ValueError, "hour out of range");
640 return 0;
641 }
642 if (buf->tm_min < 0 || buf->tm_min > 59) {
643 PyErr_SetString(PyExc_ValueError, "minute out of range");
644 return 0;
645 }
646 if (buf->tm_sec < 0 || buf->tm_sec > 61) {
647 PyErr_SetString(PyExc_ValueError, "seconds out of range");
648 return 0;
649 }
650 /* tm_wday does not need checking of its upper-bound since taking
651 ``% 7`` in gettmarg() automatically restricts the range. */
652 if (buf->tm_wday < 0) {
653 PyErr_SetString(PyExc_ValueError, "day of week out of range");
654 return 0;
655 }
656 if (buf->tm_yday == -1)
657 buf->tm_yday = 0;
658 else if (buf->tm_yday < 0 || buf->tm_yday > 365) {
659 PyErr_SetString(PyExc_ValueError, "day of year out of range");
660 return 0;
661 }
662 return 1;
663 }
664
665 #ifdef MS_WINDOWS
666 /* wcsftime() doesn't format correctly time zones, see issue #10653 */
667 # undef HAVE_WCSFTIME
668 #endif
669 #define STRFTIME_FORMAT_CODES \
670 "Commonly used format codes:\n\
671 \n\
672 %Y Year with century as a decimal number.\n\
673 %m Month as a decimal number [01,12].\n\
674 %d Day of the month as a decimal number [01,31].\n\
675 %H Hour (24-hour clock) as a decimal number [00,23].\n\
676 %M Minute as a decimal number [00,59].\n\
677 %S Second as a decimal number [00,61].\n\
678 %z Time zone offset from UTC.\n\
679 %a Locale's abbreviated weekday name.\n\
680 %A Locale's full weekday name.\n\
681 %b Locale's abbreviated month name.\n\
682 %B Locale's full month name.\n\
683 %c Locale's appropriate date and time representation.\n\
684 %I Hour (12-hour clock) as a decimal number [01,12].\n\
685 %p Locale's equivalent of either AM or PM.\n\
686 \n\
687 Other codes may be available on your platform. See documentation for\n\
688 the C library strftime function.\n"
689
690 #ifdef HAVE_STRFTIME
691 #ifdef HAVE_WCSFTIME
692 #define time_char wchar_t
693 #define format_time wcsftime
694 #define time_strlen wcslen
695 #else
696 #define time_char char
697 #define format_time strftime
698 #define time_strlen strlen
699 #endif
700
701 static PyObject *
time_strftime(PyObject * self,PyObject * args)702 time_strftime(PyObject *self, PyObject *args)
703 {
704 PyObject *tup = NULL;
705 struct tm buf;
706 const time_char *fmt;
707 #ifdef HAVE_WCSFTIME
708 wchar_t *format;
709 #else
710 PyObject *format;
711 #endif
712 PyObject *format_arg;
713 size_t fmtlen, buflen;
714 time_char *outbuf = NULL;
715 size_t i;
716 PyObject *ret = NULL;
717
718 memset((void *) &buf, '\0', sizeof(buf));
719
720 /* Will always expect a unicode string to be passed as format.
721 Given that there's no str type anymore in py3k this seems safe.
722 */
723 if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup))
724 return NULL;
725
726 if (tup == NULL) {
727 time_t tt = time(NULL);
728 if (_PyTime_localtime(tt, &buf) != 0)
729 return NULL;
730 }
731 else if (!gettmarg(tup, &buf,
732 "iiiiiiiii;strftime(): illegal time tuple argument") ||
733 !checktm(&buf))
734 {
735 return NULL;
736 }
737
738 #if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX)
739 if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
740 PyErr_SetString(PyExc_ValueError,
741 "strftime() requires year in [1; 9999]");
742 return NULL;
743 }
744 #endif
745
746 /* Normalize tm_isdst just in case someone foolishly implements %Z
747 based on the assumption that tm_isdst falls within the range of
748 [-1, 1] */
749 if (buf.tm_isdst < -1)
750 buf.tm_isdst = -1;
751 else if (buf.tm_isdst > 1)
752 buf.tm_isdst = 1;
753
754 #ifdef HAVE_WCSFTIME
755 format = PyUnicode_AsWideCharString(format_arg, NULL);
756 if (format == NULL)
757 return NULL;
758 fmt = format;
759 #else
760 /* Convert the unicode string to an ascii one */
761 format = PyUnicode_EncodeLocale(format_arg, "surrogateescape");
762 if (format == NULL)
763 return NULL;
764 fmt = PyBytes_AS_STRING(format);
765 #endif
766
767 #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME)
768 /* check that the format string contains only valid directives */
769 for (outbuf = strchr(fmt, '%');
770 outbuf != NULL;
771 outbuf = strchr(outbuf+2, '%'))
772 {
773 if (outbuf[1] == '#')
774 ++outbuf; /* not documented by python, */
775 if (outbuf[1] == '\0')
776 break;
777 if ((outbuf[1] == 'y') && buf.tm_year < 0) {
778 PyErr_SetString(PyExc_ValueError,
779 "format %y requires year >= 1900 on Windows");
780 Py_DECREF(format);
781 return NULL;
782 }
783 }
784 #elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME)
785 for (outbuf = wcschr(fmt, '%');
786 outbuf != NULL;
787 outbuf = wcschr(outbuf+2, '%'))
788 {
789 if (outbuf[1] == L'\0')
790 break;
791 /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0))
792 returns "0/" instead of "99" */
793 if (outbuf[1] == L'y' && buf.tm_year < 0) {
794 PyErr_SetString(PyExc_ValueError,
795 "format %y requires year >= 1900 on AIX");
796 PyMem_Free(format);
797 return NULL;
798 }
799 }
800 #endif
801
802 fmtlen = time_strlen(fmt);
803
804 /* I hate these functions that presume you know how big the output
805 * will be ahead of time...
806 */
807 for (i = 1024; ; i += i) {
808 outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
809 if (outbuf == NULL) {
810 PyErr_NoMemory();
811 break;
812 }
813 #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
814 errno = 0;
815 #endif
816 _Py_BEGIN_SUPPRESS_IPH
817 buflen = format_time(outbuf, i, fmt, &buf);
818 _Py_END_SUPPRESS_IPH
819 #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
820 /* VisualStudio .NET 2005 does this properly */
821 if (buflen == 0 && errno == EINVAL) {
822 PyErr_SetString(PyExc_ValueError, "Invalid format string");
823 PyMem_Free(outbuf);
824 break;
825 }
826 #endif
827 if (buflen > 0 || i >= 256 * fmtlen) {
828 /* If the buffer is 256 times as long as the format,
829 it's probably not failing for lack of room!
830 More likely, the format yields an empty result,
831 e.g. an empty format, or %Z when the timezone
832 is unknown. */
833 #ifdef HAVE_WCSFTIME
834 ret = PyUnicode_FromWideChar(outbuf, buflen);
835 #else
836 ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape");
837 #endif
838 PyMem_Free(outbuf);
839 break;
840 }
841 PyMem_Free(outbuf);
842 }
843 #ifdef HAVE_WCSFTIME
844 PyMem_Free(format);
845 #else
846 Py_DECREF(format);
847 #endif
848 return ret;
849 }
850
851 #undef time_char
852 #undef format_time
853 PyDoc_STRVAR(strftime_doc,
854 "strftime(format[, tuple]) -> string\n\
855 \n\
856 Convert a time tuple to a string according to a format specification.\n\
857 See the library reference manual for formatting codes. When the time tuple\n\
858 is not present, current time as returned by localtime() is used.\n\
859 \n" STRFTIME_FORMAT_CODES);
860 #endif /* HAVE_STRFTIME */
861
862 static PyObject *
time_strptime(PyObject * self,PyObject * args)863 time_strptime(PyObject *self, PyObject *args)
864 {
865 PyObject *module, *func, *result;
866 _Py_IDENTIFIER(_strptime_time);
867
868 module = PyImport_ImportModuleNoBlock("_strptime");
869 if (!module)
870 return NULL;
871
872 func = _PyObject_GetAttrId(module, &PyId__strptime_time);
873 Py_DECREF(module);
874 if (!func) {
875 return NULL;
876 }
877
878 result = PyObject_Call(func, args, NULL);
879 Py_DECREF(func);
880 return result;
881 }
882
883
884 PyDoc_STRVAR(strptime_doc,
885 "strptime(string, format) -> struct_time\n\
886 \n\
887 Parse a string to a time tuple according to a format specification.\n\
888 See the library reference manual for formatting codes (same as\n\
889 strftime()).\n\
890 \n" STRFTIME_FORMAT_CODES);
891
892 static PyObject *
_asctime(struct tm * timeptr)893 _asctime(struct tm *timeptr)
894 {
895 /* Inspired by Open Group reference implementation available at
896 * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */
897 static const char wday_name[7][4] = {
898 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
899 };
900 static const char mon_name[12][4] = {
901 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
902 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
903 };
904 return PyUnicode_FromFormat(
905 "%s %s%3d %.2d:%.2d:%.2d %d",
906 wday_name[timeptr->tm_wday],
907 mon_name[timeptr->tm_mon],
908 timeptr->tm_mday, timeptr->tm_hour,
909 timeptr->tm_min, timeptr->tm_sec,
910 1900 + timeptr->tm_year);
911 }
912
913 static PyObject *
time_asctime(PyObject * self,PyObject * args)914 time_asctime(PyObject *self, PyObject *args)
915 {
916 PyObject *tup = NULL;
917 struct tm buf;
918
919 if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
920 return NULL;
921 if (tup == NULL) {
922 time_t tt = time(NULL);
923 if (_PyTime_localtime(tt, &buf) != 0)
924 return NULL;
925 }
926 else if (!gettmarg(tup, &buf,
927 "iiiiiiiii;asctime(): illegal time tuple argument") ||
928 !checktm(&buf))
929 {
930 return NULL;
931 }
932 return _asctime(&buf);
933 }
934
935 PyDoc_STRVAR(asctime_doc,
936 "asctime([tuple]) -> string\n\
937 \n\
938 Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
939 When the time tuple is not present, current time as returned by localtime()\n\
940 is used.");
941
942 static PyObject *
time_ctime(PyObject * self,PyObject * args)943 time_ctime(PyObject *self, PyObject *args)
944 {
945 time_t tt;
946 struct tm buf;
947 if (!parse_time_t_args(args, "|O:ctime", &tt))
948 return NULL;
949 if (_PyTime_localtime(tt, &buf) != 0)
950 return NULL;
951 return _asctime(&buf);
952 }
953
954 PyDoc_STRVAR(ctime_doc,
955 "ctime(seconds) -> string\n\
956 \n\
957 Convert a time in seconds since the Epoch to a string in local time.\n\
958 This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
959 not present, current time as returned by localtime() is used.");
960
961 #ifdef HAVE_MKTIME
962 static PyObject *
time_mktime(PyObject * self,PyObject * tup)963 time_mktime(PyObject *self, PyObject *tup)
964 {
965 struct tm buf;
966 time_t tt;
967 if (!gettmarg(tup, &buf,
968 "iiiiiiiii;mktime(): illegal time tuple argument"))
969 {
970 return NULL;
971 }
972 #ifdef _AIX
973 /* year < 1902 or year > 2037 */
974 if (buf.tm_year < 2 || buf.tm_year > 137) {
975 /* Issue #19748: On AIX, mktime() doesn't report overflow error for
976 * timestamp < -2^31 or timestamp > 2**31-1. */
977 PyErr_SetString(PyExc_OverflowError,
978 "mktime argument out of range");
979 return NULL;
980 }
981 #else
982 buf.tm_wday = -1; /* sentinel; original value ignored */
983 #endif
984 tt = mktime(&buf);
985 /* Return value of -1 does not necessarily mean an error, but tm_wday
986 * cannot remain set to -1 if mktime succeeded. */
987 if (tt == (time_t)(-1)
988 #ifndef _AIX
989 /* Return value of -1 does not necessarily mean an error, but
990 * tm_wday cannot remain set to -1 if mktime succeeded. */
991 && buf.tm_wday == -1
992 #else
993 /* on AIX, tm_wday is always sets, even on error */
994 #endif
995 )
996 {
997 PyErr_SetString(PyExc_OverflowError,
998 "mktime argument out of range");
999 return NULL;
1000 }
1001 return PyFloat_FromDouble((double)tt);
1002 }
1003
1004 PyDoc_STRVAR(mktime_doc,
1005 "mktime(tuple) -> floating point number\n\
1006 \n\
1007 Convert a time tuple in local time to seconds since the Epoch.\n\
1008 Note that mktime(gmtime(0)) will not generally return zero for most\n\
1009 time zones; instead the returned value will either be equal to that\n\
1010 of the timezone or altzone attributes on the time module.");
1011 #endif /* HAVE_MKTIME */
1012
1013 #ifdef HAVE_WORKING_TZSET
1014 static int init_timezone(PyObject *module);
1015
1016 static PyObject *
time_tzset(PyObject * self,PyObject * unused)1017 time_tzset(PyObject *self, PyObject *unused)
1018 {
1019 PyObject* m;
1020
1021 m = PyImport_ImportModuleNoBlock("time");
1022 if (m == NULL) {
1023 return NULL;
1024 }
1025
1026 tzset();
1027
1028 /* Reset timezone, altzone, daylight and tzname */
1029 if (init_timezone(m) < 0) {
1030 return NULL;
1031 }
1032 Py_DECREF(m);
1033 if (PyErr_Occurred())
1034 return NULL;
1035
1036 Py_RETURN_NONE;
1037 }
1038
1039 PyDoc_STRVAR(tzset_doc,
1040 "tzset()\n\
1041 \n\
1042 Initialize, or reinitialize, the local timezone to the value stored in\n\
1043 os.environ['TZ']. The TZ environment variable should be specified in\n\
1044 standard Unix timezone format as documented in the tzset man page\n\
1045 (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
1046 fall back to UTC. If the TZ environment variable is not set, the local\n\
1047 timezone is set to the systems best guess of wallclock time.\n\
1048 Changing the TZ environment variable without calling tzset *may* change\n\
1049 the local timezone used by methods such as localtime, but this behaviour\n\
1050 should not be relied on.");
1051 #endif /* HAVE_WORKING_TZSET */
1052
1053 static PyObject *
time_monotonic(PyObject * self,PyObject * unused)1054 time_monotonic(PyObject *self, PyObject *unused)
1055 {
1056 _PyTime_t t = _PyTime_GetMonotonicClock();
1057 return _PyFloat_FromPyTime(t);
1058 }
1059
1060 PyDoc_STRVAR(monotonic_doc,
1061 "monotonic() -> float\n\
1062 \n\
1063 Monotonic clock, cannot go backward.");
1064
1065 static PyObject *
time_monotonic_ns(PyObject * self,PyObject * unused)1066 time_monotonic_ns(PyObject *self, PyObject *unused)
1067 {
1068 _PyTime_t t = _PyTime_GetMonotonicClock();
1069 return _PyTime_AsNanosecondsObject(t);
1070 }
1071
1072 PyDoc_STRVAR(monotonic_ns_doc,
1073 "monotonic_ns() -> int\n\
1074 \n\
1075 Monotonic clock, cannot go backward, as nanoseconds.");
1076
1077 static PyObject *
time_perf_counter(PyObject * self,PyObject * unused)1078 time_perf_counter(PyObject *self, PyObject *unused)
1079 {
1080 return perf_counter(NULL);
1081 }
1082
1083 PyDoc_STRVAR(perf_counter_doc,
1084 "perf_counter() -> float\n\
1085 \n\
1086 Performance counter for benchmarking.");
1087
1088 static PyObject *
time_perf_counter_ns(PyObject * self,PyObject * unused)1089 time_perf_counter_ns(PyObject *self, PyObject *unused)
1090 {
1091 _PyTime_t t = _PyTime_GetPerfCounter();
1092 return _PyTime_AsNanosecondsObject(t);
1093 }
1094
1095 PyDoc_STRVAR(perf_counter_ns_doc,
1096 "perf_counter_ns() -> int\n\
1097 \n\
1098 Performance counter for benchmarking as nanoseconds.");
1099
1100 static int
_PyTime_GetProcessTimeWithInfo(_PyTime_t * tp,_Py_clock_info_t * info)1101 _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1102 {
1103 #if defined(MS_WINDOWS)
1104 HANDLE process;
1105 FILETIME creation_time, exit_time, kernel_time, user_time;
1106 ULARGE_INTEGER large;
1107 _PyTime_t ktime, utime, t;
1108 BOOL ok;
1109
1110 process = GetCurrentProcess();
1111 ok = GetProcessTimes(process, &creation_time, &exit_time,
1112 &kernel_time, &user_time);
1113 if (!ok) {
1114 PyErr_SetFromWindowsErr(0);
1115 return -1;
1116 }
1117
1118 if (info) {
1119 info->implementation = "GetProcessTimes()";
1120 info->resolution = 1e-7;
1121 info->monotonic = 1;
1122 info->adjustable = 0;
1123 }
1124
1125 large.u.LowPart = kernel_time.dwLowDateTime;
1126 large.u.HighPart = kernel_time.dwHighDateTime;
1127 ktime = large.QuadPart;
1128
1129 large.u.LowPart = user_time.dwLowDateTime;
1130 large.u.HighPart = user_time.dwHighDateTime;
1131 utime = large.QuadPart;
1132
1133 /* ktime and utime have a resolution of 100 nanoseconds */
1134 t = _PyTime_FromNanoseconds((ktime + utime) * 100);
1135 *tp = t;
1136 return 0;
1137 #else
1138
1139 /* clock_gettime */
1140 #if defined(HAVE_CLOCK_GETTIME) \
1141 && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF))
1142 struct timespec ts;
1143 #ifdef CLOCK_PROF
1144 const clockid_t clk_id = CLOCK_PROF;
1145 const char *function = "clock_gettime(CLOCK_PROF)";
1146 #else
1147 const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
1148 const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
1149 #endif
1150
1151 if (clock_gettime(clk_id, &ts) == 0) {
1152 if (info) {
1153 struct timespec res;
1154 info->implementation = function;
1155 info->monotonic = 1;
1156 info->adjustable = 0;
1157 if (clock_getres(clk_id, &res)) {
1158 PyErr_SetFromErrno(PyExc_OSError);
1159 return -1;
1160 }
1161 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1162 }
1163
1164 if (_PyTime_FromTimespec(tp, &ts) < 0) {
1165 return -1;
1166 }
1167 return 0;
1168 }
1169 #endif
1170
1171 /* getrusage(RUSAGE_SELF) */
1172 #if defined(HAVE_SYS_RESOURCE_H)
1173 struct rusage ru;
1174
1175 if (getrusage(RUSAGE_SELF, &ru) == 0) {
1176 _PyTime_t utime, stime;
1177
1178 if (info) {
1179 info->implementation = "getrusage(RUSAGE_SELF)";
1180 info->monotonic = 1;
1181 info->adjustable = 0;
1182 info->resolution = 1e-6;
1183 }
1184
1185 if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) {
1186 return -1;
1187 }
1188 if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) {
1189 return -1;
1190 }
1191
1192 _PyTime_t total = utime + utime;
1193 *tp = total;
1194 return 0;
1195 }
1196 #endif
1197
1198 /* times() */
1199 #ifdef HAVE_TIMES
1200 struct tms t;
1201
1202 if (times(&t) != (clock_t)-1) {
1203 static long ticks_per_second = -1;
1204
1205 if (ticks_per_second == -1) {
1206 long freq;
1207 #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
1208 freq = sysconf(_SC_CLK_TCK);
1209 if (freq < 1) {
1210 freq = -1;
1211 }
1212 #elif defined(HZ)
1213 freq = HZ;
1214 #else
1215 freq = 60; /* magic fallback value; may be bogus */
1216 #endif
1217
1218 if (freq != -1) {
1219 /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second)
1220 cannot overflow below */
1221 #if LONG_MAX > _PyTime_MAX / SEC_TO_NS
1222 if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) {
1223 PyErr_SetString(PyExc_OverflowError,
1224 "_SC_CLK_TCK is too large");
1225 return -1;
1226 }
1227 #endif
1228
1229 ticks_per_second = freq;
1230 }
1231 }
1232
1233 if (ticks_per_second != -1) {
1234 if (info) {
1235 info->implementation = "times()";
1236 info->monotonic = 1;
1237 info->adjustable = 0;
1238 info->resolution = 1.0 / (double)ticks_per_second;
1239 }
1240
1241 _PyTime_t total;
1242 total = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second);
1243 total += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second);
1244 *tp = total;
1245 return 0;
1246 }
1247 }
1248 #endif
1249
1250 /* clock */
1251 /* Currently, Python 3 requires clock() to build: see issue #22624 */
1252 return _PyTime_GetClockWithInfo(tp, info);
1253 #endif
1254 }
1255
1256 static PyObject *
time_process_time(PyObject * self,PyObject * unused)1257 time_process_time(PyObject *self, PyObject *unused)
1258 {
1259 _PyTime_t t;
1260 if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
1261 return NULL;
1262 }
1263 return _PyFloat_FromPyTime(t);
1264 }
1265
1266 PyDoc_STRVAR(process_time_doc,
1267 "process_time() -> float\n\
1268 \n\
1269 Process time for profiling: sum of the kernel and user-space CPU time.");
1270
1271 static PyObject *
time_process_time_ns(PyObject * self,PyObject * unused)1272 time_process_time_ns(PyObject *self, PyObject *unused)
1273 {
1274 _PyTime_t t;
1275 if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
1276 return NULL;
1277 }
1278 return _PyTime_AsNanosecondsObject(t);
1279 }
1280
1281 PyDoc_STRVAR(process_time_ns_doc,
1282 "process_time() -> int\n\
1283 \n\
1284 Process time for profiling as nanoseconds:\n\
1285 sum of the kernel and user-space CPU time.");
1286
1287
1288 #if defined(MS_WINDOWS)
1289 #define HAVE_THREAD_TIME
1290 static int
_PyTime_GetThreadTimeWithInfo(_PyTime_t * tp,_Py_clock_info_t * info)1291 _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1292 {
1293 HANDLE thread;
1294 FILETIME creation_time, exit_time, kernel_time, user_time;
1295 ULARGE_INTEGER large;
1296 _PyTime_t ktime, utime, t;
1297 BOOL ok;
1298
1299 thread = GetCurrentThread();
1300 ok = GetThreadTimes(thread, &creation_time, &exit_time,
1301 &kernel_time, &user_time);
1302 if (!ok) {
1303 PyErr_SetFromWindowsErr(0);
1304 return -1;
1305 }
1306
1307 if (info) {
1308 info->implementation = "GetThreadTimes()";
1309 info->resolution = 1e-7;
1310 info->monotonic = 1;
1311 info->adjustable = 0;
1312 }
1313
1314 large.u.LowPart = kernel_time.dwLowDateTime;
1315 large.u.HighPart = kernel_time.dwHighDateTime;
1316 ktime = large.QuadPart;
1317
1318 large.u.LowPart = user_time.dwLowDateTime;
1319 large.u.HighPart = user_time.dwHighDateTime;
1320 utime = large.QuadPart;
1321
1322 /* ktime and utime have a resolution of 100 nanoseconds */
1323 t = _PyTime_FromNanoseconds((ktime + utime) * 100);
1324 *tp = t;
1325 return 0;
1326 }
1327
1328 #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
1329 #define HAVE_THREAD_TIME
1330 static int
_PyTime_GetThreadTimeWithInfo(_PyTime_t * tp,_Py_clock_info_t * info)1331 _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1332 {
1333 struct timespec ts;
1334 const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID;
1335 const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)";
1336
1337 if (clock_gettime(clk_id, &ts)) {
1338 PyErr_SetFromErrno(PyExc_OSError);
1339 return -1;
1340 }
1341 if (info) {
1342 struct timespec res;
1343 info->implementation = function;
1344 info->monotonic = 1;
1345 info->adjustable = 0;
1346 if (clock_getres(clk_id, &res)) {
1347 PyErr_SetFromErrno(PyExc_OSError);
1348 return -1;
1349 }
1350 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1351 }
1352
1353 if (_PyTime_FromTimespec(tp, &ts) < 0) {
1354 return -1;
1355 }
1356 return 0;
1357 }
1358 #endif
1359
1360 #ifdef HAVE_THREAD_TIME
1361 static PyObject *
time_thread_time(PyObject * self,PyObject * unused)1362 time_thread_time(PyObject *self, PyObject *unused)
1363 {
1364 _PyTime_t t;
1365 if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
1366 return NULL;
1367 }
1368 return _PyFloat_FromPyTime(t);
1369 }
1370
1371 PyDoc_STRVAR(thread_time_doc,
1372 "thread_time() -> float\n\
1373 \n\
1374 Thread time for profiling: sum of the kernel and user-space CPU time.");
1375
1376 static PyObject *
time_thread_time_ns(PyObject * self,PyObject * unused)1377 time_thread_time_ns(PyObject *self, PyObject *unused)
1378 {
1379 _PyTime_t t;
1380 if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
1381 return NULL;
1382 }
1383 return _PyTime_AsNanosecondsObject(t);
1384 }
1385
1386 PyDoc_STRVAR(thread_time_ns_doc,
1387 "thread_time() -> int\n\
1388 \n\
1389 Thread time for profiling as nanoseconds:\n\
1390 sum of the kernel and user-space CPU time.");
1391 #endif
1392
1393
1394 static PyObject *
time_get_clock_info(PyObject * self,PyObject * args)1395 time_get_clock_info(PyObject *self, PyObject *args)
1396 {
1397 char *name;
1398 _Py_clock_info_t info;
1399 PyObject *obj = NULL, *dict, *ns;
1400 _PyTime_t t;
1401
1402 if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) {
1403 return NULL;
1404 }
1405
1406 #ifdef Py_DEBUG
1407 info.implementation = NULL;
1408 info.monotonic = -1;
1409 info.adjustable = -1;
1410 info.resolution = -1.0;
1411 #else
1412 info.implementation = "";
1413 info.monotonic = 0;
1414 info.adjustable = 0;
1415 info.resolution = 1.0;
1416 #endif
1417
1418 if (strcmp(name, "time") == 0) {
1419 if (_PyTime_GetSystemClockWithInfo(&t, &info) < 0) {
1420 return NULL;
1421 }
1422 }
1423 #ifdef PYCLOCK
1424 else if (strcmp(name, "clock") == 0) {
1425 obj = pyclock(&info);
1426 if (obj == NULL) {
1427 return NULL;
1428 }
1429 Py_DECREF(obj);
1430 }
1431 #endif
1432 else if (strcmp(name, "monotonic") == 0) {
1433 if (_PyTime_GetMonotonicClockWithInfo(&t, &info) < 0) {
1434 return NULL;
1435 }
1436 }
1437 else if (strcmp(name, "perf_counter") == 0) {
1438 if (_PyTime_GetPerfCounterWithInfo(&t, &info) < 0) {
1439 return NULL;
1440 }
1441 }
1442 else if (strcmp(name, "process_time") == 0) {
1443 if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) {
1444 return NULL;
1445 }
1446 }
1447 #ifdef HAVE_THREAD_TIME
1448 else if (strcmp(name, "thread_time") == 0) {
1449 if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) {
1450 return NULL;
1451 }
1452 }
1453 #endif
1454 else {
1455 PyErr_SetString(PyExc_ValueError, "unknown clock");
1456 return NULL;
1457 }
1458
1459 dict = PyDict_New();
1460 if (dict == NULL) {
1461 return NULL;
1462 }
1463
1464 assert(info.implementation != NULL);
1465 obj = PyUnicode_FromString(info.implementation);
1466 if (obj == NULL) {
1467 goto error;
1468 }
1469 if (PyDict_SetItemString(dict, "implementation", obj) == -1) {
1470 goto error;
1471 }
1472 Py_CLEAR(obj);
1473
1474 assert(info.monotonic != -1);
1475 obj = PyBool_FromLong(info.monotonic);
1476 if (obj == NULL) {
1477 goto error;
1478 }
1479 if (PyDict_SetItemString(dict, "monotonic", obj) == -1) {
1480 goto error;
1481 }
1482 Py_CLEAR(obj);
1483
1484 assert(info.adjustable != -1);
1485 obj = PyBool_FromLong(info.adjustable);
1486 if (obj == NULL) {
1487 goto error;
1488 }
1489 if (PyDict_SetItemString(dict, "adjustable", obj) == -1) {
1490 goto error;
1491 }
1492 Py_CLEAR(obj);
1493
1494 assert(info.resolution > 0.0);
1495 assert(info.resolution <= 1.0);
1496 obj = PyFloat_FromDouble(info.resolution);
1497 if (obj == NULL) {
1498 goto error;
1499 }
1500 if (PyDict_SetItemString(dict, "resolution", obj) == -1) {
1501 goto error;
1502 }
1503 Py_CLEAR(obj);
1504
1505 ns = _PyNamespace_New(dict);
1506 Py_DECREF(dict);
1507 return ns;
1508
1509 error:
1510 Py_DECREF(dict);
1511 Py_XDECREF(obj);
1512 return NULL;
1513 }
1514
1515 PyDoc_STRVAR(get_clock_info_doc,
1516 "get_clock_info(name: str) -> dict\n\
1517 \n\
1518 Get information of the specified clock.");
1519
1520 #if !defined(HAVE_TZNAME) || defined(__GLIBC__) || defined(__CYGWIN__)
1521 static void
get_zone(char * zone,int n,struct tm * p)1522 get_zone(char *zone, int n, struct tm *p)
1523 {
1524 #ifdef HAVE_STRUCT_TM_TM_ZONE
1525 strncpy(zone, p->tm_zone ? p->tm_zone : " ", n);
1526 #else
1527 tzset();
1528 strftime(zone, n, "%Z", p);
1529 #endif
1530 }
1531
1532 static time_t
get_gmtoff(time_t t,struct tm * p)1533 get_gmtoff(time_t t, struct tm *p)
1534 {
1535 #ifdef HAVE_STRUCT_TM_TM_ZONE
1536 return p->tm_gmtoff;
1537 #else
1538 return timegm(p) - t;
1539 #endif
1540 }
1541 #endif /* !defined(HAVE_TZNAME) || defined(__GLIBC__) || defined(__CYGWIN__) */
1542
1543 static int
init_timezone(PyObject * m)1544 init_timezone(PyObject *m)
1545 {
1546 assert(!PyErr_Occurred());
1547
1548 /* This code moved from PyInit_time wholesale to allow calling it from
1549 time_tzset. In the future, some parts of it can be moved back
1550 (for platforms that don't HAVE_WORKING_TZSET, when we know what they
1551 are), and the extraneous calls to tzset(3) should be removed.
1552 I haven't done this yet, as I don't want to change this code as
1553 little as possible when introducing the time.tzset and time.tzsetwall
1554 methods. This should simply be a method of doing the following once,
1555 at the top of this function and removing the call to tzset() from
1556 time_tzset():
1557
1558 #ifdef HAVE_TZSET
1559 tzset()
1560 #endif
1561
1562 And I'm lazy and hate C so nyer.
1563 */
1564 #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
1565 PyObject *otz0, *otz1;
1566 tzset();
1567 PyModule_AddIntConstant(m, "timezone", _Py_timezone);
1568 #ifdef HAVE_ALTZONE
1569 PyModule_AddIntConstant(m, "altzone", altzone);
1570 #else
1571 PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600);
1572 #endif
1573 PyModule_AddIntConstant(m, "daylight", _Py_daylight);
1574 otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape");
1575 if (otz0 == NULL) {
1576 return -1;
1577 }
1578 otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape");
1579 if (otz1 == NULL) {
1580 Py_DECREF(otz0);
1581 return -1;
1582 }
1583 PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1);
1584 if (tzname_obj == NULL) {
1585 return -1;
1586 }
1587 PyModule_AddObject(m, "tzname", tzname_obj);
1588 #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
1589 {
1590 #define YEAR ((time_t)((365 * 24 + 6) * 3600))
1591 time_t t;
1592 struct tm p;
1593 time_t janzone_t, julyzone_t;
1594 char janname[10], julyname[10];
1595 t = (time((time_t *)0) / YEAR) * YEAR;
1596 _PyTime_localtime(t, &p);
1597 get_zone(janname, 9, &p);
1598 janzone_t = -get_gmtoff(t, &p);
1599 janname[9] = '\0';
1600 t += YEAR/2;
1601 _PyTime_localtime(t, &p);
1602 get_zone(julyname, 9, &p);
1603 julyzone_t = -get_gmtoff(t, &p);
1604 julyname[9] = '\0';
1605
1606 /* Sanity check, don't check for the validity of timezones.
1607 In practice, it should be more in range -12 hours .. +14 hours. */
1608 #define MAX_TIMEZONE (48 * 3600)
1609 if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE
1610 || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE)
1611 {
1612 PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset");
1613 return -1;
1614 }
1615 int janzone = (int)janzone_t;
1616 int julyzone = (int)julyzone_t;
1617
1618 if( janzone < julyzone ) {
1619 /* DST is reversed in the southern hemisphere */
1620 PyModule_AddIntConstant(m, "timezone", julyzone);
1621 PyModule_AddIntConstant(m, "altzone", janzone);
1622 PyModule_AddIntConstant(m, "daylight",
1623 janzone != julyzone);
1624 PyModule_AddObject(m, "tzname",
1625 Py_BuildValue("(zz)",
1626 julyname, janname));
1627 } else {
1628 PyModule_AddIntConstant(m, "timezone", janzone);
1629 PyModule_AddIntConstant(m, "altzone", julyzone);
1630 PyModule_AddIntConstant(m, "daylight",
1631 janzone != julyzone);
1632 PyModule_AddObject(m, "tzname",
1633 Py_BuildValue("(zz)",
1634 janname, julyname));
1635 }
1636 }
1637 #ifdef __CYGWIN__
1638 tzset();
1639 PyModule_AddIntConstant(m, "timezone", _timezone);
1640 PyModule_AddIntConstant(m, "altzone", _timezone-3600);
1641 PyModule_AddIntConstant(m, "daylight", _daylight);
1642 PyModule_AddObject(m, "tzname",
1643 Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
1644 #endif /* __CYGWIN__ */
1645 #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
1646
1647 if (PyErr_Occurred()) {
1648 return -1;
1649 }
1650 return 0;
1651 }
1652
1653
1654 static PyMethodDef time_methods[] = {
1655 {"time", time_time, METH_NOARGS, time_doc},
1656 {"time_ns", time_time_ns, METH_NOARGS, time_ns_doc},
1657 #ifdef PYCLOCK
1658 {"clock", time_clock, METH_NOARGS, clock_doc},
1659 #endif
1660 #ifdef HAVE_CLOCK_GETTIME
1661 {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc},
1662 {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc},
1663 #endif
1664 #ifdef HAVE_CLOCK_SETTIME
1665 {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc},
1666 {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc},
1667 #endif
1668 #ifdef HAVE_CLOCK_GETRES
1669 {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc},
1670 #endif
1671 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
1672 {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc},
1673 #endif
1674 {"sleep", time_sleep, METH_O, sleep_doc},
1675 {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc},
1676 {"localtime", time_localtime, METH_VARARGS, localtime_doc},
1677 {"asctime", time_asctime, METH_VARARGS, asctime_doc},
1678 {"ctime", time_ctime, METH_VARARGS, ctime_doc},
1679 #ifdef HAVE_MKTIME
1680 {"mktime", time_mktime, METH_O, mktime_doc},
1681 #endif
1682 #ifdef HAVE_STRFTIME
1683 {"strftime", time_strftime, METH_VARARGS, strftime_doc},
1684 #endif
1685 {"strptime", time_strptime, METH_VARARGS, strptime_doc},
1686 #ifdef HAVE_WORKING_TZSET
1687 {"tzset", time_tzset, METH_NOARGS, tzset_doc},
1688 #endif
1689 {"monotonic", time_monotonic, METH_NOARGS, monotonic_doc},
1690 {"monotonic_ns", time_monotonic_ns, METH_NOARGS, monotonic_ns_doc},
1691 {"process_time", time_process_time, METH_NOARGS, process_time_doc},
1692 {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc},
1693 #ifdef HAVE_THREAD_TIME
1694 {"thread_time", time_thread_time, METH_NOARGS, thread_time_doc},
1695 {"thread_time_ns", time_thread_time_ns, METH_NOARGS, thread_time_ns_doc},
1696 #endif
1697 {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc},
1698 {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc},
1699 {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc},
1700 {NULL, NULL} /* sentinel */
1701 };
1702
1703
1704 PyDoc_STRVAR(module_doc,
1705 "This module provides various functions to manipulate time values.\n\
1706 \n\
1707 There are two standard representations of time. One is the number\n\
1708 of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\
1709 or a floating point number (to represent fractions of seconds).\n\
1710 The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
1711 The actual value can be retrieved by calling gmtime(0).\n\
1712 \n\
1713 The other representation is a tuple of 9 integers giving local time.\n\
1714 The tuple items are:\n\
1715 year (including century, e.g. 1998)\n\
1716 month (1-12)\n\
1717 day (1-31)\n\
1718 hours (0-23)\n\
1719 minutes (0-59)\n\
1720 seconds (0-59)\n\
1721 weekday (0-6, Monday is 0)\n\
1722 Julian day (day in the year, 1-366)\n\
1723 DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
1724 If the DST flag is 0, the time is given in the regular time zone;\n\
1725 if it is 1, the time is given in the DST time zone;\n\
1726 if it is -1, mktime() should guess based on the date and time.\n");
1727
1728
1729
1730 static struct PyModuleDef timemodule = {
1731 PyModuleDef_HEAD_INIT,
1732 "time",
1733 module_doc,
1734 -1,
1735 time_methods,
1736 NULL,
1737 NULL,
1738 NULL,
1739 NULL
1740 };
1741
1742 PyMODINIT_FUNC
PyInit_time(void)1743 PyInit_time(void)
1744 {
1745 PyObject *m;
1746 m = PyModule_Create(&timemodule);
1747 if (m == NULL)
1748 return NULL;
1749
1750 /* Set, or reset, module variables like time.timezone */
1751 if (init_timezone(m) < 0) {
1752 return NULL;
1753 }
1754
1755 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES)
1756
1757 #ifdef CLOCK_REALTIME
1758 PyModule_AddIntMacro(m, CLOCK_REALTIME);
1759 #endif
1760 #ifdef CLOCK_MONOTONIC
1761 PyModule_AddIntMacro(m, CLOCK_MONOTONIC);
1762 #endif
1763 #ifdef CLOCK_MONOTONIC_RAW
1764 PyModule_AddIntMacro(m, CLOCK_MONOTONIC_RAW);
1765 #endif
1766 #ifdef CLOCK_HIGHRES
1767 PyModule_AddIntMacro(m, CLOCK_HIGHRES);
1768 #endif
1769 #ifdef CLOCK_PROCESS_CPUTIME_ID
1770 PyModule_AddIntMacro(m, CLOCK_PROCESS_CPUTIME_ID);
1771 #endif
1772 #ifdef CLOCK_THREAD_CPUTIME_ID
1773 PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID);
1774 #endif
1775 #ifdef CLOCK_PROF
1776 PyModule_AddIntMacro(m, CLOCK_PROF);
1777 #endif
1778 #ifdef CLOCK_BOOTTIME
1779 PyModule_AddIntMacro(m, CLOCK_BOOTTIME);
1780 #endif
1781 #ifdef CLOCK_UPTIME
1782 PyModule_AddIntMacro(m, CLOCK_UPTIME);
1783 #endif
1784
1785 #endif /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */
1786
1787 if (!initialized) {
1788 if (PyStructSequence_InitType2(&StructTimeType,
1789 &struct_time_type_desc) < 0)
1790 return NULL;
1791 }
1792 Py_INCREF(&StructTimeType);
1793 PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 11);
1794 PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
1795 initialized = 1;
1796
1797 if (PyErr_Occurred()) {
1798 return NULL;
1799 }
1800 return m;
1801 }
1802
1803 /* Implement pysleep() for various platforms.
1804 When interrupted (or when another error occurs), return -1 and
1805 set an exception; else return 0. */
1806
1807 static int
pysleep(_PyTime_t secs)1808 pysleep(_PyTime_t secs)
1809 {
1810 _PyTime_t deadline, monotonic;
1811 #ifndef MS_WINDOWS
1812 struct timeval timeout;
1813 int err = 0;
1814 #else
1815 _PyTime_t millisecs;
1816 unsigned long ul_millis;
1817 DWORD rc;
1818 HANDLE hInterruptEvent;
1819 #endif
1820
1821 deadline = _PyTime_GetMonotonicClock() + secs;
1822
1823 do {
1824 #ifndef MS_WINDOWS
1825 if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0)
1826 return -1;
1827
1828 Py_BEGIN_ALLOW_THREADS
1829 err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
1830 Py_END_ALLOW_THREADS
1831
1832 if (err == 0)
1833 break;
1834
1835 if (errno != EINTR) {
1836 PyErr_SetFromErrno(PyExc_OSError);
1837 return -1;
1838 }
1839 #else
1840 millisecs = _PyTime_AsMilliseconds(secs, _PyTime_ROUND_CEILING);
1841 if (millisecs > (double)ULONG_MAX) {
1842 PyErr_SetString(PyExc_OverflowError,
1843 "sleep length is too large");
1844 return -1;
1845 }
1846
1847 /* Allow sleep(0) to maintain win32 semantics, and as decreed
1848 * by Guido, only the main thread can be interrupted.
1849 */
1850 ul_millis = (unsigned long)millisecs;
1851 if (ul_millis == 0 || !_PyOS_IsMainThread()) {
1852 Py_BEGIN_ALLOW_THREADS
1853 Sleep(ul_millis);
1854 Py_END_ALLOW_THREADS
1855 break;
1856 }
1857
1858 hInterruptEvent = _PyOS_SigintEvent();
1859 ResetEvent(hInterruptEvent);
1860
1861 Py_BEGIN_ALLOW_THREADS
1862 rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
1863 Py_END_ALLOW_THREADS
1864
1865 if (rc != WAIT_OBJECT_0)
1866 break;
1867 #endif
1868
1869 /* sleep was interrupted by SIGINT */
1870 if (PyErr_CheckSignals())
1871 return -1;
1872
1873 monotonic = _PyTime_GetMonotonicClock();
1874 secs = deadline - monotonic;
1875 if (secs < 0)
1876 break;
1877 /* retry with the recomputed delay */
1878 } while (1);
1879
1880 return 0;
1881 }
1882