Coverage Report

Created: 2025-07-11 06:24

/src/cpython/Modules/timemodule.c
Line
Count
Source (jump to first uncovered line)
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
16
#  define HAVE_CLOCK_GETTIME_RUNTIME 1
61
#endif
62
63
64
32
#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
4.15k
{
93
4.15k
    void *state = _PyModule_GetState(module);
94
4.15k
    assert(state != NULL);
95
4.15k
    return (time_module_state *)state;
96
4.15k
}
97
98
99
static PyObject*
100
_PyFloat_FromPyTime(PyTime_t t)
101
0
{
102
0
    double d = PyTime_AsSecondsDouble(t);
103
0
    return PyFloat_FromDouble(d);
104
0
}
105
106
107
static PyObject *
108
time_time(PyObject *self, PyObject *unused)
109
0
{
110
0
    PyTime_t t;
111
0
    if (PyTime_Time(&t) < 0) {
112
0
        return NULL;
113
0
    }
114
0
    return _PyFloat_FromPyTime(t);
115
0
}
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
0
{
127
0
    PyTime_t t;
128
0
    if (PyTime_Time(&t) < 0) {
129
0
        return NULL;
130
0
    }
131
0
    return _PyTime_AsLong(t);
132
0
}
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 _PyTime_AsLong(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 (_PyTime_FromLong(&t, obj) < 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
0
{
614
0
    int y;
615
616
0
    memset((void *) p, '\0', sizeof(struct tm));
617
618
0
    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
0
    if (!PyArg_ParseTuple(args, format,
625
0
                          &y, &p->tm_mon, &p->tm_mday,
626
0
                          &p->tm_hour, &p->tm_min, &p->tm_sec,
627
0
                          &p->tm_wday, &p->tm_yday, &p->tm_isdst))
628
0
        return 0;
629
630
0
    if (y < INT_MIN + 1900) {
631
0
        PyErr_SetString(PyExc_OverflowError, "year out of range");
632
0
        return 0;
633
0
    }
634
635
0
    p->tm_year = y - 1900;
636
0
    p->tm_mon--;
637
0
    p->tm_wday = (p->tm_wday + 1) % 7;
638
0
    p->tm_yday--;
639
0
#ifdef HAVE_STRUCT_TM_TM_ZONE
640
0
    if (Py_IS_TYPE(args, state->struct_time_type)) {
641
0
        PyObject *item;
642
0
        item = PyStructSequence_GET_ITEM(args, 9);
643
0
        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
0
        item = PyStructSequence_GET_ITEM(args, 10);
664
0
        if (item != Py_None) {
665
0
            p->tm_gmtoff = PyLong_AsLong(item);
666
0
            if (PyErr_Occurred())
667
0
                return 0;
668
0
        }
669
0
    }
670
0
#endif /* HAVE_STRUCT_TM_TM_ZONE */
671
0
    return 1;
672
0
}
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
0
{
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
0
    if (buf->tm_mon == -1)
706
0
        buf->tm_mon = 0;
707
0
    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
0
    if (buf->tm_mday == 0)
712
0
        buf->tm_mday = 1;
713
0
    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
0
    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
0
    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
0
    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
0
    if (buf->tm_wday < 0) {
732
0
        PyErr_SetString(PyExc_ValueError, "day of week out of range");
733
0
        return 0;
734
0
    }
735
0
    if (buf->tm_yday == -1)
736
0
        buf->tm_yday = 0;
737
0
    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
0
    return 1;
742
0
}
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
0
#define time_char wchar_t
768
0
#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
0
{
781
0
    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
0
    while (1) {
819
0
        if (*bufsize > PY_SSIZE_T_MAX/sizeof(time_char)) {
820
0
            PyErr_NoMemory();
821
0
            return NULL;
822
0
        }
823
0
        *outbuf = (time_char *)PyMem_Realloc(*outbuf,
824
0
                                             *bufsize*sizeof(time_char));
825
0
        if (*outbuf == NULL) {
826
0
            PyErr_NoMemory();
827
0
            return NULL;
828
0
        }
829
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
830
        errno = 0;
831
#endif
832
0
        _Py_BEGIN_SUPPRESS_IPH
833
0
        buflen = format_time(*outbuf, *bufsize, format, tm);
834
0
        _Py_END_SUPPRESS_IPH
835
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
836
        /* VisualStudio .NET 2005 does this properly */
837
        if (buflen == 0 && errno == EINVAL) {
838
            PyErr_SetString(PyExc_ValueError, "Invalid format string");
839
            return NULL;
840
        }
841
#endif
842
0
        if (buflen == 0 && *bufsize < 256 * fmtlen) {
843
0
            *bufsize += *bufsize;
844
0
            continue;
845
0
        }
846
        /* If the buffer is 256 times as long as the format,
847
           it's probably not failing for lack of room!
848
           More likely, the format yields an empty result,
849
           e.g. an empty format, or %Z when the timezone
850
           is unknown. */
851
0
#ifdef HAVE_WCSFTIME
852
0
        return PyUnicode_FromWideChar(*outbuf, buflen);
853
#else
854
        return PyUnicode_DecodeLocaleAndSize(*outbuf, buflen, "surrogateescape");
855
#endif
856
0
    }
857
0
}
858
859
static PyObject *
860
time_strftime(PyObject *module, PyObject *args)
861
0
{
862
0
    PyObject *tup = NULL;
863
0
    struct tm buf;
864
0
    PyObject *format_arg;
865
0
    Py_ssize_t format_size;
866
0
    time_char *format, *outbuf = NULL;
867
0
    size_t fmtlen, bufsize = 1024;
868
869
0
    memset((void *) &buf, '\0', sizeof(buf));
870
871
0
    if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup))
872
0
        return NULL;
873
874
0
    time_module_state *state = get_time_state(module);
875
0
    if (tup == NULL) {
876
0
        time_t tt = time(NULL);
877
0
        if (_PyTime_localtime(tt, &buf) != 0)
878
0
            return NULL;
879
0
    }
880
0
    else if (!gettmarg(state, tup, &buf,
881
0
                       "iiiiiiiii;strftime(): illegal time tuple argument") ||
882
0
             !checktm(&buf))
883
0
    {
884
0
        return NULL;
885
0
    }
886
887
// Some platforms only support a limited range of years.
888
//
889
// Android works with negative years on the emulator, but fails on some
890
// physical devices (#123017).
891
#if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) \
892
    || defined(__VXWORKS__) || defined(__ANDROID__)
893
    if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
894
        PyErr_SetString(PyExc_ValueError,
895
                        "strftime() requires year in [1; 9999]");
896
        return NULL;
897
    }
898
#endif
899
900
    /* Normalize tm_isdst just in case someone foolishly implements %Z
901
       based on the assumption that tm_isdst falls within the range of
902
       [-1, 1] */
903
0
    if (buf.tm_isdst < -1)
904
0
        buf.tm_isdst = -1;
905
0
    else if (buf.tm_isdst > 1)
906
0
        buf.tm_isdst = 1;
907
908
0
    format_size = PyUnicode_GET_LENGTH(format_arg);
909
0
    if ((size_t)format_size > PY_SSIZE_T_MAX/sizeof(time_char) - 1) {
910
0
        PyErr_NoMemory();
911
0
        return NULL;
912
0
    }
913
0
    format = PyMem_Malloc((format_size + 1)*sizeof(time_char));
914
0
    if (format == NULL) {
915
0
        PyErr_NoMemory();
916
0
        return NULL;
917
0
    }
918
0
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
919
0
    if (writer == NULL) {
920
0
        goto error;
921
0
    }
922
0
    Py_ssize_t i = 0;
