Coverage Report

Created: 2025-07-11 06:59

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