Coverage Report

Created: 2026-03-08 06:40

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