923
0
    while (i < format_size) {
924
0
        fmtlen = 0;
925
0
        for (; i < format_size; i++) {
926
0
            Py_UCS4 c = PyUnicode_READ_CHAR(format_arg, i);
927
0
            if (!c || c > 127) {
928
0
                break;
929
0
            }
930
0
            format[fmtlen++] = (char)c;
931
0
        }
932
0
        if (fmtlen) {
933
0
            format[fmtlen] = 0;
934
0
            PyObject *unicode = time_strftime1(&outbuf, &bufsize,
935
0
                                               format, fmtlen, &buf);
936
0
            if (unicode == NULL) {
937
0
                goto error;
938
0
            }
939
0
            if (PyUnicodeWriter_WriteStr(writer, unicode) < 0) {
940
0
                Py_DECREF(unicode);
941
0
                goto error;
942
0
            }
943
0
            Py_DECREF(unicode);
944
0
        }
945
946
0
        Py_ssize_t start = i;
947
0
        for (; i < format_size; i++) {
948
0
            Py_UCS4 c = PyUnicode_READ_CHAR(format_arg, i);
949
0
            if (c == '%') {
950
0
                break;
951
0
            }
952
0
        }
953
0
        if (PyUnicodeWriter_WriteSubstring(writer, format_arg, start, i) < 0) {
954
0
            goto error;
955
0
        }
956
0
    }
957
958
0
    PyMem_Free(outbuf);
959
0
    PyMem_Free(format);
960
0
    return PyUnicodeWriter_Finish(writer);
961
0
error:
962
0
    PyMem_Free(outbuf);
963
0
    PyMem_Free(format);
964
0
    PyUnicodeWriter_Discard(writer);
965
0
    return NULL;
