• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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