Coverage Report

Created: 2026-05-30 06:18

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