966
0
}
967
968
#undef time_char
969
#undef format_time
970
PyDoc_STRVAR(strftime_doc,
971
"strftime(format[, tuple]) -> string\n\
972
\n\
973
Convert a time tuple to a string according to a format specification.\n\
974
See the library reference manual for formatting codes. When the time tuple\n\
975
is not present, current time as returned by localtime() is used.\n\
976
\n" STRFTIME_FORMAT_CODES);
977
#endif /* HAVE_STRFTIME */
978
979
static PyObject *
980
time_strptime(PyObject *self, PyObject *args)
981
0
{
982
0
    PyObject *func, *result;
983
984
0
    func = PyImport_ImportModuleAttrString("_strptime", "_strptime_time");
985
0
    if (!func) {
986
0
        return NULL;
987
0
    }
988
989
0
    result = PyObject_Call(func, args, NULL);
990
0
    Py_DECREF(func);
991
0
    return result;
992
0
}
993
994
995
PyDoc_STRVAR(strptime_doc,
996
"strptime(string, format) -> struct_time\n\
997
\n\
998
Parse a string to a time tuple according to a format specification.\n\
999
See the library reference manual for formatting codes (same as\n\
1000
strftime()).\n\
1001
\n" STRFTIME_FORMAT_CODES);
1002
1003
static PyObject *
1004
_asctime(struct tm *timeptr)
1005
0
{
1006
    /* Inspired by Open Group reference implementation available at
1007
     * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */
1008
0
    static const char wday_name[7][4] = {
1009
0
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
1010
0
    };
1011
0
    static const char mon_name[12][4] = {
1012
0
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1013
0
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1014
0
    };
1015
0
    return PyUnicode_FromFormat(
1016
0
        "%s %s%3d %.2d:%.2d:%.2d %d",
1017
0
        wday_name[timeptr->tm_wday],
1018
0
        mon_name[timeptr->tm_mon],
1019
0
        timeptr->tm_mday, timeptr->tm_hour,
1020
0
        timeptr->tm_min, timeptr->tm_sec,
1021
0
        1900 + timeptr->tm_year);
1022
0
}
1023
1024
static PyObject *
1025
time_asctime(PyObject *module, PyObject *args)
1026
0
{
1027
0
    PyObject *tup = NULL;
1028
0
    struct tm buf;
1029
1030
0
    if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
1031
0
        return NULL;
1032
1033
0
    time_module_state *state = get_time_state(module);
1034
0
    if (tup == NULL) {
1035
0
        time_t tt = time(NULL);
1036
0
        if (_PyTime_localtime(tt, &buf) != 0)
1037
0
            return NULL;
1038
0
    }
1039
0
    else if (!gettmarg(state, tup, &buf,
1040
0
                       "iiiiiiiii;asctime(): illegal time tuple argument") ||
1041
0
             !checktm(&buf))
1042
0
    {
1043
0
        return NULL;
1044
0
    }
1045
0
    return _asctime(&buf);
1046
0
}
1047
1048
PyDoc_STRVAR(asctime_doc,
1049
"asctime([tuple]) -> string\n\
1050
\n\
1051
Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
1052
When the time tuple is not present, current time as returned by localtime()\n\
1053
is used.");
1054
1055
static PyObject *
1056
time_ctime(PyObject *self, PyObject *args)
1057
0
{
1058
0
    time_t tt;
1059
0
    struct tm buf;
1060
0
    if (!parse_time_t_args(args, "|O:ctime", &tt))
1061
0
        return NULL;
1062
0
    if (_PyTime_localtime(tt, &buf) != 0)
1063
0
        return NULL;
1064
0
    return _asctime(&buf);
1065
0
}
1066
1067
PyDoc_STRVAR(ctime_doc,
1068
"ctime(seconds) -> string\n\
1069
\n\
1070
Convert a time in seconds since the Epoch to a string in local time.\n\
1071
This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
1072
not present, current time as returned by localtime() is used.");
1073
1074
#ifdef HAVE_MKTIME
1075
static PyObject *
1076
time_mktime(PyObject *module, PyObject *tm_tuple)
1077
0
{
1078
0
    struct tm tm;
1079
0
    time_t tt;
1080
1081
0
    time_module_state *state = get_time_state(module);
1082
0
    if (!gettmarg(state, tm_tuple, &tm,
1083
0
                  "iiiiiiiii;mktime(): illegal time tuple argument"))
1084
0
    {
1085
0
        return NULL;
1086
0
    }
1087
1088
#if defined(_AIX) || (defined(__VXWORKS__) && !defined(_WRS_CONFIG_LP64))
1089
    /* bpo-19748: AIX mktime() valid range is 00:00:00 UTC, January 1, 1970
1090
       to 03:14:07 UTC, January 19, 2038. Thanks to the workaround below,
1091
       it is possible to support years in range [1902; 2037] */
1092
    if (tm.tm_year < 2 || tm.tm_year > 137) {
1093
        /* bpo-19748: On AIX, mktime() does not report overflow error
1094
           for timestamp < -2^31 or timestamp > 2**31-1. VxWorks has the
1095
           same issue when working in 32 bit mode. */
1096
        PyErr_SetString(PyExc_OverflowError,
1097
                        "mktime argument out of range");
1098
        return NULL;
1099
    }
1100
#endif
1101
1102
#ifdef _AIX
1103
    /* bpo-34373: AIX mktime() has an integer overflow for years in range
1104
       [1902; 1969]. Workaround the issue by using a year greater or equal than
1105
       1970 (tm_year >= 70): mktime() behaves correctly in that case
1106
       (ex: properly report errors). tm_year and tm_wday are adjusted after
1107
       mktime() call. */
1108
    int orig_tm_year = tm.tm_year;
1109
    int delta_days = 0;
1110
    while (tm.tm_year < 70) {
1111
        /* Use 4 years to account properly leap years */
1112
        tm.tm_year += 4;
1113
        delta_days -= (366 + (365 * 3));
1114
    }
1115
#endif
1116
1117
0
    tm.tm_wday = -1;  /* sentinel; original value ignored */
1118
0
    tt = mktime(&tm);
1119
1120
    /* Return value of -1 does not necessarily mean an error, but tm_wday
1121
     * cannot remain set to -1 if mktime succeeded. */
1122
0
    if (tt == (time_t)(-1)
1123
        /* Return value of -1 does not necessarily mean an error, but
1124
         * tm_wday cannot remain set to -1 if mktime succeeded. */
1125
0
        && tm.tm_wday == -1)
1126
0
    {
1127
0
        PyErr_SetString(PyExc_OverflowError,
1128
0
                        "mktime argument out of range");
1129
0
        return NULL;
1130
0
    }
1131
1132
#ifdef _AIX
1133
    if (delta_days != 0) {
1134
        tm.tm_year = orig_tm_year;
1135
        if (tm.tm_wday != -1) {
1136
            tm.tm_wday = (tm.tm_wday + delta_days) % 7;
1137
        }
1138
        tt += delta_days * (24 * 3600);
1139
    }
1140
#endif
1141
1142
0
    return PyFloat_FromDouble((double)tt);
1143
0
}
1144
1145
PyDoc_STRVAR(mktime_doc,
1146
"mktime(tuple) -> floating-point number\n\
1147
\n\
1148
Convert a time tuple in local time to seconds since the Epoch.\n\
1149
Note that mktime(gmtime(0)) will not generally return zero for most\n\
1150
time zones; instead the returned value will either be equal to that\n\
1151
of the timezone or altzone attributes on the time module.");
1152
#endif /* HAVE_MKTIME */
1153
1154
#ifdef HAVE_WORKING_TZSET
1155
static int init_timezone(PyObject *module);
1156
1157
static PyObject *
1158
time_tzset(PyObject *self, PyObject *unused)
1159
0
{
1160
0
    PyObject* m;
1161
1162
0
    m = PyImport_ImportModule("time");
1163
0
    if (m == NULL) {
1164
0
        return NULL;
1165
0
    }
1166
1167
0
#if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
1168
0
    tzset();
1169
0
#endif
1170
1171
    /* Reset timezone, altzone, daylight and tzname */
1172
0
    if (init_timezone(m) < 0) {
1173
0
         return NULL;
1174
0
    }
1175
0
    Py_DECREF(m);
1176
0
    if (PyErr_Occurred())
1177
0
        return NULL;
1178
1179
0
    Py_RETURN_NONE;
1180
0
}
1181
1182
PyDoc_STRVAR(tzset_doc,
1183
"tzset()\n\
1184
\n\
1185
Initialize, or reinitialize, the local timezone to the value stored in\n\
1186
os.environ['TZ']. The TZ environment variable should be specified in\n\
1187
standard Unix timezone format as documented in the tzset man page\n\
1188
(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
1189
fall back to UTC. If the TZ environment variable is not set, the local\n\
1190
timezone is set to the systems best guess of wallclock time.\n\
1191
Changing the TZ environment variable without calling tzset *may* change\n\
1192
the local timezone used by methods such as localtime, but this behaviour\n\
1193
should not be relied on.");
1194
#endif /* HAVE_WORKING_TZSET */
1195
1196
1197
static PyObject *
1198
time_monotonic(PyObject *self, PyObject *unused)
1199
0
{
1200
0
    PyTime_t t;
1201
0
    if (PyTime_Monotonic(&t) < 0) {
1202
0
        return NULL;
1203
0
    }
1204
0
    return _PyFloat_FromPyTime(t);
1205
0
}
1206
1207
PyDoc_STRVAR(monotonic_doc,
1208
"monotonic() -> float\n\
1209
\n\
1210
Monotonic clock, cannot go backward.");
1211
1212
static PyObject *
1213
time_monotonic_ns(PyObject *self, PyObject *unused)
1214
0
{
1215
0
    PyTime_t t;
1216
0
    if (PyTime_Monotonic(&t) < 0) {
1217
0
        return NULL;
1218
0
    }
1219
0
    return _PyTime_AsLong(t);
1220
0
}
1221
1222
PyDoc_STRVAR(monotonic_ns_doc,
1223
"monotonic_ns() -> int\n\
1224
\n\
1225
Monotonic clock, cannot go backward, as nanoseconds.");
1226
1227
1228
static PyObject *
1229
time_perf_counter(PyObject *self, PyObject *unused)
1230
0
{
1231
0
    PyTime_t t;
1232
0
    if (PyTime_PerfCounter(&t) < 0) {
1233
0
        return NULL;
1234
0
    }
1235
0
    return _PyFloat_FromPyTime(t);
1236
0
}
1237
1238
PyDoc_STRVAR(perf_counter_doc,
1239
"perf_counter() -> float\n\
1240
\n\
1241
Performance counter for benchmarking.");
1242
1243
1244
static PyObject *
1245
time_perf_counter_ns(PyObject *self, PyObject *unused)
1246
0
{
1247
0
    PyTime_t t;
1248
0
    if (PyTime_PerfCounter(&t) < 0) {
1249
0
        return NULL;
1250
0
    }
1251
0
    return _PyTime_AsLong(t);
1252
0
}
1253
1254
PyDoc_STRVAR(perf_counter_ns_doc,
1255
"perf_counter_ns() -> int\n\
1256
\n\
1257
Performance counter for benchmarking as nanoseconds.");
1258
1259
1260
// gh-115714: Don't use times() on WASI.
1261
#if defined(HAVE_TIMES) && !defined(__wasi__)
1262
static int
1263
process_time_times(time_module_state *state, PyTime_t *tp,
1264
                   _Py_clock_info_t *info)
1265
0
{
1266
0
    _PyTimeFraction *base = &state->times_base;
1267
1268
0
    struct tms process;
1269
0
    if (times(&process) == (clock_t)-1) {
1270
0
        return 0;
1271
0
    }
1272
1273
0
    if (info) {
1274
0
        info->implementation = "times()";
1275
0
        info->resolution = _PyTimeFraction_Resolution(base);
1276
0
        info->monotonic = 1;
1277
0
        info->adjustable = 0;
1278
0
    }
1279
1280
0
    PyTime_t ns;
1281
0
    ns = _PyTimeFraction_Mul(process.tms_utime, base);
1282
0
    ns += _PyTimeFraction_Mul(process.tms_stime, base);
1283
0
    *tp = ns;
1284
0
    return 1;
1285
0
}
1286
#endif
1287
1288
1289
static int
1290
py_process_time(time_module_state *state, PyTime_t *tp,
1291
                _Py_clock_info_t *info)
1292
0
{
1293
#if defined(MS_WINDOWS)
1294
    HANDLE process;
1295
    FILETIME creation_time, exit_time, kernel_time, user_time;
1296
    ULARGE_INTEGER large;
1297
    PyTime_t ktime, utime;
1298
    BOOL ok;
1299
1300
    process = GetCurrentProcess();
1301
    ok = GetProcessTimes(process, &creation_time, &exit_time,
1302
                         &kernel_time, &user_time);
1303
    if (!ok) {
1304
        PyErr_SetFromWindowsErr(0);
1305
        return -1;
1306
    }
1307
1308
    if (info) {
1309
        info->implementation = "GetProcessTimes()";
1310
        info->resolution = 1e-7;
1311
        info->monotonic = 1;
1312
        info->adjustable = 0;
1313
    }
1314
1315
    large.u.LowPart = kernel_time.dwLowDateTime;
1316
    large.u.HighPart = kernel_time.dwHighDateTime;
1317
    ktime = large.QuadPart;
1318
1319
    large.u.LowPart = user_time.dwLowDateTime;
1320
    large.u.HighPart = user_time.dwHighDateTime;
1321
    utime = large.QuadPart;
1322
1323
    /* ktime and utime have a resolution of 100 nanoseconds */
1324
    *tp = (ktime + utime) * 100;
1325
    return 0;
1326
#else
1327
1328
    /* clock_gettime */
1329
// gh-115714: Don't use CLOCK_PROCESS_CPUTIME_ID on WASI.
1330
/* CLOCK_PROF is defined on NetBSD, but not supported.
1331
 * CLOCK_PROCESS_CPUTIME_ID is broken on NetBSD for the same reason as
1332
 * CLOCK_THREAD_CPUTIME_ID (see comment below).
1333
 */
1334
0
#if defined(HAVE_CLOCK_GETTIME) \
1335
0
    && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF)) \
1336
0
    && !defined(__wasi__) \
1337
0
    && !defined(__NetBSD__)
1338
0
    struct timespec ts;
1339
1340
0
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
1341
1342
#ifdef CLOCK_PROF
1343
        const clockid_t clk_id = CLOCK_PROF;
1344
        const char *function = "clock_gettime(CLOCK_PROF)";
1345
#else
1346
0
        const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
1347
0
        const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
1348
0
#endif
1349
1350
0
        if (clock_gettime(clk_id, &ts) == 0) {
1351
0
            if (info) {
1352
0
                struct timespec res;
1353
0
                info->implementation = function;
1354
0
                info->monotonic = 1;
1355
0
                info->adjustable = 0;
1356
0
                if (clock_getres(clk_id, &res)) {
1357
0
                    PyErr_SetFromErrno(PyExc_OSError);
1358
0
                    return -1;
1359
0
                }
1360
0
                info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1361
0
            }
1362
1363
0
            if (_PyTime_FromTimespec(tp, &ts) < 0) {
1364
0
                return -1;
1365
0
            }
1366
0
            return 0;
1367
0
        }
1368
0
    }
1369
0
#endif
1370
1371
    /* getrusage(RUSAGE_SELF) */
1372
0
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRUSAGE)
1373
0
    struct rusage ru;
1374
1375
0
    if (getrusage(RUSAGE_SELF, &ru) == 0) {
1376
0
        PyTime_t utime, stime;
1377
1378
0
        if (info) {
1379
0
            info->implementation = "getrusage(RUSAGE_SELF)";
1380
0
            info->monotonic = 1;
1381
0
            info->adjustable = 0;
1382
0
            info->resolution = 1e-6;
1383
0
        }
1384
1385
0
        if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) {
1386
0
            return -1;
1387
0
        }
1388
0
        if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) {
1389
0
            return -1;
1390
0
        }
1391
1392
0
        PyTime_t total = utime + stime;
1393
0
        *tp = total;
1394
0
        return 0;
1395
0
    }
1396
0
#endif
1397
1398
    /* times() */
1399
// gh-115714: Don't use times() on WASI.
1400
0
#if defined(HAVE_TIMES) && !defined(__wasi__)
1401
0
    int res = process_time_times(state, tp, info);
1402
0
    if (res < 0) {
1403
0
        return -1;
1404
0
    }
1405
0
    if (res == 1) {
1406
0
        return 0;
1407
0
    }
1408
    // times() failed, ignore failure
1409
0
#endif
1410
1411
    /* clock(). Python 3 requires clock() to build (see gh-66814) */
1412
0
    return py_clock(state, tp, info);
1413
0
#endif
1414
0
}
1415
1416
static PyObject *
1417
time_process_time(PyObject *module, PyObject *unused)
1418
0
{
1419
0
    time_module_state *state = get_time_state(module);
1420
0
    PyTime_t t;
1421
0
    if (py_process_time(state, &t, NULL) < 0) {
1422
0
        return NULL;
1423
0
    }
1424
0
    return _PyFloat_FromPyTime(t);
1425
0
}
1426
1427
PyDoc_STRVAR(process_time_doc,
1428
"process_time() -> float\n\
1429
\n\
1430
Process time for profiling: sum of the kernel and user-space CPU time.");
1431
1432
static PyObject *
1433
time_process_time_ns(PyObject *module, PyObject *unused)
1434
0
{
1435
0
    time_module_state *state = get_time_state(module);
1436
0
    PyTime_t t;
1437
0
    if (py_process_time(state, &t, NULL) < 0) {
1438
0
        return NULL;
1439
0
    }
1440
0
    return _PyTime_AsLong(t);
1441
0
}
1442
1443
PyDoc_STRVAR(process_time_ns_doc,
1444
"process_time() -> int\n\
1445
\n\
1446
Process time for profiling as nanoseconds:\n\
1447
sum of the kernel and user-space CPU time.");
1448
1449
1450
#if defined(MS_WINDOWS)
1451
#define HAVE_THREAD_TIME
1452
static int
1453
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1454
{
1455
    HANDLE thread;
1456
    FILETIME creation_time, exit_time, kernel_time, user_time;
1457
    ULARGE_INTEGER large;
1458
    PyTime_t ktime, utime;
1459
    BOOL ok;
1460
1461
    thread =  GetCurrentThread();
1462
    ok = GetThreadTimes(thread, &creation_time, &exit_time,
1463
                        &kernel_time, &user_time);
1464
    if (!ok) {
1465
        PyErr_SetFromWindowsErr(0);
1466
        return -1;
1467
    }
1468
1469
    if (info) {
1470
        info->implementation = "GetThreadTimes()";
1471
        info->resolution = 1e-7;
1472
        info->monotonic = 1;
1473
        info->adjustable = 0;
1474
    }
1475
1476
    large.u.LowPart = kernel_time.dwLowDateTime;
1477
    large.u.HighPart = kernel_time.dwHighDateTime;
1478
    ktime = large.QuadPart;
1479
1480
    large.u.LowPart = user_time.dwLowDateTime;
1481
    large.u.HighPart = user_time.dwHighDateTime;
1482
    utime = large.QuadPart;
1483
1484
    /* ktime and utime have a resolution of 100 nanoseconds */
1485
    *tp = (ktime + utime) * 100;
1486
    return 0;
1487
}
1488
1489
#elif defined(_AIX)
1490
#define HAVE_THREAD_TIME
1491
static int
1492
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1493
{
1494
    /* bpo-40192: On AIX, thread_cputime() is preferred: it has nanosecond
1495
       resolution, whereas clock_gettime(CLOCK_THREAD_CPUTIME_ID)
1496
       has a resolution of 10 ms. */
1497
    thread_cputime_t tc;
1498
    if (thread_cputime(-1, &tc) != 0) {
1499
        PyErr_SetFromErrno(PyExc_OSError);
1500
        return -1;
1501
    }
1502
1503
    if (info) {
1504
        info->implementation = "thread_cputime()";
1505
        info->monotonic = 1;
1506
        info->adjustable = 0;
1507
        info->resolution = 1e-9;
1508
    }
1509
    *tp = (tc.stime + tc.utime);
1510
    return 0;
1511
}
1512
1513
#elif defined(__sun) && defined(__SVR4)
1514
#define HAVE_THREAD_TIME
1515
static int
1516
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1517
{
1518
    /* bpo-35455: On Solaris, CLOCK_THREAD_CPUTIME_ID clock is not always
1519
       available; use gethrvtime() to substitute this functionality. */
1520
    if (info) {
1521
        info->implementation = "gethrvtime()";
1522
        info->resolution = 1e-9;
1523
        info->monotonic = 1;
1524
        info->adjustable = 0;
1525
    }
1526
    *tp = gethrvtime();
1527
    return 0;
1528
}
1529
1530
/* CLOCK_THREAD_CPUTIME_ID is broken on NetBSD: the result of clock_gettime()
1531
 * includes the sleeping time, that defeats the purpose of the clock.
1532
 * Also, clock_getres() does not support it.
1533
 * https://github.com/python/cpython/issues/123978
1534
 * https://gnats.netbsd.org/57512
1535
 */
1536
#elif defined(HAVE_CLOCK_GETTIME) && \
1537
      defined(CLOCK_THREAD_CPUTIME_ID) && \
1538
      !defined(__EMSCRIPTEN__) && !defined(__wasi__) && \
1539
      !defined(__NetBSD__)
1540
#define HAVE_THREAD_TIME
1541
1542
#if defined(__APPLE__) && _Py__has_attribute(availability)
1543
static int
1544
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1545
     __attribute__((availability(macos, introduced=10.12)))
1546
     __attribute__((availability(ios, introduced=10.0)))
1547
     __attribute__((availability(tvos, introduced=10.0)))
1548
     __attribute__((availability(watchos, introduced=3.0)));
1549
#endif
1550
1551
static int
1552
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
1553
0
{
1554
0
    struct timespec ts;
1555
0
    const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID;
1556
0
    const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)";
1557
1558
0
    if (clock_gettime(clk_id, &ts)) {
1559
0
        PyErr_SetFromErrno(PyExc_OSError);
1560
0
        return -1;
1561
0
    }
1562
0
    if (info) {
1563
0
        struct timespec res;
1564
0
        info->implementation = function;
1565
0
        info->monotonic = 1;
1566
0
        info->adjustable = 0;
1567
0
        if (clock_getres(clk_id, &res)) {
1568
0
            PyErr_SetFromErrno(PyExc_OSError);
1569
0
            return -1;
1570
0
        }
1571
0
        info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1572
0
    }
1573
1574
0
    if (_PyTime_FromTimespec(tp, &ts) < 0) {
1575
0
        return -1;
1576
0
    }
1577
0
    return 0;
1578
0
}
1579
#endif
1580
1581
#ifdef HAVE_THREAD_TIME
1582
#ifdef __APPLE__
1583
/*
1584
 * The clock_* functions will be removed from the module
1585
 * dict entirely when the C API is not available.
1586
 */
1587
#pragma clang diagnostic push
1588
#pragma clang diagnostic ignored "-Wunguarded-availability"
1589
#endif
1590
1591
static PyObject *
1592
time_thread_time(PyObject *self, PyObject *unused)
1593
0
{
1594
0
    PyTime_t t;
1595
0
    if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
1596
0
        return NULL;
1597
0
    }
1598
0
    return _PyFloat_FromPyTime(t);
1599
0
}
1600
1601
PyDoc_STRVAR(thread_time_doc,
1602
"thread_time() -> float\n\
1603
\n\
1604
Thread time for profiling: sum of the kernel and user-space CPU time.");
1605
1606
static PyObject *
1607
time_thread_time_ns(PyObject *self, PyObject *unused)
1608
0
{
1609
0
    PyTime_t t;
1610
0
    if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
1611
0
        return NULL;
1612
0
    }
1613
0
    return _PyTime_AsLong(t);
1614
0
}
1615
1616
PyDoc_STRVAR(thread_time_ns_doc,
1617
"thread_time() -> int\n\
1618
\n\
1619
Thread time for profiling as nanoseconds:\n\
1620
sum of the kernel and user-space CPU time.");
1621
1622
#ifdef __APPLE__
1623
#pragma clang diagnostic pop
1624
#endif
1625
1626
#endif
1627
1628
1629
static PyObject *
1630
time_get_clock_info(PyObject *module, PyObject *args)
1631
0
{
1632
0
    char *name;
1633
0
    _Py_clock_info_t info;
1634
0
    PyObject *obj = NULL, *dict, *ns;
1635
0
    PyTime_t t;
1636
1637
0
    if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) {
1638
0
        return NULL;
1639
0
    }
1640
1641
#ifdef Py_DEBUG
1642
    info.implementation = NULL;
1643
    info.monotonic = -1;
1644
    info.adjustable = -1;
1645
    info.resolution = -1.0;
1646
#else
1647
0
    info.implementation = "";
1648
0
    info.monotonic = 0;
1649
0
    info.adjustable = 0;
1650
0
    info.resolution = 1.0;
1651
0
#endif
1652
1653
0
    if (strcmp(name, "time") == 0) {
1654
0
        if (_PyTime_TimeWithInfo(&t, &info) < 0) {
1655
0
            return NULL;
1656
0
        }
1657
0
    }
1658
0
    else if (strcmp(name, "monotonic") == 0) {
1659
0
        if (_PyTime_MonotonicWithInfo(&t, &info) < 0) {
1660
0
            return NULL;
1661
0
        }
1662
0
    }
1663
0
    else if (strcmp(name, "perf_counter") == 0) {
1664
0
        if (_PyTime_PerfCounterWithInfo(&t, &info) < 0) {
1665
0
            return NULL;
1666
0
        }
1667
0
    }
1668
0
    else if (strcmp(name, "process_time") == 0) {
1669
0
        time_module_state *state = get_time_state(module);
1670
0
        if (py_process_time(state, &t, &info) < 0) {
1671
0
            return NULL;
1672
0
        }
1673
0
    }
1674
0
#ifdef HAVE_THREAD_TIME
1675
0
    else if (strcmp(name, "thread_time") == 0) {
1676
1677
#ifdef __APPLE__
1678
        if (HAVE_CLOCK_GETTIME_RUNTIME) {
1679
#endif
1680
0
            if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) {
1681
0
                return NULL;
1682
0
            }
1683
#ifdef __APPLE__
1684
        } else {
1685
            PyErr_SetString(PyExc_ValueError, "unknown clock");
1686
            return NULL;
1687
        }
1688
#endif
1689
0
    }
1690
0
#endif
1691
0
    else {
1692
0
        PyErr_SetString(PyExc_ValueError, "unknown clock");
1693
0
        return NULL;
1694
0
    }
1695
1696
0
    dict = PyDict_New();
1697
0
    if (dict == NULL) {
1698
0
        return NULL;
1699
0
    }
1700
1701
0
    assert(info.implementation != NULL);
1702
0
    obj = PyUnicode_FromString(info.implementation);
1703
0
    if (obj == NULL) {
1704
0
        goto error;
1705
0
    }
1706
0
    if (PyDict_SetItemString(dict, "implementation", obj) == -1) {
1707
0
        goto error;
1708
0
    }
1709
0
    Py_CLEAR(obj);
1710
1711
0
    assert(info.monotonic != -1);
1712
0
    obj = PyBool_FromLong(info.monotonic);
1713
0
    if (obj == NULL) {
1714
0
        goto error;
1715
0
    }
1716
0
    if (PyDict_SetItemString(dict, "monotonic", obj) == -1) {
1717
0
        goto error;
1718
0
    }
1719
0
    Py_CLEAR(obj);
1720
1721
0
    assert(info.adjustable != -1);
1722
0
    obj = PyBool_FromLong(info.adjustable);
1723
0
    if (obj == NULL) {
1724
0
        goto error;
1725
0
    }
1726
0
    if (PyDict_SetItemString(dict, "adjustable", obj) == -1) {
1727
0
        goto error;
1728
0
    }
1729
0
    Py_CLEAR(obj);
1730
1731
0
    assert(info.resolution > 0.0);
1732
0
    assert(info.resolution <= 1.0);
1733
0
    obj = PyFloat_FromDouble(info.resolution);
1734
0
    if (obj == NULL) {
1735
0
        goto error;
1736
0
    }
1737
0
    if (PyDict_SetItemString(dict, "resolution", obj) == -1) {
1738
0
        goto error;
1739
0
    }
1740
0
    Py_CLEAR(obj);
1741
1742
0
    ns = _PyNamespace_New(dict);
1743
0
    Py_DECREF(dict);
1744
0
    return ns;
1745
1746
0
error:
1747
0
    Py_DECREF(dict);
1748
0
    Py_XDECREF(obj);
1749
0
    return NULL;
1750
0
}
1751
1752
PyDoc_STRVAR(get_clock_info_doc,
1753
"get_clock_info(name: str) -> dict\n\
1754
\n\
1755
Get information of the specified clock.");
1756
1757
#ifndef HAVE_DECL_TZNAME
1758
static void
1759
get_zone(char *zone, int n, struct tm *p)
1760
32
{
1761
32
#ifdef HAVE_STRUCT_TM_TM_ZONE
1762
32
    strncpy(zone, p->tm_zone ? p->tm_zone : "   ", n);
1763
#else
1764
    tzset();
1765
    strftime(zone, n, "%Z", p);
1766
#endif
1767
32
}
1768
1769
static time_t
1770
get_gmtoff(time_t t, struct tm *p)
1771
32
{
1772
32
#ifdef HAVE_STRUCT_TM_TM_ZONE
1773
32
    return p->tm_gmtoff;
1774
#else
1775
    return timegm(p) - t;
1776
#endif
1777
32
}
1778
#endif // !HAVE_DECL_TZNAME
1779
1780
static int
1781
init_timezone(PyObject *m)
1782
16
{
1783
48
#define ADD_INT(NAME, VALUE) do {                       \
1784
48
    if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) {  \
1785
0
        return -1;                                      \
1786
0
    }                                                   \
1787
48
} while (0)
1788
1789
16
    assert(!PyErr_Occurred());
1790
1791
    /* This code moved from PyInit_time wholesale to allow calling it from
1792
    time_tzset. In the future, some parts of it can be moved back
1793
    (for platforms that don't HAVE_WORKING_TZSET, when we know what they
1794
    are), and the extraneous calls to tzset(3) should be removed.
1795
    I haven't done this yet, as I don't want to change this code as
1796
    little as possible when introducing the time.tzset and time.tzsetwall
1797
    methods. This should simply be a method of doing the following once,
1798
    at the top of this function and removing the call to tzset() from
1799
    time_tzset():
1800
1801
        #ifdef HAVE_TZSET
1802
        tzset()
1803
        #endif
1804
1805
    And I'm lazy and hate C so nyer.
1806
     */
1807
#ifdef HAVE_DECL_TZNAME
1808
    PyObject *otz0, *otz1;
1809
#if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
1810
    tzset();
1811
#endif
1812
    ADD_INT("timezone", _Py_timezone);
1813
#ifdef HAVE_ALTZONE
1814
    ADD_INT("altzone", altzone);
1815
#else
1816
    ADD_INT("altzone", _Py_timezone-3600);
1817
#endif
1818
    ADD_INT("daylight", _Py_daylight);
1819
#ifdef MS_WINDOWS
1820
    TIME_ZONE_INFORMATION tzinfo = {0};
1821
    GetTimeZoneInformation(&tzinfo);
1822
    otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1);
1823
    if (otz0 == NULL) {
1824
        return -1;
1825
    }
1826
    otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1);
1827
    if (otz1 == NULL) {
1828
        Py_DECREF(otz0);
1829
        return -1;
1830
    }
1831
#else
1832
    otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape");
1833
    if (otz0 == NULL) {
1834
        return -1;
1835
    }
1836
    otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape");
1837
    if (otz1 == NULL) {
1838
        Py_DECREF(otz0);
1839
        return -1;
1840
    }
1841
#endif // MS_WINDOWS
1842
    if (PyModule_Add(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)) < 0) {
1843
        return -1;
1844
    }
1845
#else // !HAVE_DECL_TZNAME
1846
16
    static const time_t YEAR = (365 * 24 + 6) * 3600;
1847
16
    time_t t;
1848
16
    struct tm p;
1849
16
    time_t janzone_t, julyzone_t;
1850
16
    char janname[10], julyname[10];
1851
16
    t = (time((time_t *)0) / YEAR) * YEAR;
1852
16
    _PyTime_localtime(t, &p);
1853
16
    get_zone(janname, 9, &p);
1854
16
    janzone_t = -get_gmtoff(t, &p);
1855
16
    janname[9] = '\0';
1856
16
    t += YEAR/2;
1857
16
    _PyTime_localtime(t, &p);
1858
16
    get_zone(julyname, 9, &p);
1859
16
    julyzone_t = -get_gmtoff(t, &p);
1860
16
    julyname[9] = '\0';
1861
1862
    /* Sanity check, don't check for the validity of timezones.
1863
       In practice, it should be more in range -12 hours .. +14 hours. */
1864
112
#define MAX_TIMEZONE (48 * 3600)
1865
16
    if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE
1866
16
        || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE)
