diff options
Diffstat (limited to 'Modules/timemodule.c')
-rw-r--r-- | Modules/timemodule.c | 1264 |
1 files changed, 632 insertions, 632 deletions
diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 0161ac0..20acacf 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -48,12 +48,12 @@ extern int ftime(struct timeb *); static HANDLE hInterruptEvent = NULL; static BOOL WINAPI PyCtrlHandler(DWORD dwCtrlType) { - SetEvent(hInterruptEvent); - /* allow other default handlers to be called. - Default Python handler will setup the - KeyboardInterrupt exception. - */ - return FALSE; + SetEvent(hInterruptEvent); + /* allow other default handlers to be called. + Default Python handler will setup the + KeyboardInterrupt exception. + */ + return FALSE; } static long main_thread; @@ -94,38 +94,38 @@ static PyObject *moddict; time_t _PyTime_DoubleToTimet(double x) { - time_t result; - double diff; - - result = (time_t)x; - /* How much info did we lose? time_t may be an integral or - * floating type, and we don't know which. If it's integral, - * we don't know whether C truncates, rounds, returns the floor, - * etc. If we lost a second or more, the C rounding is - * unreasonable, or the input just doesn't fit in a time_t; - * call it an error regardless. Note that the original cast to - * time_t can cause a C error too, but nothing we can do to - * worm around that. - */ - diff = x - (double)result; - if (diff <= -1.0 || diff >= 1.0) { - PyErr_SetString(PyExc_ValueError, - "timestamp out of range for platform time_t"); - result = (time_t)-1; - } - return result; + time_t result; + double diff; + + result = (time_t)x; + /* How much info did we lose? time_t may be an integral or + * floating type, and we don't know which. If it's integral, + * we don't know whether C truncates, rounds, returns the floor, + * etc. If we lost a second or more, the C rounding is + * unreasonable, or the input just doesn't fit in a time_t; + * call it an error regardless. Note that the original cast to + * time_t can cause a C error too, but nothing we can do to + * worm around that. + */ + diff = x - (double)result; + if (diff <= -1.0 || diff >= 1.0) { + PyErr_SetString(PyExc_ValueError, + "timestamp out of range for platform time_t"); + result = (time_t)-1; + } + return result; } static PyObject * time_time(PyObject *self, PyObject *unused) { - double secs; - secs = floattime(); - if (secs == 0.0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - return PyFloat_FromDouble(secs); + double secs; + secs = floattime(); + if (secs == 0.0) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + return PyFloat_FromDouble(secs); } PyDoc_STRVAR(time_doc, @@ -147,7 +147,7 @@ Fractions of a second may be present if the system clock provides them."); static PyObject * time_clock(PyObject *self, PyObject *unused) { - return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC); + return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC); } #endif /* HAVE_CLOCK */ @@ -156,25 +156,25 @@ time_clock(PyObject *self, PyObject *unused) static PyObject * time_clock(PyObject *self, PyObject *unused) { - static LARGE_INTEGER ctrStart; - static double divisor = 0.0; - LARGE_INTEGER now; - double diff; - - if (divisor == 0.0) { - LARGE_INTEGER freq; - QueryPerformanceCounter(&ctrStart); - if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { - /* Unlikely to happen - this works on all intel - machines at least! Revert to clock() */ - return PyFloat_FromDouble(((double)clock()) / - CLOCKS_PER_SEC); - } - divisor = (double)freq.QuadPart; - } - QueryPerformanceCounter(&now); - diff = (double)(now.QuadPart - ctrStart.QuadPart); - return PyFloat_FromDouble(diff / divisor); + static LARGE_INTEGER ctrStart; + static double divisor = 0.0; + LARGE_INTEGER now; + double diff; + + if (divisor == 0.0) { + LARGE_INTEGER freq; + QueryPerformanceCounter(&ctrStart); + if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { + /* Unlikely to happen - this works on all intel + machines at least! Revert to clock() */ + return PyFloat_FromDouble(((double)clock()) / + CLOCKS_PER_SEC); + } + divisor = (double)freq.QuadPart; + } + QueryPerformanceCounter(&now); + diff = (double)(now.QuadPart - ctrStart.QuadPart); + return PyFloat_FromDouble(diff / divisor); } #define HAVE_CLOCK /* So it gets included in the methods */ @@ -192,13 +192,13 @@ records."); static PyObject * time_sleep(PyObject *self, PyObject *args) { - double secs; - if (!PyArg_ParseTuple(args, "d:sleep", &secs)) - return NULL; - if (floatsleep(secs) != 0) - return NULL; - Py_INCREF(Py_None); - return Py_None; + double secs; + if (!PyArg_ParseTuple(args, "d:sleep", &secs)) + return NULL; + if (floatsleep(secs) != 0) + return NULL; + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(sleep_doc, @@ -208,23 +208,23 @@ Delay execution for a given number of seconds. The argument may be\n\ a floating point number for subsecond precision."); static PyStructSequence_Field struct_time_type_fields[] = { - {"tm_year", NULL}, - {"tm_mon", NULL}, - {"tm_mday", NULL}, - {"tm_hour", NULL}, - {"tm_min", NULL}, - {"tm_sec", NULL}, - {"tm_wday", NULL}, - {"tm_yday", NULL}, - {"tm_isdst", NULL}, - {0} + {"tm_year", NULL}, + {"tm_mon", NULL}, + {"tm_mday", NULL}, + {"tm_hour", NULL}, + {"tm_min", NULL}, + {"tm_sec", NULL}, + {"tm_wday", NULL}, + {"tm_yday", NULL}, + {"tm_isdst", NULL}, + {0} }; static PyStructSequence_Desc struct_time_type_desc = { - "time.struct_time", - NULL, - struct_time_type_fields, - 9, + "time.struct_time", + NULL, + struct_time_type_fields, + 9, }; static int initialized; @@ -233,71 +233,71 @@ static PyTypeObject StructTimeType; static PyObject * tmtotuple(struct tm *p) { - PyObject *v = PyStructSequence_New(&StructTimeType); - if (v == NULL) - return NULL; + PyObject *v = PyStructSequence_New(&StructTimeType); + if (v == NULL) + return NULL; #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) - SET(0, p->tm_year + 1900); - SET(1, p->tm_mon + 1); /* Want January == 1 */ - SET(2, p->tm_mday); - SET(3, p->tm_hour); - SET(4, p->tm_min); - SET(5, p->tm_sec); - SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */ - SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */ - SET(8, p->tm_isdst); + SET(0, p->tm_year + 1900); + SET(1, p->tm_mon + 1); /* Want January == 1 */ + SET(2, p->tm_mday); + SET(3, p->tm_hour); + SET(4, p->tm_min); + SET(5, p->tm_sec); + SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */ + SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */ + SET(8, p->tm_isdst); #undef SET - if (PyErr_Occurred()) { - Py_XDECREF(v); - return NULL; - } + if (PyErr_Occurred()) { + Py_XDECREF(v); + return NULL; + } - return v; + return v; } static PyObject * structtime_totuple(PyObject *t) { - PyObject *x = NULL; - unsigned int i; - PyObject *v = PyTuple_New(9); - if (v == NULL) - return NULL; - - for (i=0; i<9; i++) { - x = PyStructSequence_GET_ITEM(t, i); - Py_INCREF(x); - PyTuple_SET_ITEM(v, i, x); - } - - if (PyErr_Occurred()) { - Py_XDECREF(v); - return NULL; - } - - return v; + PyObject *x = NULL; + unsigned int i; + PyObject *v = PyTuple_New(9); + if (v == NULL) + return NULL; + + for (i=0; i<9; i++) { + x = PyStructSequence_GET_ITEM(t, i); + Py_INCREF(x); + PyTuple_SET_ITEM(v, i, x); + } + + if (PyErr_Occurred()) { + Py_XDECREF(v); + return NULL; + } + + return v; } static PyObject * time_convert(double when, struct tm * (*function)(const time_t *)) { - struct tm *p; - time_t whent = _PyTime_DoubleToTimet(when); - - if (whent == (time_t)-1 && PyErr_Occurred()) - return NULL; - errno = 0; - p = function(&whent); - if (p == NULL) { + struct tm *p; + time_t whent = _PyTime_DoubleToTimet(when); + + if (whent == (time_t)-1 && PyErr_Occurred()) + return NULL; + errno = 0; + p = function(&whent); + if (p == NULL) { #ifdef EINVAL - if (errno == 0) - errno = EINVAL; + if (errno == 0) + errno = EINVAL; #endif - return PyErr_SetFromErrno(PyExc_ValueError); - } - return tmtotuple(p); + return PyErr_SetFromErrno(PyExc_ValueError); + } + return tmtotuple(p); } /* Parse arg tuple that can contain an optional float-or-None value; @@ -307,28 +307,28 @@ time_convert(double when, struct tm * (*function)(const time_t *)) static int parse_time_double_args(PyObject *args, char *format, double *pwhen) { - PyObject *ot = NULL; - - if (!PyArg_ParseTuple(args, format, &ot)) - return 0; - if (ot == NULL || ot == Py_None) - *pwhen = floattime(); - else { - double when = PyFloat_AsDouble(ot); - if (PyErr_Occurred()) - return 0; - *pwhen = when; - } - return 1; + PyObject *ot = NULL; + + if (!PyArg_ParseTuple(args, format, &ot)) + return 0; + if (ot == NULL || ot == Py_None) + *pwhen = floattime(); + else { + double when = PyFloat_AsDouble(ot); + if (PyErr_Occurred()) + return 0; + *pwhen = when; + } + return 1; } static PyObject * time_gmtime(PyObject *self, PyObject *args) { - double when; - if (!parse_time_double_args(args, "|O:gmtime", &when)) - return NULL; - return time_convert(when, gmtime); + double when; + if (!parse_time_double_args(args, "|O:gmtime", &when)) + return NULL; + return time_convert(when, gmtime); } PyDoc_STRVAR(gmtime_doc, @@ -341,15 +341,15 @@ GMT). When 'seconds' is not passed in, convert the current time instead."); static PyObject * time_localtime(PyObject *self, PyObject *args) { - double when; - if (!parse_time_double_args(args, "|O:localtime", &when)) - return NULL; - return time_convert(when, localtime); + double when; + if (!parse_time_double_args(args, "|O:localtime", &when)) + return NULL; + return time_convert(when, localtime); } PyDoc_STRVAR(localtime_doc, "localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\ - tm_sec,tm_wday,tm_yday,tm_isdst)\n\ + tm_sec,tm_wday,tm_yday,tm_isdst)\n\ \n\ Convert seconds since the Epoch to a time tuple expressing local time.\n\ When 'seconds' is not passed in, convert the current time instead."); @@ -357,63 +357,63 @@ When 'seconds' is not passed in, convert the current time instead."); static int gettmarg(PyObject *args, struct tm *p) { - int y; - PyObject *t = NULL; - - memset((void *) p, '\0', sizeof(struct tm)); - - if (PyTuple_Check(args)) { - t = args; - Py_INCREF(t); - } - else if (Py_TYPE(args) == &StructTimeType) { - t = structtime_totuple(args); - } - else { - PyErr_SetString(PyExc_TypeError, - "Tuple or struct_time argument required"); - return 0; - } - - if (t == NULL || !PyArg_ParseTuple(t, "iiiiiiiii", - &y, - &p->tm_mon, - &p->tm_mday, - &p->tm_hour, - &p->tm_min, - &p->tm_sec, - &p->tm_wday, - &p->tm_yday, - &p->tm_isdst)) { - Py_XDECREF(t); - return 0; - } - Py_DECREF(t); - - if (y < 1900) { - PyObject *accept = PyDict_GetItemString(moddict, - "accept2dyear"); - if (accept == NULL || !PyLong_CheckExact(accept) || - !PyObject_IsTrue(accept)) { - PyErr_SetString(PyExc_ValueError, - "year >= 1900 required"); - return 0; - } - if (69 <= y && y <= 99) - y += 1900; - else if (0 <= y && y <= 68) - y += 2000; - else { - PyErr_SetString(PyExc_ValueError, - "year out of range"); - return 0; - } - } - p->tm_year = y - 1900; - p->tm_mon--; - p->tm_wday = (p->tm_wday + 1) % 7; - p->tm_yday--; - return 1; + int y; + PyObject *t = NULL; + + memset((void *) p, '\0', sizeof(struct tm)); + + if (PyTuple_Check(args)) { + t = args; + Py_INCREF(t); + } + else if (Py_TYPE(args) == &StructTimeType) { + t = structtime_totuple(args); + } + else { + PyErr_SetString(PyExc_TypeError, + "Tuple or struct_time argument required"); + return 0; + } + + if (t == NULL || !PyArg_ParseTuple(t, "iiiiiiiii", + &y, + &p->tm_mon, + &p->tm_mday, + &p->tm_hour, + &p->tm_min, + &p->tm_sec, + &p->tm_wday, + &p->tm_yday, + &p->tm_isdst)) { + Py_XDECREF(t); + return 0; + } + Py_DECREF(t); + + if (y < 1900) { + PyObject *accept = PyDict_GetItemString(moddict, + "accept2dyear"); + if (accept == NULL || !PyLong_CheckExact(accept) || + !PyObject_IsTrue(accept)) { + PyErr_SetString(PyExc_ValueError, + "year >= 1900 required"); + return 0; + } + if (69 <= y && y <= 99) + y += 1900; + else if (0 <= y && y <= 68) + y += 2000; + else { + PyErr_SetString(PyExc_ValueError, + "year out of range"); + return 0; + } + } + p->tm_year = y - 1900; + p->tm_mon--; + p->tm_wday = (p->tm_wday + 1) % 7; + p->tm_yday--; + return 1; } #ifdef HAVE_STRFTIME @@ -430,174 +430,174 @@ gettmarg(PyObject *args, struct tm *p) static PyObject * time_strftime(PyObject *self, PyObject *args) { - PyObject *tup = NULL; - struct tm buf; - const time_char *fmt; - PyObject *format, *tmpfmt; - size_t fmtlen, buflen; - time_char *outbuf = 0; - size_t i; - - memset((void *) &buf, '\0', sizeof(buf)); - - /* Will always expect a unicode string to be passed as format. - Given that there's no str type anymore in py3k this seems safe. - */ - if (!PyArg_ParseTuple(args, "U|O:strftime", &format, &tup)) - return NULL; - - if (tup == NULL) { - time_t tt = time(NULL); - buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf)) - return NULL; - - /* Checks added to make sure strftime() does not crash Python by - indexing blindly into some array for a textual representation - by some bad index (fixes bug #897625). - - Also support values of zero from Python code for arguments in which - that is out of range by forcing that value to the lowest value that - is valid (fixed bug #1520914). - - Valid ranges based on what is allowed in struct tm: - - - tm_year: [0, max(int)] (1) - - tm_mon: [0, 11] (2) - - tm_mday: [1, 31] - - tm_hour: [0, 23] - - tm_min: [0, 59] - - tm_sec: [0, 60] - - tm_wday: [0, 6] (1) - - tm_yday: [0, 365] (2) - - tm_isdst: [-max(int), max(int)] - - (1) gettmarg() handles bounds-checking. - (2) Python's acceptable range is one greater than the range in C, - thus need to check against automatic decrement by gettmarg(). - */ - if (buf.tm_mon == -1) - buf.tm_mon = 0; - else if (buf.tm_mon < 0 || buf.tm_mon > 11) { - PyErr_SetString(PyExc_ValueError, "month out of range"); - return NULL; - } - if (buf.tm_mday == 0) - buf.tm_mday = 1; - else if (buf.tm_mday < 0 || buf.tm_mday > 31) { - PyErr_SetString(PyExc_ValueError, "day of month out of range"); - return NULL; - } - if (buf.tm_hour < 0 || buf.tm_hour > 23) { - PyErr_SetString(PyExc_ValueError, "hour out of range"); - return NULL; - } - if (buf.tm_min < 0 || buf.tm_min > 59) { - PyErr_SetString(PyExc_ValueError, "minute out of range"); - return NULL; - } - if (buf.tm_sec < 0 || buf.tm_sec > 61) { - PyErr_SetString(PyExc_ValueError, "seconds out of range"); - return NULL; - } - /* tm_wday does not need checking of its upper-bound since taking - ``% 7`` in gettmarg() automatically restricts the range. */ - if (buf.tm_wday < 0) { - PyErr_SetString(PyExc_ValueError, "day of week out of range"); - return NULL; - } - if (buf.tm_yday == -1) - buf.tm_yday = 0; - else if (buf.tm_yday < 0 || buf.tm_yday > 365) { - PyErr_SetString(PyExc_ValueError, "day of year out of range"); - return NULL; - } - /* Normalize tm_isdst just in case someone foolishly implements %Z - based on the assumption that tm_isdst falls within the range of - [-1, 1] */ - if (buf.tm_isdst < -1) - buf.tm_isdst = -1; - else if (buf.tm_isdst > 1) - buf.tm_isdst = 1; + PyObject *tup = NULL; + struct tm buf; + const time_char *fmt; + PyObject *format, *tmpfmt; + size_t fmtlen, buflen; + time_char *outbuf = 0; + size_t i; + + memset((void *) &buf, '\0', sizeof(buf)); + + /* Will always expect a unicode string to be passed as format. + Given that there's no str type anymore in py3k this seems safe. + */ + if (!PyArg_ParseTuple(args, "U|O:strftime", &format, &tup)) + return NULL; + + if (tup == NULL) { + time_t tt = time(NULL); + buf = *localtime(&tt); + } else if (!gettmarg(tup, &buf)) + return NULL; + + /* Checks added to make sure strftime() does not crash Python by + indexing blindly into some array for a textual representation + by some bad index (fixes bug #897625). + + Also support values of zero from Python code for arguments in which + that is out of range by forcing that value to the lowest value that + is valid (fixed bug #1520914). + + Valid ranges based on what is allowed in struct tm: + + - tm_year: [0, max(int)] (1) + - tm_mon: [0, 11] (2) + - tm_mday: [1, 31] + - tm_hour: [0, 23] + - tm_min: [0, 59] + - tm_sec: [0, 60] + - tm_wday: [0, 6] (1) + - tm_yday: [0, 365] (2) + - tm_isdst: [-max(int), max(int)] + + (1) gettmarg() handles bounds-checking. + (2) Python's acceptable range is one greater than the range in C, + thus need to check against automatic decrement by gettmarg(). + */ + if (buf.tm_mon == -1) + buf.tm_mon = 0; + else if (buf.tm_mon < 0 || buf.tm_mon > 11) { + PyErr_SetString(PyExc_ValueError, "month out of range"); + return NULL; + } + if (buf.tm_mday == 0) + buf.tm_mday = 1; + else if (buf.tm_mday < 0 || buf.tm_mday > 31) { + PyErr_SetString(PyExc_ValueError, "day of month out of range"); + return NULL; + } + if (buf.tm_hour < 0 || buf.tm_hour > 23) { + PyErr_SetString(PyExc_ValueError, "hour out of range"); + return NULL; + } + if (buf.tm_min < 0 || buf.tm_min > 59) { + PyErr_SetString(PyExc_ValueError, "minute out of range"); + return NULL; + } + if (buf.tm_sec < 0 || buf.tm_sec > 61) { + PyErr_SetString(PyExc_ValueError, "seconds out of range"); + return NULL; + } + /* tm_wday does not need checking of its upper-bound since taking + ``% 7`` in gettmarg() automatically restricts the range. */ + if (buf.tm_wday < 0) { + PyErr_SetString(PyExc_ValueError, "day of week out of range"); + return NULL; + } + if (buf.tm_yday == -1) + buf.tm_yday = 0; + else if (buf.tm_yday < 0 || buf.tm_yday > 365) { + PyErr_SetString(PyExc_ValueError, "day of year out of range"); + return NULL; + } + /* Normalize tm_isdst just in case someone foolishly implements %Z + based on the assumption that tm_isdst falls within the range of + [-1, 1] */ + if (buf.tm_isdst < -1) + buf.tm_isdst = -1; + else if (buf.tm_isdst > 1) + buf.tm_isdst = 1; #ifdef HAVE_WCSFTIME - tmpfmt = PyBytes_FromStringAndSize(NULL, - sizeof(wchar_t) * (PyUnicode_GetSize(format)+1)); - if (!tmpfmt) - return NULL; - /* This assumes that PyUnicode_AsWideChar doesn't do any UTF-16 - expansion. */ - if (PyUnicode_AsWideChar((PyUnicodeObject*)format, - (wchar_t*)PyBytes_AS_STRING(tmpfmt), - PyUnicode_GetSize(format)+1) == (size_t)-1) - /* This shouldn't fail. */ - Py_FatalError("PyUnicode_AsWideChar failed"); - format = tmpfmt; - fmt = (wchar_t*)PyBytes_AS_STRING(format); + tmpfmt = PyBytes_FromStringAndSize(NULL, + sizeof(wchar_t) * (PyUnicode_GetSize(format)+1)); + if (!tmpfmt) + return NULL; + /* This assumes that PyUnicode_AsWideChar doesn't do any UTF-16 + expansion. */ + if (PyUnicode_AsWideChar((PyUnicodeObject*)format, + (wchar_t*)PyBytes_AS_STRING(tmpfmt), + PyUnicode_GetSize(format)+1) == (size_t)-1) + /* This shouldn't fail. */ + Py_FatalError("PyUnicode_AsWideChar failed"); + format = tmpfmt; + fmt = (wchar_t*)PyBytes_AS_STRING(format); #else - /* Convert the unicode string to an ascii one */ - format = PyUnicode_AsEncodedString(format, TZNAME_ENCODING, NULL); - if (format == NULL) - return NULL; - fmt = PyBytes_AS_STRING(format); + /* Convert the unicode string to an ascii one */ + format = PyUnicode_AsEncodedString(format, TZNAME_ENCODING, NULL); + if (format == NULL) + return NULL; + fmt = PyBytes_AS_STRING(format); #endif #if defined(MS_WINDOWS) && defined(HAVE_WCSFTIME) - /* check that the format string contains only valid directives */ - for(outbuf = wcschr(fmt, L'%'); - outbuf != NULL; - outbuf = wcschr(outbuf+2, L'%')) - { - if (outbuf[1]=='#') - ++outbuf; /* not documented by python, */ - if (outbuf[1]=='\0' || - !wcschr(L"aAbBcdfHIjmMpSUwWxXyYzZ%", outbuf[1])) - { - PyErr_SetString(PyExc_ValueError, "Invalid format string"); - return 0; - } - } + /* check that the format string contains only valid directives */ + for(outbuf = wcschr(fmt, L'%'); + outbuf != NULL; + outbuf = wcschr(outbuf+2, L'%')) + { + if (outbuf[1]=='#') + ++outbuf; /* not documented by python, */ + if (outbuf[1]=='\0' || + !wcschr(L"aAbBcdfHIjmMpSUwWxXyYzZ%", outbuf[1])) + { + PyErr_SetString(PyExc_ValueError, "Invalid format string"); + return 0; + } + } #endif - fmtlen = time_strlen(fmt); - - /* I hate these functions that presume you know how big the output - * will be ahead of time... - */ - for (i = 1024; ; i += i) { - outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char)); - if (outbuf == NULL) { - Py_DECREF(format); - return PyErr_NoMemory(); - } - buflen = format_time(outbuf, i, fmt, &buf); - if (buflen > 0 || i >= 256 * fmtlen) { - /* If the buffer is 256 times as long as the format, - it's probably not failing for lack of room! - More likely, the format yields an empty result, - e.g. an empty format, or %Z when the timezone - is unknown. */ - PyObject *ret; + fmtlen = time_strlen(fmt); + + /* I hate these functions that presume you know how big the output + * will be ahead of time... + */ + for (i = 1024; ; i += i) { + outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char)); + if (outbuf == NULL) { + Py_DECREF(format); + return PyErr_NoMemory(); + } + buflen = format_time(outbuf, i, fmt, &buf); + if (buflen > 0 || i >= 256 * fmtlen) { + /* If the buffer is 256 times as long as the format, + it's probably not failing for lack of room! + More likely, the format yields an empty result, + e.g. an empty format, or %Z when the timezone + is unknown. */ + PyObject *ret; #ifdef HAVE_WCSFTIME - ret = PyUnicode_FromWideChar(outbuf, buflen); + ret = PyUnicode_FromWideChar(outbuf, buflen); #else - ret = PyUnicode_Decode(outbuf, buflen, - TZNAME_ENCODING, NULL); + ret = PyUnicode_Decode(outbuf, buflen, + TZNAME_ENCODING, NULL); #endif - PyMem_Free(outbuf); - Py_DECREF(format); - return ret; - } - PyMem_Free(outbuf); + PyMem_Free(outbuf); + Py_DECREF(format); + return ret; + } + PyMem_Free(outbuf); #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) - /* VisualStudio .NET 2005 does this properly */ - if (buflen == 0 && errno == EINVAL) { - PyErr_SetString(PyExc_ValueError, "Invalid format string"); - Py_DECREF(format); - return 0; - } + /* VisualStudio .NET 2005 does this properly */ + if (buflen == 0 && errno == EINVAL) { + PyErr_SetString(PyExc_ValueError, "Invalid format string"); + Py_DECREF(format); + return 0; + } #endif - } + } } #undef time_char @@ -614,15 +614,15 @@ is not present, current time as returned by localtime() is used."); static PyObject * time_strptime(PyObject *self, PyObject *args) { - PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime"); - PyObject *strptime_result; - - if (!strptime_module) - return NULL; - strptime_result = PyObject_CallMethod(strptime_module, - "_strptime_time", "O", args); - Py_DECREF(strptime_module); - return strptime_result; + PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime"); + PyObject *strptime_result; + + if (!strptime_module) + return NULL; + strptime_result = PyObject_CallMethod(strptime_module, + "_strptime_time", "O", args); + Py_DECREF(strptime_module); + return strptime_result; } PyDoc_STRVAR(strptime_doc, @@ -635,20 +635,20 @@ See the library reference manual for formatting codes (same as strftime())."); static PyObject * time_asctime(PyObject *self, PyObject *args) { - PyObject *tup = NULL; - struct tm buf; - char *p; - if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) - return NULL; - if (tup == NULL) { - time_t tt = time(NULL); - buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf)) - return NULL; - p = asctime(&buf); - if (p[24] == '\n') - p[24] = '\0'; - return PyUnicode_FromString(p); + PyObject *tup = NULL; + struct tm buf; + char *p; + if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) + return NULL; + if (tup == NULL) { + time_t tt = time(NULL); + buf = *localtime(&tt); + } else if (!gettmarg(tup, &buf)) + return NULL; + p = asctime(&buf); + if (p[24] == '\n') + p[24] = '\0'; + return PyUnicode_FromString(p); } PyDoc_STRVAR(asctime_doc, @@ -661,30 +661,30 @@ is used."); static PyObject * time_ctime(PyObject *self, PyObject *args) { - PyObject *ot = NULL; - time_t tt; - char *p; - - if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot)) - return NULL; - if (ot == NULL || ot == Py_None) - tt = time(NULL); - else { - double dt = PyFloat_AsDouble(ot); - if (PyErr_Occurred()) - return NULL; - tt = _PyTime_DoubleToTimet(dt); - if (tt == (time_t)-1 && PyErr_Occurred()) - return NULL; - } - p = ctime(&tt); - if (p == NULL) { - PyErr_SetString(PyExc_ValueError, "unconvertible time"); - return NULL; - } - if (p[24] == '\n') - p[24] = '\0'; - return PyUnicode_FromString(p); + PyObject *ot = NULL; + time_t tt; + char *p; + + if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot)) + return NULL; + if (ot == NULL || ot == Py_None) + tt = time(NULL); + else { + double dt = PyFloat_AsDouble(ot); + if (PyErr_Occurred()) + return NULL; + tt = _PyTime_DoubleToTimet(dt); + if (tt == (time_t)-1 && PyErr_Occurred()) + return NULL; + } + p = ctime(&tt); + if (p == NULL) { + PyErr_SetString(PyExc_ValueError, "unconvertible time"); + return NULL; + } + if (p[24] == '\n') + p[24] = '\0'; + return PyUnicode_FromString(p); } PyDoc_STRVAR(ctime_doc, @@ -698,17 +698,17 @@ not present, current time as returned by localtime() is used."); static PyObject * time_mktime(PyObject *self, PyObject *tup) { - struct tm buf; - time_t tt; - if (!gettmarg(tup, &buf)) - return NULL; - tt = mktime(&buf); - if (tt == (time_t)(-1)) { - PyErr_SetString(PyExc_OverflowError, - "mktime argument out of range"); - return NULL; - } - return PyFloat_FromDouble((double)tt); + struct tm buf; + time_t tt; + if (!gettmarg(tup, &buf)) + return NULL; + tt = mktime(&buf); + if (tt == (time_t)(-1)) { + PyErr_SetString(PyExc_OverflowError, + "mktime argument out of range"); + return NULL; + } + return PyFloat_FromDouble((double)tt); } PyDoc_STRVAR(mktime_doc, @@ -723,21 +723,21 @@ static void PyInit_timezone(PyObject *module); static PyObject * time_tzset(PyObject *self, PyObject *unused) { - PyObject* m; + PyObject* m; - m = PyImport_ImportModuleNoBlock("time"); - if (m == NULL) { - return NULL; - } + m = PyImport_ImportModuleNoBlock("time"); + if (m == NULL) { + return NULL; + } - tzset(); + tzset(); - /* Reset timezone, altzone, daylight and tzname */ - PyInit_timezone(m); - Py_DECREF(m); + /* Reset timezone, altzone, daylight and tzname */ + PyInit_timezone(m); + Py_DECREF(m); - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(tzset_doc, @@ -757,115 +757,115 @@ should not be relied on."); static void PyInit_timezone(PyObject *m) { /* This code moved from PyInit_time wholesale to allow calling it from - time_tzset. In the future, some parts of it can be moved back - (for platforms that don't HAVE_WORKING_TZSET, when we know what they - are), and the extraneous calls to tzset(3) should be removed. - I haven't done this yet, as I don't want to change this code as - little as possible when introducing the time.tzset and time.tzsetwall - methods. This should simply be a method of doing the following once, - at the top of this function and removing the call to tzset() from - time_tzset(): - - #ifdef HAVE_TZSET - tzset() - #endif - - And I'm lazy and hate C so nyer. + time_tzset. In the future, some parts of it can be moved back + (for platforms that don't HAVE_WORKING_TZSET, when we know what they + are), and the extraneous calls to tzset(3) should be removed. + I haven't done this yet, as I don't want to change this code as + little as possible when introducing the time.tzset and time.tzsetwall + methods. This should simply be a method of doing the following once, + at the top of this function and removing the call to tzset() from + time_tzset(): + + #ifdef HAVE_TZSET + tzset() + #endif + + And I'm lazy and hate C so nyer. */ #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__) - PyObject *otz0, *otz1; - tzset(); + PyObject *otz0, *otz1; + tzset(); #ifdef PYOS_OS2 - PyModule_AddIntConstant(m, "timezone", _timezone); + PyModule_AddIntConstant(m, "timezone", _timezone); #else /* !PYOS_OS2 */ - PyModule_AddIntConstant(m, "timezone", timezone); + PyModule_AddIntConstant(m, "timezone", timezone); #endif /* PYOS_OS2 */ #ifdef HAVE_ALTZONE - PyModule_AddIntConstant(m, "altzone", altzone); + PyModule_AddIntConstant(m, "altzone", altzone); #else #ifdef PYOS_OS2 - PyModule_AddIntConstant(m, "altzone", _timezone-3600); + PyModule_AddIntConstant(m, "altzone", _timezone-3600); #else /* !PYOS_OS2 */ - PyModule_AddIntConstant(m, "altzone", timezone-3600); + PyModule_AddIntConstant(m, "altzone", timezone-3600); #endif /* PYOS_OS2 */ #endif - PyModule_AddIntConstant(m, "daylight", daylight); - otz0 = PyUnicode_Decode(tzname[0], strlen(tzname[0]), TZNAME_ENCODING, NULL); - otz1 = PyUnicode_Decode(tzname[1], strlen(tzname[1]), TZNAME_ENCODING, NULL); - PyModule_AddObject(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)); + PyModule_AddIntConstant(m, "daylight", daylight); + otz0 = PyUnicode_Decode(tzname[0], strlen(tzname[0]), TZNAME_ENCODING, NULL); + otz1 = PyUnicode_Decode(tzname[1], strlen(tzname[1]), TZNAME_ENCODING, NULL); + PyModule_AddObject(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)); #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ #ifdef HAVE_STRUCT_TM_TM_ZONE - { + { #define YEAR ((time_t)((365 * 24 + 6) * 3600)) - time_t t; - struct tm *p; - long janzone, julyzone; - char janname[10], julyname[10]; - t = (time((time_t *)0) / YEAR) * YEAR; - p = localtime(&t); - janzone = -p->tm_gmtoff; - strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9); - janname[9] = '\0'; - t += YEAR/2; - p = localtime(&t); - julyzone = -p->tm_gmtoff; - strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9); - julyname[9] = '\0'; - - if( janzone < julyzone ) { - /* DST is reversed in the southern hemisphere */ - PyModule_AddIntConstant(m, "timezone", julyzone); - PyModule_AddIntConstant(m, "altzone", janzone); - PyModule_AddIntConstant(m, "daylight", - janzone != julyzone); - PyModule_AddObject(m, "tzname", - Py_BuildValue("(zz)", - julyname, janname)); - } else { - PyModule_AddIntConstant(m, "timezone", janzone); - PyModule_AddIntConstant(m, "altzone", julyzone); - PyModule_AddIntConstant(m, "daylight", - janzone != julyzone); - PyModule_AddObject(m, "tzname", - Py_BuildValue("(zz)", - janname, julyname)); - } - } + time_t t; + struct tm *p; + long janzone, julyzone; + char janname[10], julyname[10]; + t = (time((time_t *)0) / YEAR) * YEAR; + p = localtime(&t); + janzone = -p->tm_gmtoff; + strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9); + janname[9] = '\0'; + t += YEAR/2; + p = localtime(&t); + julyzone = -p->tm_gmtoff; + strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9); + julyname[9] = '\0'; + + if( janzone < julyzone ) { + /* DST is reversed in the southern hemisphere */ + PyModule_AddIntConstant(m, "timezone", julyzone); + PyModule_AddIntConstant(m, "altzone", janzone); + PyModule_AddIntConstant(m, "daylight", + janzone != julyzone); + PyModule_AddObject(m, "tzname", + Py_BuildValue("(zz)", + julyname, janname)); + } else { + PyModule_AddIntConstant(m, "timezone", janzone); + PyModule_AddIntConstant(m, "altzone", julyzone); + PyModule_AddIntConstant(m, "daylight", + janzone != julyzone); + PyModule_AddObject(m, "tzname", + Py_BuildValue("(zz)", + janname, julyname)); + } + } #else #endif /* HAVE_STRUCT_TM_TM_ZONE */ #ifdef __CYGWIN__ - tzset(); - PyModule_AddIntConstant(m, "timezone", _timezone); - PyModule_AddIntConstant(m, "altzone", _timezone-3600); - PyModule_AddIntConstant(m, "daylight", _daylight); - PyModule_AddObject(m, "tzname", - Py_BuildValue("(zz)", _tzname[0], _tzname[1])); + tzset(); + PyModule_AddIntConstant(m, "timezone", _timezone); + PyModule_AddIntConstant(m, "altzone", _timezone-3600); + PyModule_AddIntConstant(m, "daylight", _daylight); + PyModule_AddObject(m, "tzname", + Py_BuildValue("(zz)", _tzname[0], _tzname[1])); #endif /* __CYGWIN__ */ #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ } static PyMethodDef time_methods[] = { - {"time", time_time, METH_NOARGS, time_doc}, + {"time", time_time, METH_NOARGS, time_doc}, #ifdef HAVE_CLOCK - {"clock", time_clock, METH_NOARGS, clock_doc}, + {"clock", time_clock, METH_NOARGS, clock_doc}, #endif - {"sleep", time_sleep, METH_VARARGS, sleep_doc}, - {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, - {"localtime", time_localtime, METH_VARARGS, localtime_doc}, - {"asctime", time_asctime, METH_VARARGS, asctime_doc}, - {"ctime", time_ctime, METH_VARARGS, ctime_doc}, + {"sleep", time_sleep, METH_VARARGS, sleep_doc}, + {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, + {"localtime", time_localtime, METH_VARARGS, localtime_doc}, + {"asctime", time_asctime, METH_VARARGS, asctime_doc}, + {"ctime", time_ctime, METH_VARARGS, ctime_doc}, #ifdef HAVE_MKTIME - {"mktime", time_mktime, METH_O, mktime_doc}, + {"mktime", time_mktime, METH_O, mktime_doc}, #endif #ifdef HAVE_STRFTIME - {"strftime", time_strftime, METH_VARARGS, strftime_doc}, + {"strftime", time_strftime, METH_VARARGS, strftime_doc}, #endif - {"strptime", time_strptime, METH_VARARGS, strptime_doc}, + {"strptime", time_strptime, METH_VARARGS, strptime_doc}, #ifdef HAVE_WORKING_TZSET - {"tzset", time_tzset, METH_NOARGS, tzset_doc}, + {"tzset", time_tzset, METH_NOARGS, tzset_doc}, #endif - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; @@ -917,53 +917,53 @@ tzset() -- change the local timezone"); static struct PyModuleDef timemodule = { - PyModuleDef_HEAD_INIT, - "time", - module_doc, - -1, - time_methods, - NULL, - NULL, - NULL, - NULL + PyModuleDef_HEAD_INIT, + "time", + module_doc, + -1, + time_methods, + NULL, + NULL, + NULL, + NULL }; PyMODINIT_FUNC PyInit_time(void) { - PyObject *m; - char *p; - m = PyModule_Create(&timemodule); - if (m == NULL) - return NULL; - - /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */ - p = Py_GETENV("PYTHONY2K"); - PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p)); - /* Squirrel away the module's dictionary for the y2k check */ - moddict = PyModule_GetDict(m); - Py_INCREF(moddict); - - /* Set, or reset, module variables like time.timezone */ - PyInit_timezone(m); + PyObject *m; + char *p; + m = PyModule_Create(&timemodule); + if (m == NULL) + return NULL; + + /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */ + p = Py_GETENV("PYTHONY2K"); + PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p)); + /* Squirrel away the module's dictionary for the y2k check */ + moddict = PyModule_GetDict(m); + Py_INCREF(moddict); + + /* Set, or reset, module variables like time.timezone */ + PyInit_timezone(m); #ifdef MS_WINDOWS - /* Helper to allow interrupts for Windows. - If Ctrl+C event delivered while not sleeping - it will be ignored. - */ - main_thread = PyThread_get_thread_ident(); - hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - SetConsoleCtrlHandler( PyCtrlHandler, TRUE); + /* Helper to allow interrupts for Windows. + If Ctrl+C event delivered while not sleeping + it will be ignored. + */ + main_thread = PyThread_get_thread_ident(); + hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + SetConsoleCtrlHandler( PyCtrlHandler, TRUE); #endif /* MS_WINDOWS */ - if (!initialized) { - PyStructSequence_InitType(&StructTimeType, - &struct_time_type_desc); - } - Py_INCREF(&StructTimeType); - PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType); - initialized = 1; - return m; + if (!initialized) { + PyStructSequence_InitType(&StructTimeType, + &struct_time_type_desc); + } + Py_INCREF(&StructTimeType); + PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType); + initialized = 1; + return m; } @@ -972,38 +972,38 @@ PyInit_time(void) static double floattime(void) { - /* There are three ways to get the time: - (1) gettimeofday() -- resolution in microseconds - (2) ftime() -- resolution in milliseconds - (3) time() -- resolution in seconds - In all cases the return value is a float in seconds. - Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may - fail, so we fall back on ftime() or time(). - Note: clock resolution does not imply clock accuracy! */ + /* There are three ways to get the time: + (1) gettimeofday() -- resolution in microseconds + (2) ftime() -- resolution in milliseconds + (3) time() -- resolution in seconds + In all cases the return value is a float in seconds. + Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may + fail, so we fall back on ftime() or time(). + Note: clock resolution does not imply clock accuracy! */ #ifdef HAVE_GETTIMEOFDAY - { - struct timeval t; + { + struct timeval t; #ifdef GETTIMEOFDAY_NO_TZ - if (gettimeofday(&t) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; + if (gettimeofday(&t) == 0) + return (double)t.tv_sec + t.tv_usec*0.000001; #else /* !GETTIMEOFDAY_NO_TZ */ - if (gettimeofday(&t, (struct timezone *)NULL) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; + if (gettimeofday(&t, (struct timezone *)NULL) == 0) + return (double)t.tv_sec + t.tv_usec*0.000001; #endif /* !GETTIMEOFDAY_NO_TZ */ - } + } #endif /* !HAVE_GETTIMEOFDAY */ - { + { #if defined(HAVE_FTIME) - struct timeb t; - ftime(&t); - return (double)t.time + (double)t.millitm * (double)0.001; + struct timeb t; + ftime(&t); + return (double)t.time + (double)t.millitm * (double)0.001; #else /* !HAVE_FTIME */ - time_t secs; - time(&secs); - return (double)secs; + time_t secs; + time(&secs); + return (double)secs; #endif /* !HAVE_FTIME */ - } + } } @@ -1016,80 +1016,80 @@ floatsleep(double secs) { /* XXX Should test for MS_WINDOWS first! */ #if defined(HAVE_SELECT) && !defined(__EMX__) - struct timeval t; - double frac; - frac = fmod(secs, 1.0); - secs = floor(secs); - t.tv_sec = (long)secs; - t.tv_usec = (long)(frac*1000000.0); - Py_BEGIN_ALLOW_THREADS - if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) { + struct timeval t; + double frac; + frac = fmod(secs, 1.0); + secs = floor(secs); + t.tv_sec = (long)secs; + t.tv_usec = (long)(frac*1000000.0); + Py_BEGIN_ALLOW_THREADS + if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) { #ifdef EINTR - if (errno != EINTR) { + if (errno != EINTR) { #else - if (1) { + if (1) { #endif - Py_BLOCK_THREADS - PyErr_SetFromErrno(PyExc_IOError); - return -1; - } - } - Py_END_ALLOW_THREADS + Py_BLOCK_THREADS + PyErr_SetFromErrno(PyExc_IOError); + return -1; + } + } + Py_END_ALLOW_THREADS #elif defined(__WATCOMC__) && !defined(__QNX__) - /* XXX Can't interrupt this sleep */ - Py_BEGIN_ALLOW_THREADS - delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */ - Py_END_ALLOW_THREADS + /* XXX Can't interrupt this sleep */ + Py_BEGIN_ALLOW_THREADS + delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */ + Py_END_ALLOW_THREADS #elif defined(MS_WINDOWS) - { - double millisecs = secs * 1000.0; - unsigned long ul_millis; - - if (millisecs > (double)ULONG_MAX) { - PyErr_SetString(PyExc_OverflowError, - "sleep length is too large"); - return -1; - } - Py_BEGIN_ALLOW_THREADS - /* Allow sleep(0) to maintain win32 semantics, and as decreed - * by Guido, only the main thread can be interrupted. - */ - ul_millis = (unsigned long)millisecs; - if (ul_millis == 0 || - main_thread != PyThread_get_thread_ident()) - Sleep(ul_millis); - else { - DWORD rc; - ResetEvent(hInterruptEvent); - rc = WaitForSingleObject(hInterruptEvent, ul_millis); - if (rc == WAIT_OBJECT_0) { - /* Yield to make sure real Python signal - * handler called. - */ - Sleep(1); - Py_BLOCK_THREADS - errno = EINTR; - PyErr_SetFromErrno(PyExc_IOError); - return -1; - } - } - Py_END_ALLOW_THREADS - } + { + double millisecs = secs * 1000.0; + unsigned long ul_millis; + + if (millisecs > (double)ULONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "sleep length is too large"); + return -1; + } + Py_BEGIN_ALLOW_THREADS + /* Allow sleep(0) to maintain win32 semantics, and as decreed + * by Guido, only the main thread can be interrupted. + */ + ul_millis = (unsigned long)millisecs; + if (ul_millis == 0 || + main_thread != PyThread_get_thread_ident()) + Sleep(ul_millis); + else { + DWORD rc; + ResetEvent(hInterruptEvent); + rc = WaitForSingleObject(hInterruptEvent, ul_millis); + if (rc == WAIT_OBJECT_0) { + /* Yield to make sure real Python signal + * handler called. + */ + Sleep(1); + Py_BLOCK_THREADS + errno = EINTR; + PyErr_SetFromErrno(PyExc_IOError); + return -1; + } + } + Py_END_ALLOW_THREADS + } #elif defined(PYOS_OS2) - /* This Sleep *IS* Interruptable by Exceptions */ - Py_BEGIN_ALLOW_THREADS - if (DosSleep(secs * 1000) != NO_ERROR) { - Py_BLOCK_THREADS - PyErr_SetFromErrno(PyExc_IOError); - return -1; - } - Py_END_ALLOW_THREADS + /* This Sleep *IS* Interruptable by Exceptions */ + Py_BEGIN_ALLOW_THREADS + if (DosSleep(secs * 1000) != NO_ERROR) { + Py_BLOCK_THREADS + PyErr_SetFromErrno(PyExc_IOError); + return -1; + } + Py_END_ALLOW_THREADS #else - /* XXX Can't interrupt this sleep */ - Py_BEGIN_ALLOW_THREADS - sleep((int)secs); - Py_END_ALLOW_THREADS + /* XXX Can't interrupt this sleep */ + Py_BEGIN_ALLOW_THREADS + sleep((int)secs); + Py_END_ALLOW_THREADS #endif - return 0; + return 0; } |