LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - timemodule.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 425 0.0 %
Date: 2012-12-17 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Time module */
       2             : 
       3             : #include "Python.h"
       4             : 
       5             : #include <ctype.h>
       6             : 
       7             : #ifdef HAVE_SYS_TIMES_H
       8             : #include <sys/times.h>
       9             : #endif
      10             : 
      11             : #ifdef HAVE_SYS_TYPES_H
      12             : #include <sys/types.h>
      13             : #endif
      14             : 
      15             : #if defined(HAVE_SYS_RESOURCE_H)
      16             : #include <sys/resource.h>
      17             : #endif
      18             : 
      19             : #ifdef QUICKWIN
      20             : #include <io.h>
      21             : #endif
      22             : 
      23             : #if defined(__WATCOMC__) && !defined(__QNX__)
      24             : #include <i86.h>
      25             : #else
      26             : #ifdef MS_WINDOWS
      27             : #define WIN32_LEAN_AND_MEAN
      28             : #include <windows.h>
      29             : #include "pythread.h"
      30             : 
      31             : #if defined(__BORLANDC__)
      32             : /* These overrides not needed for Win32 */
      33             : #define timezone _timezone
      34             : #define tzname _tzname
      35             : #define daylight _daylight
      36             : #endif /* __BORLANDC__ */
      37             : #endif /* MS_WINDOWS */
      38             : #endif /* !__WATCOMC__ || __QNX__ */
      39             : 
      40             : #if defined(PYOS_OS2)
      41             : #define INCL_DOS
      42             : #define INCL_ERRORS
      43             : #include <os2.h>
      44             : #endif
      45             : 
      46             : #if defined(PYCC_VACPP)
      47             : #include <sys/time.h>
      48             : #endif
      49             : 
      50             : #if defined(__APPLE__)
      51             : #include <mach/mach_time.h>
      52             : #endif
      53             : 
      54             : /* Forward declarations */
      55             : static int floatsleep(double);
      56             : static PyObject* floattime(_Py_clock_info_t *info);
      57             : 
      58             : #ifdef MS_WINDOWS
      59             : static OSVERSIONINFOEX winver;
      60             : #endif
      61             : 
      62             : static PyObject *
      63           0 : time_time(PyObject *self, PyObject *unused)
      64             : {
      65           0 :     return floattime(NULL);
      66             : }
      67             : 
      68             : PyDoc_STRVAR(time_doc,
      69             : "time() -> floating point number\n\
      70             : \n\
      71             : Return the current time in seconds since the Epoch.\n\
      72             : Fractions of a second may be present if the system clock provides them.");
      73             : 
      74             : #if defined(HAVE_CLOCK)
      75             : 
      76             : #ifndef CLOCKS_PER_SEC
      77             : #ifdef CLK_TCK
      78             : #define CLOCKS_PER_SEC CLK_TCK
      79             : #else
      80             : #define CLOCKS_PER_SEC 1000000
      81             : #endif
      82             : #endif
      83             : 
      84             : static PyObject *
      85           0 : floatclock(_Py_clock_info_t *info)
      86             : {
      87             :     clock_t value;
      88           0 :     value = clock();
      89           0 :     if (value == (clock_t)-1) {
      90           0 :         PyErr_SetString(PyExc_RuntimeError,
      91             :                 "the processor time used is not available "
      92             :                 "or its value cannot be represented");
      93           0 :         return NULL;
      94             :     }
      95           0 :     if (info) {
      96           0 :         info->implementation = "clock()";
      97           0 :         info->resolution = 1.0 / (double)CLOCKS_PER_SEC;
      98           0 :         info->monotonic = 1;
      99           0 :         info->adjustable = 0;
     100             :     }
     101           0 :     return PyFloat_FromDouble((double)value / CLOCKS_PER_SEC);
     102             : }
     103             : #endif /* HAVE_CLOCK */
     104             : 
     105             : #if defined(MS_WINDOWS) && !defined(__BORLANDC__)
     106             : #define WIN32_PERF_COUNTER
     107             : /* Win32 has better clock replacement; we have our own version, due to Mark
     108             :    Hammond and Tim Peters */
     109             : static int
     110             : win_perf_counter(_Py_clock_info_t *info, PyObject **result)
     111             : {
     112             :     static LONGLONG cpu_frequency = 0;
     113             :     static LONGLONG ctrStart;
     114             :     LARGE_INTEGER now;
     115             :     double diff;
     116             : 
     117             :     if (cpu_frequency == 0) {
     118             :         LARGE_INTEGER freq;
     119             :         QueryPerformanceCounter(&now);
     120             :         ctrStart = now.QuadPart;
     121             :         if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) {
     122             :             /* Unlikely to happen - this works on all intel
     123             :                machines at least!  Revert to clock() */
     124             :             *result = NULL;
     125             :             return -1;
     126             :         }
     127             :         cpu_frequency = freq.QuadPart;
     128             :     }
     129             :     QueryPerformanceCounter(&now);
     130             :     diff = (double)(now.QuadPart - ctrStart);
     131             :     if (info) {
     132             :         info->implementation = "QueryPerformanceCounter()";
     133             :         info->resolution = 1.0 / (double)cpu_frequency;
     134             :         info->monotonic = 1;
     135             :         info->adjustable = 0;
     136             :     }
     137             :     *result = PyFloat_FromDouble(diff / (double)cpu_frequency);
     138             :     return 0;
     139             : }
     140             : #endif
     141             : 
     142             : #if defined(WIN32_PERF_COUNTER) || defined(HAVE_CLOCK)
     143             : #define PYCLOCK
     144             : static PyObject*
     145           0 : pyclock(_Py_clock_info_t *info)
     146             : {
     147             : #ifdef WIN32_PERF_COUNTER
     148             :     PyObject *res;
     149             :     if (win_perf_counter(info, &res) == 0)
     150             :         return res;
     151             : #endif
     152           0 :     return floatclock(info);
     153             : }
     154             : 
     155             : static PyObject *
     156           0 : time_clock(PyObject *self, PyObject *unused)
     157             : {
     158           0 :     return pyclock(NULL);
     159             : }
     160             : 
     161             : PyDoc_STRVAR(clock_doc,
     162             : "clock() -> floating point number\n\
     163             : \n\
     164             : Return the CPU time or real time since the start of the process or since\n\
     165             : the first call to clock().  This has as much precision as the system\n\
     166             : records.");
     167             : #endif
     168             : 
     169             : #ifdef HAVE_CLOCK_GETTIME
     170             : static PyObject *
     171           0 : time_clock_gettime(PyObject *self, PyObject *args)
     172             : {
     173             :     int ret;
     174             :     int clk_id;
     175             :     struct timespec tp;
     176             : 
     177           0 :     if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id))
     178           0 :         return NULL;
     179             : 
     180           0 :     ret = clock_gettime((clockid_t)clk_id, &tp);
     181           0 :     if (ret != 0) {
     182           0 :         PyErr_SetFromErrno(PyExc_IOError);
     183           0 :         return NULL;
     184             :     }
     185           0 :     return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
     186             : }
     187             : 
     188             : PyDoc_STRVAR(clock_gettime_doc,
     189             : "clock_gettime(clk_id) -> floating point number\n\
     190             : \n\
     191             : Return the time of the specified clock clk_id.");
     192             : 
     193             : static PyObject *
     194           0 : time_clock_settime(PyObject *self, PyObject *args)
     195             : {
     196             :     int clk_id;
     197             :     PyObject *obj;
     198             :     struct timespec tp;
     199             :     int ret;
     200             : 
     201           0 :     if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj))
     202           0 :         return NULL;
     203             : 
     204           0 :     if (_PyTime_ObjectToTimespec(obj, &tp.tv_sec, &tp.tv_nsec) == -1)
     205           0 :         return NULL;
     206             : 
     207           0 :     ret = clock_settime((clockid_t)clk_id, &tp);
     208           0 :     if (ret != 0) {
     209           0 :         PyErr_SetFromErrno(PyExc_IOError);
     210           0 :         return NULL;
     211             :     }
     212           0 :     Py_RETURN_NONE;
     213             : }
     214             : 
     215             : PyDoc_STRVAR(clock_settime_doc,
     216             : "clock_settime(clk_id, time)\n\
     217             : \n\
     218             : Set the time of the specified clock clk_id.");
     219             : 
     220             : static PyObject *
     221           0 : time_clock_getres(PyObject *self, PyObject *args)
     222             : {
     223             :     int ret;
     224             :     int clk_id;
     225             :     struct timespec tp;
     226             : 
     227           0 :     if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id))
     228           0 :         return NULL;
     229             : 
     230           0 :     ret = clock_getres((clockid_t)clk_id, &tp);
     231           0 :     if (ret != 0) {
     232           0 :         PyErr_SetFromErrno(PyExc_IOError);
     233           0 :         return NULL;
     234             :     }
     235             : 
     236           0 :     return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
     237             : }
     238             : 
     239             : PyDoc_STRVAR(clock_getres_doc,
     240             : "clock_getres(clk_id) -> floating point number\n\
     241             : \n\
     242             : Return the resolution (precision) of the specified clock clk_id.");
     243             : #endif   /* HAVE_CLOCK_GETTIME */
     244             : 
     245             : static PyObject *
     246           0 : time_sleep(PyObject *self, PyObject *args)
     247             : {
     248             :     double secs;
     249           0 :     if (!PyArg_ParseTuple(args, "d:sleep", &secs))
     250           0 :         return NULL;
     251           0 :     if (secs < 0) {
     252           0 :         PyErr_SetString(PyExc_ValueError,
     253             :                         "sleep length must be non-negative");
     254           0 :         return NULL;
     255             :     }
     256           0 :     if (floatsleep(secs) != 0)
     257           0 :         return NULL;
     258           0 :     Py_INCREF(Py_None);
     259           0 :     return Py_None;
     260             : }
     261             : 
     262             : PyDoc_STRVAR(sleep_doc,
     263             : "sleep(seconds)\n\
     264             : \n\
     265             : Delay execution for a given number of seconds.  The argument may be\n\
     266             : a floating point number for subsecond precision.");
     267             : 
     268             : static PyStructSequence_Field struct_time_type_fields[] = {
     269             :     {"tm_year", "year, for example, 1993"},
     270             :     {"tm_mon", "month of year, range [1, 12]"},
     271             :     {"tm_mday", "day of month, range [1, 31]"},
     272             :     {"tm_hour", "hours, range [0, 23]"},
     273             :     {"tm_min", "minutes, range [0, 59]"},
     274             :     {"tm_sec", "seconds, range [0, 61])"},
     275             :     {"tm_wday", "day of week, range [0, 6], Monday is 0"},
     276             :     {"tm_yday", "day of year, range [1, 366]"},
     277             :     {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"},
     278             : #ifdef HAVE_STRUCT_TM_TM_ZONE
     279             :     {"tm_zone", "abbreviation of timezone name"},
     280             :     {"tm_gmtoff", "offset from UTC in seconds"},
     281             : #endif /* HAVE_STRUCT_TM_TM_ZONE */
     282             :     {0}
     283             : };
     284             : 
     285             : static PyStructSequence_Desc struct_time_type_desc = {
     286             :     "time.struct_time",
     287             :     "The time value as returned by gmtime(), localtime(), and strptime(), and\n"
     288             :     " accepted by asctime(), mktime() and strftime().  May be considered as a\n"
     289             :     " sequence of 9 integers.\n\n"
     290             :     " Note that several fields' values are not the same as those defined by\n"
     291             :     " the C language standard for struct tm.  For example, the value of the\n"
     292             :     " field tm_year is the actual year, not year - 1900.  See individual\n"
     293             :     " fields' descriptions for details.",
     294             :     struct_time_type_fields,
     295             :     9,
     296             : };
     297             : 
     298             : static int initialized;
     299             : static PyTypeObject StructTimeType;
     300             : 
     301             : 
     302             : static PyObject *
     303           0 : tmtotuple(struct tm *p)
     304             : {
     305           0 :     PyObject *v = PyStructSequence_New(&StructTimeType);
     306           0 :     if (v == NULL)
     307           0 :         return NULL;
     308             : 
     309             : #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
     310             : 
     311           0 :     SET(0, p->tm_year + 1900);
     312           0 :     SET(1, p->tm_mon + 1);         /* Want January == 1 */
     313           0 :     SET(2, p->tm_mday);
     314           0 :     SET(3, p->tm_hour);
     315           0 :     SET(4, p->tm_min);
     316           0 :     SET(5, p->tm_sec);
     317           0 :     SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
     318           0 :     SET(7, p->tm_yday + 1);        /* Want January, 1 == 1 */
     319           0 :     SET(8, p->tm_isdst);
     320             : #ifdef HAVE_STRUCT_TM_TM_ZONE
     321           0 :     PyStructSequence_SET_ITEM(v, 9,
     322             :         PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape"));
     323           0 :     SET(10, p->tm_gmtoff);
     324             : #endif /* HAVE_STRUCT_TM_TM_ZONE */
     325             : #undef SET
     326           0 :     if (PyErr_Occurred()) {
     327           0 :         Py_XDECREF(v);
     328           0 :         return NULL;
     329             :     }
     330             : 
     331           0 :     return v;
     332             : }
     333             : 
     334             : /* Parse arg tuple that can contain an optional float-or-None value;
     335             :    format needs to be "|O:name".
     336             :    Returns non-zero on success (parallels PyArg_ParseTuple).
     337             : */
     338             : static int
     339           0 : parse_time_t_args(PyObject *args, char *format, time_t *pwhen)
     340             : {
     341           0 :     PyObject *ot = NULL;
     342             :     time_t whent;
     343             : 
     344           0 :     if (!PyArg_ParseTuple(args, format, &ot))
     345           0 :         return 0;
     346           0 :     if (ot == NULL || ot == Py_None) {
     347           0 :         whent = time(NULL);
     348             :     }
     349             :     else {
     350           0 :         if (_PyTime_ObjectToTime_t(ot, &whent) == -1)
     351           0 :             return 0;
     352             :     }
     353           0 :     *pwhen = whent;
     354           0 :     return 1;
     355             : }
     356             : 
     357             : static PyObject *
     358           0 : time_gmtime(PyObject *self, PyObject *args)
     359             : {
     360             :     time_t when;
     361             :     struct tm buf, *local;
     362             : 
     363           0 :     if (!parse_time_t_args(args, "|O:gmtime", &when))
     364           0 :         return NULL;
     365             : 
     366           0 :     errno = 0;
     367           0 :     local = gmtime(&when);
     368           0 :     if (local == NULL) {
     369             : #ifdef EINVAL
     370           0 :         if (errno == 0)
     371           0 :             errno = EINVAL;
     372             : #endif
     373           0 :         return PyErr_SetFromErrno(PyExc_OSError);
     374             :     }
     375           0 :     buf = *local;
     376           0 :     return tmtotuple(&buf);
     377             : }
     378             : 
     379             : PyDoc_STRVAR(gmtime_doc,
     380             : "gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\
     381             :                        tm_sec, tm_wday, tm_yday, tm_isdst)\n\
     382             : \n\
     383             : Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
     384             : GMT).  When 'seconds' is not passed in, convert the current time instead.\n\
     385             : \n\
     386             : If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
     387             : attributes only.");
     388             : 
     389             : static int
     390           0 : pylocaltime(time_t *timep, struct tm *result)
     391             : {
     392             :     struct tm *local;
     393             : 
     394             :     assert (timep != NULL);
     395           0 :     local = localtime(timep);
     396           0 :     if (local == NULL) {
     397             :         /* unconvertible time */
     398             : #ifdef EINVAL
     399           0 :         if (errno == 0)
     400           0 :             errno = EINVAL;
     401             : #endif
     402           0 :         PyErr_SetFromErrno(PyExc_OSError);
     403           0 :         return -1;
     404             :     }
     405           0 :     *result = *local;
     406           0 :     return 0;
     407             : }
     408             : 
     409             : static PyObject *
     410           0 : time_localtime(PyObject *self, PyObject *args)
     411             : {
     412             :     time_t when;
     413             :     struct tm buf;
     414             : 
     415           0 :     if (!parse_time_t_args(args, "|O:localtime", &when))
     416           0 :         return NULL;
     417           0 :     if (pylocaltime(&when, &buf) == -1)
     418           0 :         return NULL;
     419           0 :     return tmtotuple(&buf);
     420             : }
     421             : 
     422             : PyDoc_STRVAR(localtime_doc,
     423             : "localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
     424             :                           tm_sec,tm_wday,tm_yday,tm_isdst)\n\
     425             : \n\
     426             : Convert seconds since the Epoch to a time tuple expressing local time.\n\
     427             : When 'seconds' is not passed in, convert the current time instead.");
     428             : 
     429             : /* Convert 9-item tuple to tm structure.  Return 1 on success, set
     430             :  * an exception and return 0 on error.
     431             :  */
     432             : static int
     433           0 : gettmarg(PyObject *args, struct tm *p)
     434             : {
     435             :     int y;
     436             : 
     437           0 :     memset((void *) p, '\0', sizeof(struct tm));
     438             : 
     439           0 :     if (!PyTuple_Check(args)) {
     440           0 :         PyErr_SetString(PyExc_TypeError,
     441             :                         "Tuple or struct_time argument required");
     442           0 :         return 0;
     443             :     }
     444             : 
     445           0 :     if (!PyArg_ParseTuple(args, "iiiiiiiii",
     446             :                           &y, &p->tm_mon, &p->tm_mday,
     447             :                           &p->tm_hour, &p->tm_min, &p->tm_sec,
     448             :                           &p->tm_wday, &p->tm_yday, &p->tm_isdst))
     449           0 :         return 0;
     450           0 :     p->tm_year = y - 1900;
     451           0 :     p->tm_mon--;
     452           0 :     p->tm_wday = (p->tm_wday + 1) % 7;
     453           0 :     p->tm_yday--;
     454             : #ifdef HAVE_STRUCT_TM_TM_ZONE
     455           0 :     if (Py_TYPE(args) == &StructTimeType) {
     456             :         PyObject *item;
     457           0 :         item = PyTuple_GET_ITEM(args, 9);
     458           0 :         p->tm_zone = item == Py_None ? NULL : _PyUnicode_AsString(item);
     459           0 :         item = PyTuple_GET_ITEM(args, 10);
     460           0 :         p->tm_gmtoff = item == Py_None ? 0 : PyLong_AsLong(item);
     461           0 :         if (PyErr_Occurred())
     462           0 :             return 0;
     463             :     }
     464             : #endif /* HAVE_STRUCT_TM_TM_ZONE */
     465           0 :     return 1;
     466             : }
     467             : 
     468             : /* Check values of the struct tm fields before it is passed to strftime() and
     469             :  * asctime().  Return 1 if all values are valid, otherwise set an exception
     470             :  * and returns 0.
     471             :  */
     472             : static int
     473           0 : checktm(struct tm* buf)
     474             : {
     475             :     /* Checks added to make sure strftime() and asctime() does not crash Python by
     476             :        indexing blindly into some array for a textual representation
     477             :        by some bad index (fixes bug #897625 and #6608).
     478             : 
     479             :        Also support values of zero from Python code for arguments in which
     480             :        that is out of range by forcing that value to the lowest value that
     481             :        is valid (fixed bug #1520914).
     482             : 
     483             :        Valid ranges based on what is allowed in struct tm:
     484             : 
     485             :        - tm_year: [0, max(int)] (1)
     486             :        - tm_mon: [0, 11] (2)
     487             :        - tm_mday: [1, 31]
     488             :        - tm_hour: [0, 23]
     489             :        - tm_min: [0, 59]
     490             :        - tm_sec: [0, 60]
     491             :        - tm_wday: [0, 6] (1)
     492             :        - tm_yday: [0, 365] (2)
     493             :        - tm_isdst: [-max(int), max(int)]
     494             : 
     495             :        (1) gettmarg() handles bounds-checking.
     496             :        (2) Python's acceptable range is one greater than the range in C,
     497             :        thus need to check against automatic decrement by gettmarg().
     498             :     */
     499           0 :     if (buf->tm_mon == -1)
     500           0 :         buf->tm_mon = 0;
     501           0 :     else if (buf->tm_mon < 0 || buf->tm_mon > 11) {
     502           0 :         PyErr_SetString(PyExc_ValueError, "month out of range");
     503           0 :         return 0;
     504             :     }
     505           0 :     if (buf->tm_mday == 0)
     506           0 :         buf->tm_mday = 1;
     507           0 :     else if (buf->tm_mday < 0 || buf->tm_mday > 31) {
     508           0 :         PyErr_SetString(PyExc_ValueError, "day of month out of range");
     509           0 :         return 0;
     510             :     }
     511           0 :     if (buf->tm_hour < 0 || buf->tm_hour > 23) {
     512           0 :         PyErr_SetString(PyExc_ValueError, "hour out of range");
     513           0 :         return 0;
     514             :     }
     515           0 :     if (buf->tm_min < 0 || buf->tm_min > 59) {
     516           0 :         PyErr_SetString(PyExc_ValueError, "minute out of range");
     517           0 :         return 0;
     518             :     }
     519           0 :     if (buf->tm_sec < 0 || buf->tm_sec > 61) {
     520           0 :         PyErr_SetString(PyExc_ValueError, "seconds out of range");
     521           0 :         return 0;
     522             :     }
     523             :     /* tm_wday does not need checking of its upper-bound since taking
     524             :     ``% 7`` in gettmarg() automatically restricts the range. */
     525           0 :     if (buf->tm_wday < 0) {
     526           0 :         PyErr_SetString(PyExc_ValueError, "day of week out of range");
     527           0 :         return 0;
     528             :     }
     529           0 :     if (buf->tm_yday == -1)
     530           0 :         buf->tm_yday = 0;
     531           0 :     else if (buf->tm_yday < 0 || buf->tm_yday > 365) {
     532           0 :         PyErr_SetString(PyExc_ValueError, "day of year out of range");
     533           0 :         return 0;
     534             :     }
     535           0 :     return 1;
     536             : }
     537             : 
     538             : #ifdef MS_WINDOWS
     539             :    /* wcsftime() doesn't format correctly time zones, see issue #10653 */
     540             : #  undef HAVE_WCSFTIME
     541             : #endif
     542             : 
     543             : #ifdef HAVE_STRFTIME
     544             : #ifdef HAVE_WCSFTIME
     545             : #define time_char wchar_t
     546             : #define format_time wcsftime
     547             : #define time_strlen wcslen
     548             : #else
     549             : #define time_char char
     550             : #define format_time strftime
     551             : #define time_strlen strlen
     552             : #endif
     553             : 
     554             : static PyObject *
     555           0 : time_strftime(PyObject *self, PyObject *args)
     556             : {
     557           0 :     PyObject *tup = NULL;
     558             :     struct tm buf;
     559             :     const time_char *fmt;
     560             : #ifdef HAVE_WCSFTIME
     561             :     wchar_t *format;
     562             : #else
     563             :     PyObject *format;
     564             : #endif
     565             :     PyObject *format_arg;
     566             :     size_t fmtlen, buflen;
     567           0 :     time_char *outbuf = NULL;
     568             :     size_t i;
     569           0 :     PyObject *ret = NULL;
     570             : 
     571           0 :     memset((void *) &buf, '\0', sizeof(buf));
     572             : 
     573             :     /* Will always expect a unicode string to be passed as format.
     574             :        Given that there's no str type anymore in py3k this seems safe.
     575             :     */
     576           0 :     if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup))
     577           0 :         return NULL;
     578             : 
     579           0 :     if (tup == NULL) {
     580           0 :         time_t tt = time(NULL);
     581           0 :         if (pylocaltime(&tt, &buf) == -1)
     582           0 :             return NULL;
     583             :     }
     584           0 :     else if (!gettmarg(tup, &buf) || !checktm(&buf))
     585           0 :         return NULL;
     586             : 
     587             : #if defined(_MSC_VER) || defined(sun)
     588             :     if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
     589             :         PyErr_SetString(PyExc_ValueError,
     590             :                         "strftime() requires year in [1; 9999]");
     591             :         return NULL;
     592             :     }
     593             : #endif
     594             : 
     595             :     /* Normalize tm_isdst just in case someone foolishly implements %Z
     596             :        based on the assumption that tm_isdst falls within the range of
     597             :        [-1, 1] */
     598           0 :     if (buf.tm_isdst < -1)
     599           0 :         buf.tm_isdst = -1;
     600           0 :     else if (buf.tm_isdst > 1)
     601           0 :         buf.tm_isdst = 1;
     602             : 
     603             : #ifdef HAVE_WCSFTIME
     604           0 :     format = PyUnicode_AsWideCharString(format_arg, NULL);
     605           0 :     if (format == NULL)
     606           0 :         return NULL;
     607           0 :     fmt = format;
     608             : #else
     609             :     /* Convert the unicode string to an ascii one */
     610             :     format = PyUnicode_EncodeLocale(format_arg, "surrogateescape");
     611             :     if (format == NULL)
     612             :         return NULL;
     613             :     fmt = PyBytes_AS_STRING(format);
     614             : #endif
     615             : 
     616             : #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME)
     617             :     /* check that the format string contains only valid directives */
     618             :     for(outbuf = strchr(fmt, '%');
     619             :         outbuf != NULL;
     620             :         outbuf = strchr(outbuf+2, '%'))
     621             :     {
     622             :         if (outbuf[1]=='#')
     623             :             ++outbuf; /* not documented by python, */
     624             :         if (outbuf[1]=='\0' ||
     625             :             !strchr("aAbBcdHIjmMpSUwWxXyYzZ%", outbuf[1]))
     626             :         {
     627             :             PyErr_SetString(PyExc_ValueError, "Invalid format string");
     628             :             Py_DECREF(format);
     629             :             return NULL;
     630             :         }
     631             :     }
     632             : #endif
     633             : 
     634           0 :     fmtlen = time_strlen(fmt);
     635             : 
     636             :     /* I hate these functions that presume you know how big the output
     637             :      * will be ahead of time...
     638             :      */
     639           0 :     for (i = 1024; ; i += i) {
     640             : #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
     641             :         int err;
     642             : #endif
     643           0 :         outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
     644           0 :         if (outbuf == NULL) {
     645           0 :             PyErr_NoMemory();
     646           0 :             break;
     647             :         }
     648           0 :         buflen = format_time(outbuf, i, fmt, &buf);
     649             : #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
     650             :         err = errno;
     651             : #endif
     652           0 :         if (buflen > 0 || i >= 256 * fmtlen) {
     653             :             /* If the buffer is 256 times as long as the format,
     654             :                it's probably not failing for lack of room!
     655             :                More likely, the format yields an empty result,
     656             :                e.g. an empty format, or %Z when the timezone
     657             :                is unknown. */
     658             : #ifdef HAVE_WCSFTIME
     659           0 :             ret = PyUnicode_FromWideChar(outbuf, buflen);
     660             : #else
     661             :             ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen,
     662             :                                                 "surrogateescape");
     663             : #endif
     664           0 :             PyMem_Free(outbuf);
     665           0 :             break;
     666             :         }
     667           0 :         PyMem_Free(outbuf);
     668             : #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
     669             :         /* VisualStudio .NET 2005 does this properly */
     670             :         if (buflen == 0 && err == EINVAL) {
     671             :             PyErr_SetString(PyExc_ValueError, "Invalid format string");
     672             :             break;
     673             :         }
     674             : #endif
     675           0 :     }
     676             : #ifdef HAVE_WCSFTIME
     677           0 :     PyMem_Free(format);
     678             : #else
     679             :     Py_DECREF(format);
     680             : #endif
     681           0 :     return ret;
     682             : }
     683             : 
     684             : #undef time_char
     685             : #undef format_time
     686             : 
     687             : PyDoc_STRVAR(strftime_doc,
     688             : "strftime(format[, tuple]) -> string\n\
     689             : \n\
     690             : Convert a time tuple to a string according to a format specification.\n\
     691             : See the library reference manual for formatting codes. When the time tuple\n\
     692             : is not present, current time as returned by localtime() is used.");
     693             : #endif /* HAVE_STRFTIME */
     694             : 
     695             : static PyObject *
     696           0 : time_strptime(PyObject *self, PyObject *args)
     697             : {
     698           0 :     PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime");
     699             :     PyObject *strptime_result;
     700             :     _Py_IDENTIFIER(_strptime_time);
     701             : 
     702           0 :     if (!strptime_module)
     703           0 :         return NULL;
     704           0 :     strptime_result = _PyObject_CallMethodId(strptime_module,
     705             :                                              &PyId__strptime_time, "O", args);
     706           0 :     Py_DECREF(strptime_module);
     707           0 :     return strptime_result;
     708             : }
     709             : 
     710             : 
     711             : PyDoc_STRVAR(strptime_doc,
     712             : "strptime(string, format) -> struct_time\n\
     713             : \n\
     714             : Parse a string to a time tuple according to a format specification.\n\
     715             : See the library reference manual for formatting codes (same as strftime()).");
     716             : 
     717             : static PyObject *
     718           0 : _asctime(struct tm *timeptr)
     719             : {
     720             :     /* Inspired by Open Group reference implementation available at
     721             :      * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */
     722             :     static char wday_name[7][4] = {
     723             :         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
     724             :     };
     725             :     static char mon_name[12][4] = {
     726             :         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
     727             :         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
     728             :     };
     729           0 :     return PyUnicode_FromFormat(
     730             :         "%s %s%3d %.2d:%.2d:%.2d %d",
     731           0 :         wday_name[timeptr->tm_wday],
     732           0 :         mon_name[timeptr->tm_mon],
     733             :         timeptr->tm_mday, timeptr->tm_hour,
     734             :         timeptr->tm_min, timeptr->tm_sec,
     735           0 :         1900 + timeptr->tm_year);
     736             : }
     737             : 
     738             : static PyObject *
     739           0 : time_asctime(PyObject *self, PyObject *args)
     740             : {
     741           0 :     PyObject *tup = NULL;
     742             :     struct tm buf;
     743             : 
     744           0 :     if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
     745           0 :         return NULL;
     746           0 :     if (tup == NULL) {
     747           0 :         time_t tt = time(NULL);
     748           0 :         if (pylocaltime(&tt, &buf) == -1)
     749           0 :             return NULL;
     750             : 
     751           0 :     } else if (!gettmarg(tup, &buf) || !checktm(&buf))
     752           0 :         return NULL;
     753           0 :     return _asctime(&buf);
     754             : }
     755             : 
     756             : PyDoc_STRVAR(asctime_doc,
     757             : "asctime([tuple]) -> string\n\
     758             : \n\
     759             : Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
     760             : When the time tuple is not present, current time as returned by localtime()\n\
     761             : is used.");
     762             : 
     763             : static PyObject *
     764           0 : time_ctime(PyObject *self, PyObject *args)
     765             : {
     766             :     time_t tt;
     767             :     struct tm buf;
     768           0 :     if (!parse_time_t_args(args, "|O:ctime", &tt))
     769           0 :         return NULL;
     770           0 :     if (pylocaltime(&tt, &buf) == -1)
     771           0 :         return NULL;
     772           0 :     return _asctime(&buf);
     773             : }
     774             : 
     775             : PyDoc_STRVAR(ctime_doc,
     776             : "ctime(seconds) -> string\n\
     777             : \n\
     778             : Convert a time in seconds since the Epoch to a string in local time.\n\
     779             : This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
     780             : not present, current time as returned by localtime() is used.");
     781             : 
     782             : #ifdef HAVE_MKTIME
     783             : static PyObject *
     784           0 : time_mktime(PyObject *self, PyObject *tup)
     785             : {
     786             :     struct tm buf;
     787             :     time_t tt;
     788           0 :     if (!gettmarg(tup, &buf))
     789           0 :         return NULL;
     790           0 :     buf.tm_wday = -1;  /* sentinel; original value ignored */
     791           0 :     tt = mktime(&buf);
     792             :     /* Return value of -1 does not necessarily mean an error, but tm_wday
     793             :      * cannot remain set to -1 if mktime succeeded. */
     794           0 :     if (tt == (time_t)(-1) && buf.tm_wday == -1) {
     795           0 :         PyErr_SetString(PyExc_OverflowError,
     796             :                         "mktime argument out of range");
     797           0 :         return NULL;
     798             :     }
     799           0 :     return PyFloat_FromDouble((double)tt);
     800             : }
     801             : 
     802             : PyDoc_STRVAR(mktime_doc,
     803             : "mktime(tuple) -> floating point number\n\
     804             : \n\
     805             : Convert a time tuple in local time to seconds since the Epoch.\n\
     806             : Note that mktime(gmtime(0)) will not generally return zero for most\n\
     807             : time zones; instead the returned value will either be equal to that\n\
     808             : of the timezone or altzone attributes on the time module.");
     809             : #endif /* HAVE_MKTIME */
     810             : 
     811             : #ifdef HAVE_WORKING_TZSET
     812             : static void PyInit_timezone(PyObject *module);
     813             : 
     814             : static PyObject *
     815           0 : time_tzset(PyObject *self, PyObject *unused)
     816             : {
     817             :     PyObject* m;
     818             : 
     819           0 :     m = PyImport_ImportModuleNoBlock("time");
     820           0 :     if (m == NULL) {
     821           0 :         return NULL;
     822             :     }
     823             : 
     824           0 :     tzset();
     825             : 
     826             :     /* Reset timezone, altzone, daylight and tzname */
     827           0 :     PyInit_timezone(m);
     828           0 :     Py_DECREF(m);
     829             : 
     830           0 :     Py_INCREF(Py_None);
     831           0 :     return Py_None;
     832             : }
     833             : 
     834             : PyDoc_STRVAR(tzset_doc,
     835             : "tzset()\n\
     836             : \n\
     837             : Initialize, or reinitialize, the local timezone to the value stored in\n\
     838             : os.environ['TZ']. The TZ environment variable should be specified in\n\
     839             : standard Unix timezone format as documented in the tzset man page\n\
     840             : (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
     841             : fall back to UTC. If the TZ environment variable is not set, the local\n\
     842             : timezone is set to the systems best guess of wallclock time.\n\
     843             : Changing the TZ environment variable without calling tzset *may* change\n\
     844             : the local timezone used by methods such as localtime, but this behaviour\n\
     845             : should not be relied on.");
     846             : #endif /* HAVE_WORKING_TZSET */
     847             : 
     848             : #if defined(MS_WINDOWS) || defined(__APPLE__) \
     849             :     || (defined(HAVE_CLOCK_GETTIME) \
     850             :         && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC)))
     851             : #define PYMONOTONIC
     852             : #endif
     853             : 
     854             : #ifdef PYMONOTONIC
     855             : static PyObject*
     856           0 : pymonotonic(_Py_clock_info_t *info)
     857             : {
     858             : #if defined(MS_WINDOWS)
     859             :     static ULONGLONG (*GetTickCount64) (void) = NULL;
     860             :     static ULONGLONG (CALLBACK *Py_GetTickCount64)(void);
     861             :     static int has_getickcount64 = -1;
     862             :     double result;
     863             : 
     864             :     if (has_getickcount64 == -1) {
     865             :         /* GetTickCount64() was added to Windows Vista */
     866             :         if (winver.dwMajorVersion >= 6) {
     867             :             HINSTANCE hKernel32;
     868             :             hKernel32 = GetModuleHandleW(L"KERNEL32");
     869             :             *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32,
     870             :                                                            "GetTickCount64");
     871             :             has_getickcount64 = (Py_GetTickCount64 != NULL);
     872             :         }
     873             :         else
     874             :             has_getickcount64 = 0;
     875             :     }
     876             : 
     877             :     if (has_getickcount64) {
     878             :         ULONGLONG ticks;
     879             :         ticks = Py_GetTickCount64();
     880             :         result = (double)ticks * 1e-3;
     881             :     }
     882             :     else {
     883             :         static DWORD last_ticks = 0;
     884             :         static DWORD n_overflow = 0;
     885             :         DWORD ticks;
     886             : 
     887             :         ticks = GetTickCount();
     888             :         if (ticks < last_ticks)
     889             :             n_overflow++;
     890             :         last_ticks = ticks;
     891             : 
     892             :         result = ldexp(n_overflow, 32);
     893             :         result += ticks;
     894             :         result *= 1e-3;
     895             :     }
     896             : 
     897             :     if (info) {
     898             :         DWORD timeAdjustment, timeIncrement;
     899             :         BOOL isTimeAdjustmentDisabled, ok;
     900             :         if (has_getickcount64)
     901             :             info->implementation = "GetTickCount64()";
     902             :         else
     903             :             info->implementation = "GetTickCount()";
     904             :         info->monotonic = 1;
     905             :         ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
     906             :                                      &isTimeAdjustmentDisabled);
     907             :         if (!ok) {
     908             :             PyErr_SetFromWindowsErr(0);
     909             :             return NULL;
     910             :         }
     911             :         info->resolution = timeIncrement * 1e-7;
     912             :         info->adjustable = 0;
     913             :     }
     914             :     return PyFloat_FromDouble(result);
     915             : 
     916             : #elif defined(__APPLE__)
     917             :     static mach_timebase_info_data_t timebase;
     918             :     uint64_t time;
     919             :     double secs;
     920             : 
     921             :     if (timebase.denom == 0) {
     922             :         /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
     923             :            fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
     924             :         (void)mach_timebase_info(&timebase);
     925             :     }
     926             : 
     927             :     time = mach_absolute_time();
     928             :     secs = (double)time * timebase.numer / timebase.denom * 1e-9;
     929             :     if (info) {
     930             :         info->implementation = "mach_absolute_time()";
     931             :         info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
     932             :         info->monotonic = 1;
     933             :         info->adjustable = 0;
     934             :     }
     935             :     return PyFloat_FromDouble(secs);
     936             : 
     937             : #elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC))
     938             :     struct timespec tp;
     939             : #ifdef CLOCK_HIGHRES
     940             :     const clockid_t clk_id = CLOCK_HIGHRES;
     941             :     const char *function = "clock_gettime(CLOCK_HIGHRES)";
     942             : #else
     943           0 :     const clockid_t clk_id = CLOCK_MONOTONIC;
     944           0 :     const char *function = "clock_gettime(CLOCK_MONOTONIC)";
     945             : #endif
     946             : 
     947           0 :     if (clock_gettime(clk_id, &tp) != 0) {
     948           0 :         PyErr_SetFromErrno(PyExc_OSError);
     949           0 :         return NULL;
     950             :     }
     951             : 
     952           0 :     if (info) {
     953             :         struct timespec res;
     954           0 :         info->monotonic = 1;
     955           0 :         info->implementation = function;
     956           0 :         info->adjustable = 0;
     957           0 :         if (clock_getres(clk_id, &res) == 0)
     958           0 :             info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
     959             :         else
     960           0 :             info->resolution = 1e-9;
     961             :     }
     962           0 :     return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
     963             : #endif
     964             : }
     965             : 
     966             : static PyObject *
     967           0 : time_monotonic(PyObject *self, PyObject *unused)
     968             : {
     969           0 :     return pymonotonic(NULL);
     970             : }
     971             : 
     972             : PyDoc_STRVAR(monotonic_doc,
     973             : "monotonic() -> float\n\
     974             : \n\
     975             : Monotonic clock, cannot go backward.");
     976             : #endif   /* PYMONOTONIC */
     977             : 
     978             : static PyObject*
     979           0 : perf_counter(_Py_clock_info_t *info)
     980             : {
     981             : #if defined(WIN32_PERF_COUNTER) || defined(PYMONOTONIC)
     982             :     PyObject *res;
     983             : #endif
     984             : #if defined(WIN32_PERF_COUNTER)
     985             :     static int use_perf_counter = 1;
     986             : #endif
     987             : #ifdef PYMONOTONIC
     988             :     static int use_monotonic = 1;
     989             : #endif
     990             : 
     991             : #ifdef WIN32_PERF_COUNTER
     992             :     if (use_perf_counter) {
     993             :         if (win_perf_counter(info, &res) == 0)
     994             :             return res;
     995             :         use_perf_counter = 0;
     996             :     }
     997             : #endif
     998             : 
     999             : #ifdef PYMONOTONIC
    1000           0 :     if (use_monotonic) {
    1001           0 :         res = pymonotonic(info);
    1002           0 :         if (res != NULL)
    1003           0 :             return res;
    1004           0 :         use_monotonic = 0;
    1005           0 :         PyErr_Clear();
    1006             :     }
    1007             : #endif
    1008             : 
    1009           0 :     return floattime(info);
    1010             : }
    1011             : 
    1012             : static PyObject *
    1013           0 : time_perf_counter(PyObject *self, PyObject *unused)
    1014             : {
    1015           0 :     return perf_counter(NULL);
    1016             : }
    1017             : 
    1018             : PyDoc_STRVAR(perf_counter_doc,
    1019             : "perf_counter() -> float\n\
    1020             : \n\
    1021             : Performance counter for benchmarking.");
    1022             : 
    1023             : static PyObject*
    1024           0 : py_process_time(_Py_clock_info_t *info)
    1025             : {
    1026             : #if defined(MS_WINDOWS)
    1027             :     HANDLE process;
    1028             :     FILETIME creation_time, exit_time, kernel_time, user_time;
    1029             :     ULARGE_INTEGER large;
    1030             :     double total;
    1031             :     BOOL ok;
    1032             : 
    1033             :     process = GetCurrentProcess();
    1034             :     ok = GetProcessTimes(process, &creation_time, &exit_time, &kernel_time, &user_time);
    1035             :     if (!ok)
    1036             :         return PyErr_SetFromWindowsErr(0);
    1037             : 
    1038             :     large.u.LowPart = kernel_time.dwLowDateTime;
    1039             :     large.u.HighPart = kernel_time.dwHighDateTime;
    1040             :     total = (double)large.QuadPart;
    1041             :     large.u.LowPart = user_time.dwLowDateTime;
    1042             :     large.u.HighPart = user_time.dwHighDateTime;
    1043             :     total += (double)large.QuadPart;
    1044             :     if (info) {
    1045             :         info->implementation = "GetProcessTimes()";
    1046             :         info->resolution = 1e-7;
    1047             :         info->monotonic = 1;
    1048             :         info->adjustable = 0;
    1049             :     }
    1050             :     return PyFloat_FromDouble(total * 1e-7);
    1051             : #else
    1052             : 
    1053             : #if defined(HAVE_SYS_RESOURCE_H)
    1054             :     struct rusage ru;
    1055             : #endif
    1056             : #ifdef HAVE_TIMES
    1057             :     struct tms t;
    1058             :     static long ticks_per_second = -1;
    1059             : #endif
    1060             : 
    1061             : #if defined(HAVE_CLOCK_GETTIME) \
    1062             :     && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF))
    1063             :     struct timespec tp;
    1064             : #ifdef CLOCK_PROF
    1065             :     const clockid_t clk_id = CLOCK_PROF;
    1066             :     const char *function = "clock_gettime(CLOCK_PROF)";
    1067             : #else
    1068           0 :     const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
    1069           0 :     const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
    1070             : #endif
    1071             : 
    1072           0 :     if (clock_gettime(clk_id, &tp) == 0) {
    1073           0 :         if (info) {
    1074             :             struct timespec res;
    1075           0 :             info->implementation = function;
    1076           0 :             info->monotonic = 1;
    1077           0 :             info->adjustable = 0;
    1078           0 :             if (clock_getres(clk_id, &res) == 0)
    1079           0 :                 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
    1080             :             else
    1081           0 :                 info->resolution = 1e-9;
    1082             :         }
    1083           0 :         return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
    1084             :     }
    1085             : #endif
    1086             : 
    1087             : #if defined(HAVE_SYS_RESOURCE_H)
    1088           0 :     if (getrusage(RUSAGE_SELF, &ru) == 0) {
    1089             :         double total;
    1090           0 :         total = ru.ru_utime.tv_sec + ru.ru_utime.tv_usec * 1e-6;
    1091           0 :         total += ru.ru_stime.tv_sec + ru.ru_stime.tv_usec * 1e-6;
    1092           0 :         if (info) {
    1093           0 :             info->implementation = "getrusage(RUSAGE_SELF)";
    1094           0 :             info->monotonic = 1;
    1095           0 :             info->adjustable = 0;
    1096           0 :             info->resolution = 1e-6;
    1097             :         }
    1098           0 :         return PyFloat_FromDouble(total);
    1099             :     }
    1100             : #endif
    1101             : 
    1102             : #ifdef HAVE_TIMES
    1103           0 :     if (times(&t) != (clock_t)-1) {
    1104             :         double total;
    1105             : 
    1106           0 :         if (ticks_per_second == -1) {
    1107             : #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
    1108           0 :             ticks_per_second = sysconf(_SC_CLK_TCK);
    1109           0 :             if (ticks_per_second < 1)
    1110           0 :                 ticks_per_second = -1;
    1111             : #elif defined(HZ)
    1112             :             ticks_per_second = HZ;
    1113             : #else
    1114             :             ticks_per_second = 60; /* magic fallback value; may be bogus */
    1115             : #endif
    1116             :         }
    1117             : 
    1118           0 :         if (ticks_per_second != -1) {
    1119           0 :             total = (double)t.tms_utime / ticks_per_second;
    1120           0 :             total += (double)t.tms_stime / ticks_per_second;
    1121           0 :             if (info) {
    1122           0 :                 info->implementation = "times()";
    1123           0 :                 info->monotonic = 1;
    1124           0 :                 info->adjustable = 0;
    1125           0 :                 info->resolution = 1.0 / ticks_per_second;
    1126             :             }
    1127           0 :             return PyFloat_FromDouble(total);
    1128             :         }
    1129             :     }
    1130             : #endif
    1131             : 
    1132           0 :     return floatclock(info);
    1133             : #endif
    1134             : }
    1135             : 
    1136             : static PyObject *
    1137           0 : time_process_time(PyObject *self, PyObject *unused)
    1138             : {
    1139           0 :     return py_process_time(NULL);
    1140             : }
    1141             : 
    1142             : PyDoc_STRVAR(process_time_doc,
    1143             : "process_time() -> float\n\
    1144             : \n\
    1145             : Process time for profiling: sum of the kernel and user-space CPU time.");
    1146             : 
    1147             : 
    1148             : static PyObject *
    1149           0 : time_get_clock_info(PyObject *self, PyObject *args)
    1150             : {
    1151             :     char *name;
    1152             :     _Py_clock_info_t info;
    1153           0 :     PyObject *obj = NULL, *dict, *ns;
    1154             : 
    1155           0 :     if (!PyArg_ParseTuple(args, "s:get_clock_info", &name))
    1156           0 :         return NULL;
    1157             : 
    1158             : #ifdef Py_DEBUG
    1159             :     info.implementation = NULL;
    1160             :     info.monotonic = -1;
    1161             :     info.adjustable = -1;
    1162             :     info.resolution = -1.0;
    1163             : #else
    1164           0 :     info.implementation = "";
    1165           0 :     info.monotonic = 0;
    1166           0 :     info.adjustable = 0;
    1167           0 :     info.resolution = 1.0;
    1168             : #endif
    1169             : 
    1170           0 :     if (strcmp(name, "time") == 0)
    1171           0 :         obj = floattime(&info);
    1172             : #ifdef PYCLOCK
    1173           0 :     else if (strcmp(name, "clock") == 0)
    1174           0 :         obj = pyclock(&info);
    1175             : #endif
    1176             : #ifdef PYMONOTONIC
    1177           0 :     else if (strcmp(name, "monotonic") == 0)
    1178           0 :         obj = pymonotonic(&info);
    1179             : #endif
    1180           0 :     else if (strcmp(name, "perf_counter") == 0)
    1181           0 :         obj = perf_counter(&info);
    1182           0 :     else if (strcmp(name, "process_time") == 0)
    1183           0 :         obj = py_process_time(&info);
    1184             :     else {
    1185           0 :         PyErr_SetString(PyExc_ValueError, "unknown clock");
    1186           0 :         return NULL;
    1187             :     }
    1188           0 :     if (obj == NULL)
    1189           0 :         return NULL;
    1190           0 :     Py_DECREF(obj);
    1191             : 
    1192           0 :     dict = PyDict_New();
    1193           0 :     if (dict == NULL)
    1194           0 :         return NULL;
    1195             : 
    1196             :     assert(info.implementation != NULL);
    1197           0 :     obj = PyUnicode_FromString(info.implementation);
    1198           0 :     if (obj == NULL)
    1199           0 :         goto error;
    1200           0 :     if (PyDict_SetItemString(dict, "implementation", obj) == -1)
    1201           0 :         goto error;
    1202           0 :     Py_CLEAR(obj);
    1203             : 
    1204             :     assert(info.monotonic != -1);
    1205           0 :     obj = PyBool_FromLong(info.monotonic);
    1206           0 :     if (obj == NULL)
    1207           0 :         goto error;
    1208           0 :     if (PyDict_SetItemString(dict, "monotonic", obj) == -1)
    1209           0 :         goto error;
    1210           0 :     Py_CLEAR(obj);
    1211             : 
    1212             :     assert(info.adjustable != -1);
    1213           0 :     obj = PyBool_FromLong(info.adjustable);
    1214           0 :     if (obj == NULL)
    1215           0 :         goto error;
    1216           0 :     if (PyDict_SetItemString(dict, "adjustable", obj) == -1)
    1217           0 :         goto error;
    1218           0 :     Py_CLEAR(obj);
    1219             : 
    1220             :     assert(info.resolution > 0.0);
    1221             :     assert(info.resolution <= 1.0);
    1222           0 :     obj = PyFloat_FromDouble(info.resolution);
    1223           0 :     if (obj == NULL)
    1224           0 :         goto error;
    1225           0 :     if (PyDict_SetItemString(dict, "resolution", obj) == -1)
    1226           0 :         goto error;
    1227           0 :     Py_CLEAR(obj);
    1228             : 
    1229           0 :     ns = _PyNamespace_New(dict);
    1230           0 :     Py_DECREF(dict);
    1231           0 :     return ns;
    1232             : 
    1233             : error:
    1234           0 :     Py_DECREF(dict);
    1235           0 :     Py_XDECREF(obj);
    1236           0 :     return NULL;
    1237             : }
    1238             : 
    1239             : PyDoc_STRVAR(get_clock_info_doc,
    1240             : "get_clock_info(name: str) -> dict\n\
    1241             : \n\
    1242             : Get information of the specified clock.");
    1243             : 
    1244             : static void
    1245           0 : PyInit_timezone(PyObject *m) {
    1246             :     /* This code moved from PyInit_time wholesale to allow calling it from
    1247             :     time_tzset. In the future, some parts of it can be moved back
    1248             :     (for platforms that don't HAVE_WORKING_TZSET, when we know what they
    1249             :     are), and the extraneous calls to tzset(3) should be removed.
    1250             :     I haven't done this yet, as I don't want to change this code as
    1251             :     little as possible when introducing the time.tzset and time.tzsetwall
    1252             :     methods. This should simply be a method of doing the following once,
    1253             :     at the top of this function and removing the call to tzset() from
    1254             :     time_tzset():
    1255             : 
    1256             :         #ifdef HAVE_TZSET
    1257             :         tzset()
    1258             :         #endif
    1259             : 
    1260             :     And I'm lazy and hate C so nyer.
    1261             :      */
    1262             : #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
    1263             :     PyObject *otz0, *otz1;
    1264             :     tzset();
    1265             : #ifdef PYOS_OS2
    1266             :     PyModule_AddIntConstant(m, "timezone", _timezone);
    1267             : #else /* !PYOS_OS2 */
    1268             :     PyModule_AddIntConstant(m, "timezone", timezone);
    1269             : #endif /* PYOS_OS2 */
    1270             : #ifdef HAVE_ALTZONE
    1271             :     PyModule_AddIntConstant(m, "altzone", altzone);
    1272             : #else
    1273             : #ifdef PYOS_OS2
    1274             :     PyModule_AddIntConstant(m, "altzone", _timezone-3600);
    1275             : #else /* !PYOS_OS2 */
    1276             :     PyModule_AddIntConstant(m, "altzone", timezone-3600);
    1277             : #endif /* PYOS_OS2 */
    1278             : #endif
    1279             :     PyModule_AddIntConstant(m, "daylight", daylight);
    1280             :     otz0 = PyUnicode_DecodeLocale(tzname[0], "surrogateescape");
    1281             :     otz1 = PyUnicode_DecodeLocale(tzname[1], "surrogateescape");
    1282             :     PyModule_AddObject(m, "tzname", Py_BuildValue("(NN)", otz0, otz1));
    1283             : #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
    1284             : #ifdef HAVE_STRUCT_TM_TM_ZONE
    1285             :     {
    1286             : #define YEAR ((time_t)((365 * 24 + 6) * 3600))
    1287             :         time_t t;
    1288             :         struct tm *p;
    1289             :         long janzone, julyzone;
    1290             :         char janname[10], julyname[10];
    1291           0 :         t = (time((time_t *)0) / YEAR) * YEAR;
    1292           0 :         p = localtime(&t);
    1293           0 :         janzone = -p->tm_gmtoff;
    1294           0 :         strncpy(janname, p->tm_zone ? p->tm_zone : "   ", 9);
    1295           0 :         janname[9] = '\0';
    1296           0 :         t += YEAR/2;
    1297           0 :         p = localtime(&t);
    1298           0 :         julyzone = -p->tm_gmtoff;
    1299           0 :         strncpy(julyname, p->tm_zone ? p->tm_zone : "   ", 9);
    1300           0 :         julyname[9] = '\0';
    1301             : 
    1302           0 :         if( janzone < julyzone ) {
    1303             :             /* DST is reversed in the southern hemisphere */
    1304           0 :             PyModule_AddIntConstant(m, "timezone", julyzone);
    1305           0 :             PyModule_AddIntConstant(m, "altzone", janzone);
    1306           0 :             PyModule_AddIntConstant(m, "daylight",
    1307             :                                     janzone != julyzone);
    1308           0 :             PyModule_AddObject(m, "tzname",
    1309             :                                Py_BuildValue("(zz)",
    1310             :                                              julyname, janname));
    1311             :         } else {
    1312           0 :             PyModule_AddIntConstant(m, "timezone", janzone);
    1313           0 :             PyModule_AddIntConstant(m, "altzone", julyzone);
    1314           0 :             PyModule_AddIntConstant(m, "daylight",
    1315             :                                     janzone != julyzone);
    1316           0 :             PyModule_AddObject(m, "tzname",
    1317             :                                Py_BuildValue("(zz)",
    1318             :                                              janname, julyname));
    1319             :         }
    1320             :     }
    1321             : #else
    1322             : #endif /* HAVE_STRUCT_TM_TM_ZONE */
    1323             : #ifdef __CYGWIN__
    1324             :     tzset();
    1325             :     PyModule_AddIntConstant(m, "timezone", _timezone);
    1326             :     PyModule_AddIntConstant(m, "altzone", _timezone-3600);
    1327             :     PyModule_AddIntConstant(m, "daylight", _daylight);
    1328             :     PyModule_AddObject(m, "tzname",
    1329             :                        Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
    1330             : #endif /* __CYGWIN__ */
    1331             : #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
    1332             : 
    1333             : #if defined(HAVE_CLOCK_GETTIME)
    1334           0 :     PyModule_AddIntMacro(m, CLOCK_REALTIME);
    1335             : #ifdef CLOCK_MONOTONIC
    1336           0 :     PyModule_AddIntMacro(m, CLOCK_MONOTONIC);
    1337             : #endif
    1338             : #ifdef CLOCK_MONOTONIC_RAW
    1339           0 :     PyModule_AddIntMacro(m, CLOCK_MONOTONIC_RAW);
    1340             : #endif
    1341             : #ifdef CLOCK_HIGHRES
    1342             :     PyModule_AddIntMacro(m, CLOCK_HIGHRES);
    1343             : #endif
    1344             : #ifdef CLOCK_PROCESS_CPUTIME_ID
    1345           0 :     PyModule_AddIntMacro(m, CLOCK_PROCESS_CPUTIME_ID);
    1346             : #endif
    1347             : #ifdef CLOCK_THREAD_CPUTIME_ID
    1348           0 :     PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID);
    1349             : #endif
    1350             : #endif /* HAVE_CLOCK_GETTIME */
    1351           0 : }
    1352             : 
    1353             : 
    1354             : static PyMethodDef time_methods[] = {
    1355             :     {"time",            time_time, METH_NOARGS, time_doc},
    1356             : #ifdef PYCLOCK
    1357             :     {"clock",           time_clock, METH_NOARGS, clock_doc},
    1358             : #endif
    1359             : #ifdef HAVE_CLOCK_GETTIME
    1360             :     {"clock_gettime",   time_clock_gettime, METH_VARARGS, clock_gettime_doc},
    1361             :     {"clock_settime",   time_clock_settime, METH_VARARGS, clock_settime_doc},
    1362             :     {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
    1363             : #endif
    1364             :     {"sleep",           time_sleep, METH_VARARGS, sleep_doc},
    1365             :     {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
    1366             :     {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
    1367             :     {"asctime",         time_asctime, METH_VARARGS, asctime_doc},
    1368             :     {"ctime",           time_ctime, METH_VARARGS, ctime_doc},
    1369             : #ifdef HAVE_MKTIME
    1370             :     {"mktime",          time_mktime, METH_O, mktime_doc},
    1371             : #endif
    1372             : #ifdef HAVE_STRFTIME
    1373             :     {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
    1374             : #endif
    1375             :     {"strptime",        time_strptime, METH_VARARGS, strptime_doc},
    1376             : #ifdef HAVE_WORKING_TZSET
    1377             :     {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
    1378             : #endif
    1379             : #ifdef PYMONOTONIC
    1380             :     {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
    1381             : #endif
    1382             :     {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
    1383             :     {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
    1384             :     {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},
    1385             :     {NULL,              NULL}           /* sentinel */
    1386             : };
    1387             : 
    1388             : 
    1389             : PyDoc_STRVAR(module_doc,
    1390             : "This module provides various functions to manipulate time values.\n\
    1391             : \n\
    1392             : There are two standard representations of time.  One is the number\n\
    1393             : of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\n\
    1394             : or a floating point number (to represent fractions of seconds).\n\
    1395             : The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
    1396             : The actual value can be retrieved by calling gmtime(0).\n\
    1397             : \n\
    1398             : The other representation is a tuple of 9 integers giving local time.\n\
    1399             : The tuple items are:\n\
    1400             :   year (including century, e.g. 1998)\n\
    1401             :   month (1-12)\n\
    1402             :   day (1-31)\n\
    1403             :   hours (0-23)\n\
    1404             :   minutes (0-59)\n\
    1405             :   seconds (0-59)\n\
    1406             :   weekday (0-6, Monday is 0)\n\
    1407             :   Julian day (day in the year, 1-366)\n\
    1408             :   DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
    1409             : If the DST flag is 0, the time is given in the regular time zone;\n\
    1410             : if it is 1, the time is given in the DST time zone;\n\
    1411             : if it is -1, mktime() should guess based on the date and time.\n\
    1412             : \n\
    1413             : Variables:\n\
    1414             : \n\
    1415             : timezone -- difference in seconds between UTC and local standard time\n\
    1416             : altzone -- difference in  seconds between UTC and local DST time\n\
    1417             : daylight -- whether local time should reflect DST\n\
    1418             : tzname -- tuple of (standard time zone name, DST time zone name)\n\
    1419             : \n\
    1420             : Functions:\n\
    1421             : \n\
    1422             : time() -- return current time in seconds since the Epoch as a float\n\
    1423             : clock() -- return CPU time since process start as a float\n\
    1424             : sleep() -- delay for a number of seconds given as a float\n\
    1425             : gmtime() -- convert seconds since Epoch to UTC tuple\n\
    1426             : localtime() -- convert seconds since Epoch to local time tuple\n\
    1427             : asctime() -- convert time tuple to string\n\
    1428             : ctime() -- convert time in seconds to string\n\
    1429             : mktime() -- convert local time tuple to seconds since Epoch\n\
    1430             : strftime() -- convert time tuple to string according to format specification\n\
    1431             : strptime() -- parse string to time tuple according to format specification\n\
    1432             : tzset() -- change the local timezone");
    1433             : 
    1434             : 
    1435             : 
    1436             : static struct PyModuleDef timemodule = {
    1437             :     PyModuleDef_HEAD_INIT,
    1438             :     "time",
    1439             :     module_doc,
    1440             :     -1,
    1441             :     time_methods,
    1442             :     NULL,
    1443             :     NULL,
    1444             :     NULL,
    1445             :     NULL
    1446             : };
    1447             : 
    1448             : PyMODINIT_FUNC
    1449           0 : PyInit_time(void)
    1450             : {
    1451             :     PyObject *m;
    1452           0 :     m = PyModule_Create(&timemodule);
    1453           0 :     if (m == NULL)
    1454           0 :         return NULL;
    1455             : 
    1456             :     /* Set, or reset, module variables like time.timezone */
    1457           0 :     PyInit_timezone(m);
    1458             : 
    1459           0 :     if (!initialized) {
    1460           0 :         PyStructSequence_InitType(&StructTimeType,
    1461             :                                   &struct_time_type_desc);
    1462             : 
    1463             : #ifdef MS_WINDOWS
    1464             :         winver.dwOSVersionInfoSize = sizeof(winver);
    1465             :         if (!GetVersionEx((OSVERSIONINFO*)&winver)) {
    1466             :             Py_DECREF(m);
    1467             :             PyErr_SetFromWindowsErr(0);
    1468             :             return NULL;
    1469             :         }
    1470             : #endif
    1471             :     }
    1472           0 :     Py_INCREF(&StructTimeType);
    1473             : #ifdef HAVE_STRUCT_TM_TM_ZONE
    1474           0 :     PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 11);
    1475             : #else
    1476             :     PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 9);
    1477             : #endif
    1478           0 :     PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
    1479           0 :     initialized = 1;
    1480           0 :     return m;
    1481             : }
    1482             : 
    1483             : static PyObject*
    1484           0 : floattime(_Py_clock_info_t *info)
    1485             : {
    1486             :     _PyTime_timeval t;
    1487             : #ifdef HAVE_CLOCK_GETTIME
    1488             :     struct timespec tp;
    1489             :     int ret;
    1490             : 
    1491             :     /* _PyTime_gettimeofday() does not use clock_gettime()
    1492             :        because it would require to link Python to the rt (real-time)
    1493             :        library, at least on Linux */
    1494           0 :     ret = clock_gettime(CLOCK_REALTIME, &tp);
    1495           0 :     if (ret == 0) {
    1496           0 :         if (info) {
    1497             :             struct timespec res;
    1498           0 :             info->implementation = "clock_gettime(CLOCK_REALTIME)";
    1499           0 :             info->monotonic = 0;
    1500           0 :             info->adjustable = 1;
    1501           0 :             if (clock_getres(CLOCK_REALTIME, &res) == 0)
    1502           0 :                 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
    1503             :             else
    1504           0 :                 info->resolution = 1e-9;
    1505             :         }
    1506           0 :         return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
    1507             :     }
    1508             : #endif
    1509           0 :     _PyTime_gettimeofday_info(&t, info);
    1510           0 :     return PyFloat_FromDouble((double)t.tv_sec + t.tv_usec * 1e-6);
    1511             : }
    1512             : 
    1513             : 
    1514             : /* Implement floatsleep() for various platforms.
    1515             :    When interrupted (or when another error occurs), return -1 and
    1516             :    set an exception; else return 0. */
    1517             : 
    1518             : static int
    1519           0 : floatsleep(double secs)
    1520             : {
    1521             : /* XXX Should test for MS_WINDOWS first! */
    1522             : #if defined(HAVE_SELECT) && !defined(__EMX__)
    1523             :     struct timeval t;
    1524             :     double frac;
    1525             :     int err;
    1526             : 
    1527           0 :     frac = fmod(secs, 1.0);
    1528           0 :     secs = floor(secs);
    1529           0 :     t.tv_sec = (long)secs;
    1530           0 :     t.tv_usec = (long)(frac*1000000.0);
    1531           0 :     Py_BEGIN_ALLOW_THREADS
    1532           0 :     err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
    1533           0 :     Py_END_ALLOW_THREADS
    1534           0 :     if (err != 0) {
    1535             : #ifdef EINTR
    1536           0 :         if (errno == EINTR) {
    1537           0 :             if (PyErr_CheckSignals())
    1538           0 :                 return -1;
    1539             :         }
    1540             :         else
    1541             : #endif
    1542             :         {
    1543           0 :             PyErr_SetFromErrno(PyExc_IOError);
    1544           0 :             return -1;
    1545             :         }
    1546             :     }
    1547             : #elif defined(__WATCOMC__) && !defined(__QNX__)
    1548             :     /* XXX Can't interrupt this sleep */
    1549             :     Py_BEGIN_ALLOW_THREADS
    1550             :     delay((int)(secs * 1000 + 0.5));  /* delay() uses milliseconds */
    1551             :     Py_END_ALLOW_THREADS
    1552             : #elif defined(MS_WINDOWS)
    1553             :     {
    1554             :         double millisecs = secs * 1000.0;
    1555             :         unsigned long ul_millis;
    1556             : 
    1557             :         if (millisecs > (double)ULONG_MAX) {
    1558             :             PyErr_SetString(PyExc_OverflowError,
    1559             :                             "sleep length is too large");
    1560             :             return -1;
    1561             :         }
    1562             :         Py_BEGIN_ALLOW_THREADS
    1563             :         /* Allow sleep(0) to maintain win32 semantics, and as decreed
    1564             :          * by Guido, only the main thread can be interrupted.
    1565             :          */
    1566             :         ul_millis = (unsigned long)millisecs;
    1567             :         if (ul_millis == 0 || !_PyOS_IsMainThread())
    1568             :             Sleep(ul_millis);
    1569             :         else {
    1570             :             DWORD rc;
    1571             :             HANDLE hInterruptEvent = _PyOS_SigintEvent();
    1572             :             ResetEvent(hInterruptEvent);
    1573             :             rc = WaitForSingleObject(hInterruptEvent, ul_millis);
    1574             :             if (rc == WAIT_OBJECT_0) {
    1575             :                 Py_BLOCK_THREADS
    1576             :                 errno = EINTR;
    1577             :                 PyErr_SetFromErrno(PyExc_IOError);
    1578             :                 return -1;
    1579             :             }
    1580             :         }
    1581             :         Py_END_ALLOW_THREADS
    1582             :     }
    1583             : #elif defined(PYOS_OS2)
    1584             :     /* This Sleep *IS* Interruptable by Exceptions */
    1585             :     Py_BEGIN_ALLOW_THREADS
    1586             :     if (DosSleep(secs * 1000) != NO_ERROR) {
    1587             :         Py_BLOCK_THREADS
    1588             :         PyErr_SetFromErrno(PyExc_IOError);
    1589             :         return -1;
    1590             :     }
    1591             :     Py_END_ALLOW_THREADS
    1592             : #else
    1593             :     /* XXX Can't interrupt this sleep */
    1594             :     Py_BEGIN_ALLOW_THREADS
    1595             :     sleep((int)secs);
    1596             :     Py_END_ALLOW_THREADS
    1597             : #endif
    1598             : 
    1599           0 :     return 0;
    1600             : }

Generated by: LCOV version 1.10