1867
0
    {
1868
0
        PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset");
1869
0
        return -1;
1870
0
    }
1871
16
    int janzone = (int)janzone_t;
1872
16
    int julyzone = (int)julyzone_t;
1873
1874
16
    PyObject *tzname_obj;
1875
16
    if (janzone < julyzone) {
1876
        /* DST is reversed in the southern hemisphere */
1877
0
        ADD_INT("timezone", julyzone);
1878
0
        ADD_INT("altzone", janzone);
1879
0
        ADD_INT("daylight", janzone != julyzone);
1880
0
        tzname_obj = Py_BuildValue("(zz)", julyname, janname);
1881
16
    } else {
1882
16
        ADD_INT("timezone", janzone);
1883
16
        ADD_INT("altzone", julyzone);
1884
16
        ADD_INT("daylight", janzone != julyzone);
1885
16
        tzname_obj = Py_BuildValue("(zz)", janname, julyname);
1886
16
    }
1887
16
    if (PyModule_Add(m, "tzname", tzname_obj) < 0) {
1888
0
        return -1;
1889
0
    }
1890
16
#endif // !HAVE_DECL_TZNAME
1891
16
#undef ADD_INT
1892
1893
16
    if (PyErr_Occurred()) {
1894
0
        return -1;
1895
0
    }
1896
16
    return 0;
1897
16
}
1898
1899
1900
// Include Argument Clinic code after defining converters such as
1901
// time_clockid_converter().
1902
#include "clinic/timemodule.c.h"
1903
1904
static PyMethodDef time_methods[] = {
1905
    {"time",            time_time, METH_NOARGS, time_doc},
1906
    {"time_ns",         time_time_ns, METH_NOARGS, time_ns_doc},
1907
#ifdef HAVE_CLOCK_GETTIME
1908
    TIME_CLOCK_GETTIME_METHODDEF
1909
    TIME_CLOCK_GETTIME_NS_METHODDEF
1910
#endif
1911
#ifdef HAVE_CLOCK_SETTIME
1912
    {"clock_settime",   time_clock_settime, METH_VARARGS, clock_settime_doc},
1913
    {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc},
1914
#endif
1915
#ifdef HAVE_CLOCK_GETRES
1916
    {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
1917
#endif
1918
#ifdef HAVE_PTHREAD_GETCPUCLOCKID
1919
    {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc},
1920
#endif
1921
    {"sleep",           time_sleep, METH_O, sleep_doc},
1922
    {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
1923
    {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
1924
    {"asctime",         time_asctime, METH_VARARGS, asctime_doc},
1925
    {"ctime",           time_ctime, METH_VARARGS, ctime_doc},
1926
#ifdef HAVE_MKTIME
1927
    {"mktime",          time_mktime, METH_O, mktime_doc},
1928
#endif
1929
#ifdef HAVE_STRFTIME
1930
    {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
1931
#endif
1932
    {"strptime",        time_strptime, METH_VARARGS, strptime_doc},
1933
#ifdef HAVE_WORKING_TZSET
1934
    {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
1935
#endif
1936
    {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
1937
    {"monotonic_ns",    time_monotonic_ns, METH_NOARGS, monotonic_ns_doc},
1938
    {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
1939
    {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc},
1940
#ifdef HAVE_THREAD_TIME
1941
    {"thread_time",     time_thread_time, METH_NOARGS, thread_time_doc},
1942
    {"thread_time_ns",  time_thread_time_ns, METH_NOARGS, thread_time_ns_doc},
1943
#endif
1944
    {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
1945
    {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc},
1946
    {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},
1947
    {NULL,              NULL}           /* sentinel */
1948
};
1949
1950
1951
PyDoc_STRVAR(module_doc,
1952
"This module provides various functions to manipulate time values.\n\
1953
\n\
1954
There are two standard representations of time.  One is the number\n\
1955
of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\n\
1956
or a floating-point number (to represent fractions of seconds).\n\
1957
The epoch is the point where the time starts, the return value of time.gmtime(0).\n\
1958
It is January 1, 1970, 00:00:00 (UTC) on all platforms.\n\
1959
\n\
1960
The other representation is a tuple of 9 integers giving local time.\n\
1961
The tuple items are:\n\
1962
  year (including century, e.g. 1998)\n\
1963
  month (1-12)\n\
1964
  day (1-31)\n\
1965
  hours (0-23)\n\
1966
  minutes (0-59)\n\
1967
  seconds (0-59)\n\
1968
  weekday (0-6, Monday is 0)\n\
1969
  Julian day (day in the year, 1-366)\n\
1970
  DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
1971
If the DST flag is 0, the time is given in the regular time zone;\n\
1972
if it is 1, the time is given in the DST time zone;\n\
1973
if it is -1, mktime() should guess based on the date and time.\n");
1974
1975
1976
static int
1977
time_exec(PyObject *module)
1978
16
{
1979
16
    time_module_state *state = get_time_state(module);
1980
#if defined(__APPLE__) && defined(HAVE_CLOCK_GETTIME)
1981
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
1982
        /* pass: ^^^ cannot use '!' here */
1983
    } else {
1984
        PyObject* dct = PyModule_GetDict(module);
1985
        if (dct == NULL) {
1986
            return -1;
1987
        }
1988
1989
        if (PyDict_PopString(dct, "clock_gettime", NULL) < 0) {
1990
            return -1;
1991
        }
1992
        if (PyDict_PopString(dct, "clock_gettime_ns", NULL) < 0) {
1993
            return -1;
1994
        }
1995
        if (PyDict_PopString(dct, "clock_settime", NULL) < 0) {
1996
            return -1;
1997
        }
1998
        if (PyDict_PopString(dct, "clock_settime_ns", NULL) < 0) {
1999
            return -1;
2000
        }
2001
        if (PyDict_PopString(dct, "clock_getres", NULL) < 0) {
2002
            return -1;
2003
        }
2004
    }
2005
#endif
2006
#if defined(__APPLE__) && defined(HAVE_THREAD_TIME)
2007
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
2008
        /* pass: ^^^ cannot use '!' here */
2009
    } else {
2010
        PyObject* dct = PyModule_GetDict(module);
2011
2012
        if (PyDict_PopString(dct, "thread_time", NULL) < 0) {
2013
            return -1;
2014
        }
2015
        if (PyDict_PopString(dct, "thread_time_ns", NULL) < 0) {
2016
            return -1;
2017
        }
2018
    }
2019
#endif
2020
    /* Set, or reset, module variables like time.timezone */
2021
16
    if (init_timezone(module) < 0) {
2022
0
        return -1;
2023
0
    }
2024
2025
16
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES)
2026
16
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
2027
2028
16
#ifdef CLOCK_REALTIME
2029
16
        if (PyModule_AddIntMacro(module, CLOCK_REALTIME) < 0) {
2030
0
            return -1;
2031
0
        }
2032
16
#endif
2033
16
#ifdef CLOCK_MONOTONIC
2034
16
        if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC) < 0) {
2035
0
            return -1;
2036
0
        }
2037
16
#endif
2038
16
#ifdef CLOCK_MONOTONIC_RAW
2039
16
        if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW) < 0) {
2040
0
            return -1;
2041
0
        }
2042
16
#endif
2043
#ifdef CLOCK_HIGHRES
2044
        if (PyModule_AddIntMacro(module, CLOCK_HIGHRES) < 0) {
2045
            return -1;
2046
        }
2047
#endif
2048
16
#ifdef CLOCK_PROCESS_CPUTIME_ID
2049
16
        if (PyModule_AddIntMacro(module, CLOCK_PROCESS_CPUTIME_ID) < 0) {
2050
0
            return -1;
2051
0
        }
2052
16
#endif
2053
16
#ifdef CLOCK_THREAD_CPUTIME_ID
2054
16
        if (PyModule_AddIntMacro(module, CLOCK_THREAD_CPUTIME_ID) < 0) {
2055
0
            return -1;
2056
0
        }
2057
16
#endif
2058
#ifdef CLOCK_PROF
2059
        if (PyModule_AddIntMacro(module, CLOCK_PROF) < 0) {
2060
            return -1;
2061
        }
2062
#endif
2063
16
#ifdef CLOCK_BOOTTIME
2064
16
        if (PyModule_AddIntMacro(module, CLOCK_BOOTTIME) < 0) {
2065
0
            return -1;
2066
0
        }
2067
16
#endif
2068
16
#ifdef CLOCK_TAI
2069
16
        if (PyModule_AddIntMacro(module, CLOCK_TAI) < 0) {
2070
0
            return -1;
2071
0
        }
2072
16
#endif
2073
#ifdef CLOCK_UPTIME
2074
        if (PyModule_AddIntMacro(module, CLOCK_UPTIME) < 0) {
2075
            return -1;
2076
        }
2077
#endif
2078
#ifdef CLOCK_UPTIME_RAW
2079
        if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW) < 0) {
2080
            return -1;
2081
        }
2082
#endif
2083
#ifdef CLOCK_MONOTONIC_RAW_APPROX
2084
        if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW_APPROX) < 0) {
2085
            return -1;
2086
        }
2087
#endif
2088
#ifdef CLOCK_UPTIME_RAW_APPROX
2089
        if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW_APPROX) < 0) {
2090
            return -1;
2091
        }
2092
#endif
2093
16
    }
2094
2095
16
#endif  /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */
2096
2097
16
    if (PyModule_AddIntConstant(module, "_STRUCT_TM_ITEMS", 11)) {
2098
0
        return -1;
2099
0
    }
2100
2101
    // struct_time type
2102
16
    state->struct_time_type = PyStructSequence_NewType(&struct_time_type_desc);
2103
16
    if (state->struct_time_type == NULL) {
2104
0
        return -1;
2105
0
    }
2106
16
    if (PyModule_AddType(module, state->struct_time_type)) {
2107
0
        return -1;
2108
0
    }
2109
2110
#if defined(__linux__) && !defined(__GLIBC__)
2111
    struct tm tm;
2112
    const time_t zero = 0;
2113
    if (gmtime_r(&zero, &tm) != NULL)
2114
        utc_string = tm.tm_zone;
2115
#endif
2116
2117
#if defined(MS_WINDOWS)
2118
    if (timer_flags == (DWORD)-1) {
2119
        DWORD test_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
2120
        HANDLE timer = CreateWaitableTimerExW(NULL, NULL, test_flags,
2121
                                              TIMER_ALL_ACCESS);
2122
        if (timer == NULL) {
2123
            // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is not supported.
2124
            timer_flags = 0;
2125
        }
2126
        else {
2127
            // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is supported.
2128
            timer_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
2129
            CloseHandle(timer);
2130
        }
2131
    }
2132
#endif
2133
2134
// gh-115714: Don't use times() on WASI.
2135
16
#if defined(HAVE_TIMES) && !defined(__wasi__)
2136
16
    long ticks_per_second;
2137
16
    if (_Py_GetTicksPerSecond(&ticks_per_second) < 0) {
2138
0
        PyErr_SetString(PyExc_RuntimeError,
2139
0
                        "cannot read ticks_per_second");
2140
0
        return -1;
2141
0
    }
2142
16
    if (_PyTimeFraction_Set(&state->times_base, SEC_TO_NS,
2143
16
                            ticks_per_second) < 0) {
2144
0
        PyErr_Format(PyExc_OverflowError, "ticks_per_second is too large");
2145
0
        return -1;
2146
0
    }
2147
16
#endif
2148
2149
16
#ifdef HAVE_CLOCK
2150
16
    if (_PyTimeFraction_Set(&state->clock_base, SEC_TO_NS,
2151
16
                            CLOCKS_PER_SEC) < 0) {
2152
0
        PyErr_Format(PyExc_OverflowError, "CLOCKS_PER_SEC is too large");
2153
0
        return -1;
2154
0
    }
2155
16
#endif
2156
2157
16
    return 0;
2158
16
}
2159
2160
2161
static int
2162
time_module_traverse(PyObject *module, visitproc visit, void *arg)
2163
4.13k
{
2164
4.13k
    time_module_state *state = get_time_state(module);
2165
4.13k
    Py_VISIT(state->struct_time_type);
2166
4.13k
    return 0;
2167
4.13k
}
2168
2169
2170
static int
2171
time_module_clear(PyObject *module)
2172
0
{
2173
0
    time_module_state *state = get_time_state(module);
2174
0
    Py_CLEAR(state->struct_time_type);
2175
0
    return 0;
2176
0
}
2177
2178
2179
static void
2180
time_module_free(void *module)
2181
0
{
2182
0
    time_module_clear((PyObject *)module);
2183
0
}
2184
2185
2186
static struct PyModuleDef_Slot time_slots[] = {
2187
    {Py_mod_exec, time_exec},
2188
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
2189
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
2190
    {0, NULL}
2191
};
2192
2193
static struct PyModuleDef timemodule = {
2194
    PyModuleDef_HEAD_INIT,
2195
    .m_name = "time",
2196
    .m_doc = module_doc,
2197
    .m_size = sizeof(time_module_state),
2198
    .m_methods = time_methods,
2199
    .m_slots = time_slots,
2200
    .m_traverse = time_module_traverse,
2201
    .m_clear = time_module_clear,
2202
    .m_free = time_module_free,
2203
};
2204
2205
PyMODINIT_FUNC
2206
PyInit_time(void)
2207
16
{
2208
16
    return PyModuleDef_Init(&timemodule);
2209
16
}
2210
2211
2212
// time.sleep() implementation.
2213
// On error, raise an exception and return -1.
2214
// On success, return 0.
2215
static int
2216
pysleep(PyTime_t timeout)
2217
0
{
2218
0
    assert(timeout >= 0);
2219
2220
0
#ifndef MS_WINDOWS
2221
0
#ifdef HAVE_CLOCK_NANOSLEEP
2222
0
    struct timespec timeout_abs;
2223
#elif defined(HAVE_NANOSLEEP)
2224
    struct timespec timeout_ts;
2225
#else
2226
    struct timeval timeout_tv;
2227
#endif
2228
0
    PyTime_t deadline, monotonic;
2229
0
    int err = 0;
2230
2231
0
    if (PyTime_Monotonic(&monotonic) < 0) {
2232
0
        return -1;
2233
0
    }
2234
0
    deadline = monotonic + timeout;
2235
0
#ifdef HAVE_CLOCK_NANOSLEEP
2236
0
    if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) {
2237
0
        return -1;
2238
0
    }
2239
0
#endif
2240
2241
0
    do {
2242
0
#ifdef HAVE_CLOCK_NANOSLEEP
2243
        // use timeout_abs
2244
#elif defined(HAVE_NANOSLEEP)
2245
        if (_PyTime_AsTimespec(timeout, &timeout_ts) < 0) {
2246
            return -1;
2247
        }
2248
#else
2249
        if (_PyTime_AsTimeval(timeout, &timeout_tv, _PyTime_ROUND_CEILING) < 0) {
2250
            return -1;
2251
        }
2252
#endif
2253
2254
0
        int ret;
2255
0
        Py_BEGIN_ALLOW_THREADS
2256
0
#ifdef HAVE_CLOCK_NANOSLEEP
2257
0
        ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL);
2258
0
        err = ret;
2259
#elif defined(HAVE_NANOSLEEP)
2260
        ret = nanosleep(&timeout_ts, NULL);
2261
        err = errno;
2262
#else
2263
        ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout_tv);
2264
        err = errno;
2265
#endif
2266
0
        Py_END_ALLOW_THREADS
2267
2268
0
        if (ret == 0) {
2269
0
            break;
2270
0
        }
2271
2272
0
        if (err != EINTR) {
2273
0
            errno = err;
2274
0
            PyErr_SetFromErrno(PyExc_OSError);
2275
0
            return -1;
2276
0
        }
2277
2278
        /* sleep was interrupted by SIGINT */
2279
0
        if (PyErr_CheckSignals()) {
2280
0
            return -1;
2281
0
        }
2282
2283
#ifndef HAVE_CLOCK_NANOSLEEP
2284
        if (PyTime_Monotonic(&monotonic) < 0) {
2285
            return -1;
2286
        }
2287
        timeout = deadline - monotonic;
2288
        if (timeout < 0) {
2289
            break;
2290
        }
2291
        /* retry with the recomputed delay */
2292
#endif
2293
0
    } while (1);
2294
2295
0
    return 0;
2296
#else  // MS_WINDOWS
2297
    PyTime_t timeout_100ns = _PyTime_As100Nanoseconds(timeout,
2298
                                                       _PyTime_ROUND_CEILING);
2299
2300
    // Maintain Windows Sleep() semantics for time.sleep(0)
2301
    if (timeout_100ns == 0) {
2302
        Py_BEGIN_ALLOW_THREADS
2303
        // A value of zero causes the thread to relinquish the remainder of its
2304
        // time slice to any other thread that is ready to run. If there are no
2305
        // other threads ready to run, the function returns immediately, and
2306
        // the thread continues execution.
2307
        Sleep(0);
2308
        Py_END_ALLOW_THREADS
2309
        return 0;
2310
    }
2311
2312
    LARGE_INTEGER relative_timeout;
2313
    // No need to check for integer overflow, both types are signed
2314
    assert(sizeof(relative_timeout) == sizeof(timeout_100ns));
2315
    // SetWaitableTimer(): a negative due time indicates relative time
2316
    relative_timeout.QuadPart = -timeout_100ns;
2317
2318
    HANDLE timer = CreateWaitableTimerExW(NULL, NULL, timer_flags,
2319
                                          TIMER_ALL_ACCESS);
2320
    if (timer == NULL) {
2321
        PyErr_SetFromWindowsErr(0);
2322
        return -1;
2323
    }
2324
2325
    if (!SetWaitableTimerEx(timer, &relative_timeout,
2326
                            0, // no period; the timer is signaled once
2327
                            NULL, NULL, // no completion routine
2328
                            NULL,  // no wake context; do not resume from suspend
2329
                            0)) // no tolerable delay for timer coalescing
2330
    {
2331
        PyErr_SetFromWindowsErr(0);
2332
        goto error;
2333
    }
2334
2335
    // Only the main thread can be interrupted by SIGINT.
2336
    // Signal handlers are only executed in the main thread.
2337
    if (_PyOS_IsMainThread()) {
2338
        HANDLE sigint_event = _PyOS_SigintEvent();
2339
2340
        while (1) {
2341
            // Check for pending SIGINT signal before resetting the event
2342
            if (PyErr_CheckSignals()) {
2343
                goto error;
2344
            }
2345
            ResetEvent(sigint_event);
2346
2347
            HANDLE events[] = {timer, sigint_event};
2348
            DWORD rc;
2349
2350
            Py_BEGIN_ALLOW_THREADS
2351
            rc = WaitForMultipleObjects(Py_ARRAY_LENGTH(events), events,
2352
                                        // bWaitAll
2353
                                        FALSE,
2354
                                        // No wait timeout
2355
                                        INFINITE);
2356
            Py_END_ALLOW_THREADS
2357
2358
            if (rc == WAIT_FAILED) {
2359
                PyErr_SetFromWindowsErr(0);
2360
                goto error;
2361
            }
2362
2363
            if (rc == WAIT_OBJECT_0) {
2364
                // Timer signaled: we are done
2365
                break;
2366
            }
2367
2368
            assert(rc == (WAIT_OBJECT_0 + 1));
2369
            // The sleep was interrupted by SIGINT: restart sleeping
2370
        }
2371
    }
2372
    else {
2373
        DWORD rc;
2374
2375
        Py_BEGIN_ALLOW_THREADS
2376
        rc = WaitForSingleObject(timer, INFINITE);
2377
        Py_END_ALLOW_THREADS
2378
2379
        if (rc == WAIT_FAILED) {
2380
            PyErr_SetFromWindowsErr(0);
2381
            goto error;
2382
        }
2383
2384
        assert(rc == WAIT_OBJECT_0);
2385
        // Timer signaled: we are done
2386
    }
2387
2388
    CloseHandle(timer);
2389
    return 0;
2390
2391
error:
2392
    CloseHandle(timer);
2393
    return -1;
2394
#endif
2395
0
}