]>
Commit | Line | Data |
---|---|---|
7eb75bcc DM |
1 | \r |
2 | /* Time module */\r | |
3 | \r | |
4 | #include "Python.h"\r | |
5 | #include "structseq.h"\r | |
6 | #include "timefuncs.h"\r | |
7 | \r | |
8 | #ifdef __APPLE__\r | |
9 | #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)\r | |
10 | /*\r | |
11 | * floattime falls back to ftime when getttimeofday fails because the latter\r | |
12 | * might fail on some platforms. This fallback is unwanted on MacOSX because\r | |
13 | * that makes it impossible to use a binary build on OSX 10.4 on earlier\r | |
14 | * releases of the OS. Therefore claim we don't support ftime.\r | |
15 | */\r | |
16 | # undef HAVE_FTIME\r | |
17 | #endif\r | |
18 | #endif\r | |
19 | \r | |
20 | #include <ctype.h>\r | |
21 | \r | |
22 | #ifdef HAVE_SYS_TYPES_H\r | |
23 | #include <sys/types.h>\r | |
24 | #endif /* HAVE_SYS_TYPES_H */\r | |
25 | \r | |
26 | #ifdef QUICKWIN\r | |
27 | #include <io.h>\r | |
28 | #endif\r | |
29 | \r | |
30 | #ifdef HAVE_FTIME\r | |
31 | #include <sys/timeb.h>\r | |
32 | #if !defined(MS_WINDOWS) && !defined(PYOS_OS2)\r | |
33 | extern int ftime(struct timeb *);\r | |
34 | #endif /* MS_WINDOWS */\r | |
35 | #endif /* HAVE_FTIME */\r | |
36 | \r | |
37 | #if defined(__WATCOMC__) && !defined(__QNX__)\r | |
38 | #include <i86.h>\r | |
39 | #else\r | |
40 | #ifdef MS_WINDOWS\r | |
41 | #define WIN32_LEAN_AND_MEAN\r | |
42 | #include <windows.h>\r | |
43 | #include "pythread.h"\r | |
44 | \r | |
45 | /* helper to allow us to interrupt sleep() on Windows*/\r | |
46 | static HANDLE hInterruptEvent = NULL;\r | |
47 | static BOOL WINAPI PyCtrlHandler(DWORD dwCtrlType)\r | |
48 | {\r | |
49 | SetEvent(hInterruptEvent);\r | |
50 | /* allow other default handlers to be called.\r | |
51 | Default Python handler will setup the\r | |
52 | KeyboardInterrupt exception.\r | |
53 | */\r | |
54 | return FALSE;\r | |
55 | }\r | |
56 | static long main_thread;\r | |
57 | \r | |
58 | \r | |
59 | #if defined(__BORLANDC__)\r | |
60 | /* These overrides not needed for Win32 */\r | |
61 | #define timezone _timezone\r | |
62 | #define tzname _tzname\r | |
63 | #define daylight _daylight\r | |
64 | #endif /* __BORLANDC__ */\r | |
65 | #endif /* MS_WINDOWS */\r | |
66 | #endif /* !__WATCOMC__ || __QNX__ */\r | |
67 | \r | |
68 | #if defined(MS_WINDOWS) && !defined(__BORLANDC__)\r | |
69 | /* Win32 has better clock replacement; we have our own version below. */\r | |
70 | #undef HAVE_CLOCK\r | |
71 | #endif /* MS_WINDOWS && !defined(__BORLANDC__) */\r | |
72 | \r | |
73 | #if defined(PYOS_OS2)\r | |
74 | #define INCL_DOS\r | |
75 | #define INCL_ERRORS\r | |
76 | #include <os2.h>\r | |
77 | #endif\r | |
78 | \r | |
79 | #if defined(PYCC_VACPP)\r | |
80 | #include <sys/time.h>\r | |
81 | #endif\r | |
82 | \r | |
83 | #ifdef __BEOS__\r | |
84 | #include <time.h>\r | |
85 | /* For bigtime_t, snooze(). - [cjh] */\r | |
86 | #include <support/SupportDefs.h>\r | |
87 | #include <kernel/OS.h>\r | |
88 | #endif\r | |
89 | \r | |
90 | #ifdef RISCOS\r | |
91 | extern int riscos_sleep(double);\r | |
92 | #endif\r | |
93 | \r | |
94 | /* Forward declarations */\r | |
95 | static int floatsleep(double);\r | |
96 | static double floattime(void);\r | |
97 | \r | |
98 | /* For Y2K check */\r | |
99 | static PyObject *moddict = NULL;\r | |
100 | \r | |
101 | /* Exposed in timefuncs.h. */\r | |
102 | time_t\r | |
103 | _PyTime_DoubleToTimet(double x)\r | |
104 | {\r | |
105 | time_t result;\r | |
106 | double diff;\r | |
107 | \r | |
108 | result = (time_t)x;\r | |
109 | /* How much info did we lose? time_t may be an integral or\r | |
110 | * floating type, and we don't know which. If it's integral,\r | |
111 | * we don't know whether C truncates, rounds, returns the floor,\r | |
112 | * etc. If we lost a second or more, the C rounding is\r | |
113 | * unreasonable, or the input just doesn't fit in a time_t;\r | |
114 | * call it an error regardless. Note that the original cast to\r | |
115 | * time_t can cause a C error too, but nothing we can do to\r | |
116 | * worm around that.\r | |
117 | */\r | |
118 | diff = x - (double)result;\r | |
119 | if (diff <= -1.0 || diff >= 1.0) {\r | |
120 | PyErr_SetString(PyExc_ValueError,\r | |
121 | "timestamp out of range for platform time_t");\r | |
122 | result = (time_t)-1;\r | |
123 | }\r | |
124 | return result;\r | |
125 | }\r | |
126 | \r | |
127 | static PyObject *\r | |
128 | time_time(PyObject *self, PyObject *unused)\r | |
129 | {\r | |
130 | double secs;\r | |
131 | secs = floattime();\r | |
132 | if (secs == 0.0) {\r | |
133 | PyErr_SetFromErrno(PyExc_IOError);\r | |
134 | return NULL;\r | |
135 | }\r | |
136 | return PyFloat_FromDouble(secs);\r | |
137 | }\r | |
138 | \r | |
139 | PyDoc_STRVAR(time_doc,\r | |
140 | "time() -> floating point number\n\\r | |
141 | \n\\r | |
142 | Return the current time in seconds since the Epoch.\n\\r | |
143 | Fractions of a second may be present if the system clock provides them.");\r | |
144 | \r | |
145 | #ifdef HAVE_CLOCK\r | |
146 | \r | |
147 | #ifndef CLOCKS_PER_SEC\r | |
148 | #ifdef CLK_TCK\r | |
149 | #define CLOCKS_PER_SEC CLK_TCK\r | |
150 | #else\r | |
151 | #define CLOCKS_PER_SEC 1000000\r | |
152 | #endif\r | |
153 | #endif\r | |
154 | \r | |
155 | static PyObject *\r | |
156 | time_clock(PyObject *self, PyObject *unused)\r | |
157 | {\r | |
158 | return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);\r | |
159 | }\r | |
160 | #endif /* HAVE_CLOCK */\r | |
161 | \r | |
162 | #if defined(MS_WINDOWS) && !defined(__BORLANDC__)\r | |
163 | /* Due to Mark Hammond and Tim Peters */\r | |
164 | static PyObject *\r | |
165 | time_clock(PyObject *self, PyObject *unused)\r | |
166 | {\r | |
167 | static LARGE_INTEGER ctrStart;\r | |
168 | static double divisor = 0.0;\r | |
169 | LARGE_INTEGER now;\r | |
170 | double diff;\r | |
171 | \r | |
172 | if (divisor == 0.0) {\r | |
173 | LARGE_INTEGER freq;\r | |
174 | QueryPerformanceCounter(&ctrStart);\r | |
175 | if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) {\r | |
176 | /* Unlikely to happen - this works on all intel\r | |
177 | machines at least! Revert to clock() */\r | |
178 | return PyFloat_FromDouble(((double)clock()) /\r | |
179 | CLOCKS_PER_SEC);\r | |
180 | }\r | |
181 | divisor = (double)freq.QuadPart;\r | |
182 | }\r | |
183 | QueryPerformanceCounter(&now);\r | |
184 | diff = (double)(now.QuadPart - ctrStart.QuadPart);\r | |
185 | return PyFloat_FromDouble(diff / divisor);\r | |
186 | }\r | |
187 | \r | |
188 | #define HAVE_CLOCK /* So it gets included in the methods */\r | |
189 | #endif /* MS_WINDOWS && !defined(__BORLANDC__) */\r | |
190 | \r | |
191 | #ifdef HAVE_CLOCK\r | |
192 | PyDoc_STRVAR(clock_doc,\r | |
193 | "clock() -> floating point number\n\\r | |
194 | \n\\r | |
195 | Return the CPU time or real time since the start of the process or since\n\\r | |
196 | the first call to clock(). This has as much precision as the system\n\\r | |
197 | records.");\r | |
198 | #endif\r | |
199 | \r | |
200 | static PyObject *\r | |
201 | time_sleep(PyObject *self, PyObject *args)\r | |
202 | {\r | |
203 | double secs;\r | |
204 | if (!PyArg_ParseTuple(args, "d:sleep", &secs))\r | |
205 | return NULL;\r | |
206 | if (floatsleep(secs) != 0)\r | |
207 | return NULL;\r | |
208 | Py_INCREF(Py_None);\r | |
209 | return Py_None;\r | |
210 | }\r | |
211 | \r | |
212 | PyDoc_STRVAR(sleep_doc,\r | |
213 | "sleep(seconds)\n\\r | |
214 | \n\\r | |
215 | Delay execution for a given number of seconds. The argument may be\n\\r | |
216 | a floating point number for subsecond precision.");\r | |
217 | \r | |
218 | static PyStructSequence_Field struct_time_type_fields[] = {\r | |
219 | {"tm_year", "year, for example, 1993"},\r | |
220 | {"tm_mon", "month of year, range [1, 12]"},\r | |
221 | {"tm_mday", "day of month, range [1, 31]"},\r | |
222 | {"tm_hour", "hours, range [0, 23]"},\r | |
223 | {"tm_min", "minutes, range [0, 59]"},\r | |
224 | {"tm_sec", "seconds, range [0, 61])"},\r | |
225 | {"tm_wday", "day of week, range [0, 6], Monday is 0"},\r | |
226 | {"tm_yday", "day of year, range [1, 366]"},\r | |
227 | {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"},\r | |
228 | {0}\r | |
229 | };\r | |
230 | \r | |
231 | static PyStructSequence_Desc struct_time_type_desc = {\r | |
232 | "time.struct_time",\r | |
233 | "The time value as returned by gmtime(), localtime(), and strptime(), and\n"\r | |
234 | " accepted by asctime(), mktime() and strftime(). May be considered as a\n"\r | |
235 | " sequence of 9 integers.\n\n"\r | |
236 | " Note that several fields' values are not the same as those defined by\n"\r | |
237 | " the C language standard for struct tm. For example, the value of the\n"\r | |
238 | " field tm_year is the actual year, not year - 1900. See individual\n"\r | |
239 | " fields' descriptions for details.",\r | |
240 | struct_time_type_fields,\r | |
241 | 9,\r | |
242 | };\r | |
243 | \r | |
244 | static int initialized;\r | |
245 | static PyTypeObject StructTimeType;\r | |
246 | \r | |
247 | static PyObject *\r | |
248 | tmtotuple(struct tm *p)\r | |
249 | {\r | |
250 | PyObject *v = PyStructSequence_New(&StructTimeType);\r | |
251 | if (v == NULL)\r | |
252 | return NULL;\r | |
253 | \r | |
254 | #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))\r | |
255 | \r | |
256 | SET(0, p->tm_year + 1900);\r | |
257 | SET(1, p->tm_mon + 1); /* Want January == 1 */\r | |
258 | SET(2, p->tm_mday);\r | |
259 | SET(3, p->tm_hour);\r | |
260 | SET(4, p->tm_min);\r | |
261 | SET(5, p->tm_sec);\r | |
262 | SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */\r | |
263 | SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */\r | |
264 | SET(8, p->tm_isdst);\r | |
265 | #undef SET\r | |
266 | if (PyErr_Occurred()) {\r | |
267 | Py_XDECREF(v);\r | |
268 | return NULL;\r | |
269 | }\r | |
270 | \r | |
271 | return v;\r | |
272 | }\r | |
273 | \r | |
274 | static PyObject *\r | |
275 | time_convert(double when, struct tm * (*function)(const time_t *))\r | |
276 | {\r | |
277 | struct tm *p;\r | |
278 | time_t whent = _PyTime_DoubleToTimet(when);\r | |
279 | \r | |
280 | if (whent == (time_t)-1 && PyErr_Occurred())\r | |
281 | return NULL;\r | |
282 | errno = 0;\r | |
283 | p = function(&whent);\r | |
284 | if (p == NULL) {\r | |
285 | #ifdef EINVAL\r | |
286 | if (errno == 0)\r | |
287 | errno = EINVAL;\r | |
288 | #endif\r | |
289 | return PyErr_SetFromErrno(PyExc_ValueError);\r | |
290 | }\r | |
291 | return tmtotuple(p);\r | |
292 | }\r | |
293 | \r | |
294 | /* Parse arg tuple that can contain an optional float-or-None value;\r | |
295 | format needs to be "|O:name".\r | |
296 | Returns non-zero on success (parallels PyArg_ParseTuple).\r | |
297 | */\r | |
298 | static int\r | |
299 | parse_time_double_args(PyObject *args, char *format, double *pwhen)\r | |
300 | {\r | |
301 | PyObject *ot = NULL;\r | |
302 | \r | |
303 | if (!PyArg_ParseTuple(args, format, &ot))\r | |
304 | return 0;\r | |
305 | if (ot == NULL || ot == Py_None)\r | |
306 | *pwhen = floattime();\r | |
307 | else {\r | |
308 | double when = PyFloat_AsDouble(ot);\r | |
309 | if (PyErr_Occurred())\r | |
310 | return 0;\r | |
311 | *pwhen = when;\r | |
312 | }\r | |
313 | return 1;\r | |
314 | }\r | |
315 | \r | |
316 | static PyObject *\r | |
317 | time_gmtime(PyObject *self, PyObject *args)\r | |
318 | {\r | |
319 | double when;\r | |
320 | if (!parse_time_double_args(args, "|O:gmtime", &when))\r | |
321 | return NULL;\r | |
322 | return time_convert(when, gmtime);\r | |
323 | }\r | |
324 | \r | |
325 | PyDoc_STRVAR(gmtime_doc,\r | |
326 | "gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\\r | |
327 | tm_sec, tm_wday, tm_yday, tm_isdst)\n\\r | |
328 | \n\\r | |
329 | Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\\r | |
330 | GMT). When 'seconds' is not passed in, convert the current time instead.");\r | |
331 | \r | |
332 | static PyObject *\r | |
333 | time_localtime(PyObject *self, PyObject *args)\r | |
334 | {\r | |
335 | double when;\r | |
336 | if (!parse_time_double_args(args, "|O:localtime", &when))\r | |
337 | return NULL;\r | |
338 | return time_convert(when, localtime);\r | |
339 | }\r | |
340 | \r | |
341 | PyDoc_STRVAR(localtime_doc,\r | |
342 | "localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\\r | |
343 | tm_sec,tm_wday,tm_yday,tm_isdst)\n\\r | |
344 | \n\\r | |
345 | Convert seconds since the Epoch to a time tuple expressing local time.\n\\r | |
346 | When 'seconds' is not passed in, convert the current time instead.");\r | |
347 | \r | |
348 | static int\r | |
349 | gettmarg(PyObject *args, struct tm *p)\r | |
350 | {\r | |
351 | int y;\r | |
352 | memset((void *) p, '\0', sizeof(struct tm));\r | |
353 | \r | |
354 | if (!PyArg_Parse(args, "(iiiiiiiii)",\r | |
355 | &y,\r | |
356 | &p->tm_mon,\r | |
357 | &p->tm_mday,\r | |
358 | &p->tm_hour,\r | |
359 | &p->tm_min,\r | |
360 | &p->tm_sec,\r | |
361 | &p->tm_wday,\r | |
362 | &p->tm_yday,\r | |
363 | &p->tm_isdst))\r | |
364 | return 0;\r | |
365 | if (y < 1900) {\r | |
366 | PyObject *accept = PyDict_GetItemString(moddict,\r | |
367 | "accept2dyear");\r | |
368 | if (accept == NULL || !PyInt_Check(accept) ||\r | |
369 | PyInt_AsLong(accept) == 0) {\r | |
370 | PyErr_SetString(PyExc_ValueError,\r | |
371 | "year >= 1900 required");\r | |
372 | return 0;\r | |
373 | }\r | |
374 | if (69 <= y && y <= 99)\r | |
375 | y += 1900;\r | |
376 | else if (0 <= y && y <= 68)\r | |
377 | y += 2000;\r | |
378 | else {\r | |
379 | PyErr_SetString(PyExc_ValueError,\r | |
380 | "year out of range");\r | |
381 | return 0;\r | |
382 | }\r | |
383 | }\r | |
384 | p->tm_year = y - 1900;\r | |
385 | p->tm_mon--;\r | |
386 | p->tm_wday = (p->tm_wday + 1) % 7;\r | |
387 | p->tm_yday--;\r | |
388 | return 1;\r | |
389 | }\r | |
390 | \r | |
391 | #ifdef HAVE_STRFTIME\r | |
392 | static PyObject *\r | |
393 | time_strftime(PyObject *self, PyObject *args)\r | |
394 | {\r | |
395 | PyObject *tup = NULL;\r | |
396 | struct tm buf;\r | |
397 | const char *fmt;\r | |
398 | size_t fmtlen, buflen;\r | |
399 | char *outbuf = 0;\r | |
400 | size_t i;\r | |
401 | \r | |
402 | memset((void *) &buf, '\0', sizeof(buf));\r | |
403 | \r | |
404 | if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup))\r | |
405 | return NULL;\r | |
406 | \r | |
407 | if (tup == NULL) {\r | |
408 | time_t tt = time(NULL);\r | |
409 | buf = *localtime(&tt);\r | |
410 | } else if (!gettmarg(tup, &buf))\r | |
411 | return NULL;\r | |
412 | \r | |
413 | /* Checks added to make sure strftime() does not crash Python by\r | |
414 | indexing blindly into some array for a textual representation\r | |
415 | by some bad index (fixes bug #897625).\r | |
416 | \r | |
417 | Also support values of zero from Python code for arguments in which\r | |
418 | that is out of range by forcing that value to the lowest value that\r | |
419 | is valid (fixed bug #1520914).\r | |
420 | \r | |
421 | Valid ranges based on what is allowed in struct tm:\r | |
422 | \r | |
423 | - tm_year: [0, max(int)] (1)\r | |
424 | - tm_mon: [0, 11] (2)\r | |
425 | - tm_mday: [1, 31]\r | |
426 | - tm_hour: [0, 23]\r | |
427 | - tm_min: [0, 59]\r | |
428 | - tm_sec: [0, 60]\r | |
429 | - tm_wday: [0, 6] (1)\r | |
430 | - tm_yday: [0, 365] (2)\r | |
431 | - tm_isdst: [-max(int), max(int)]\r | |
432 | \r | |
433 | (1) gettmarg() handles bounds-checking.\r | |
434 | (2) Python's acceptable range is one greater than the range in C,\r | |
435 | thus need to check against automatic decrement by gettmarg().\r | |
436 | */\r | |
437 | if (buf.tm_mon == -1)\r | |
438 | buf.tm_mon = 0;\r | |
439 | else if (buf.tm_mon < 0 || buf.tm_mon > 11) {\r | |
440 | PyErr_SetString(PyExc_ValueError, "month out of range");\r | |
441 | return NULL;\r | |
442 | }\r | |
443 | if (buf.tm_mday == 0)\r | |
444 | buf.tm_mday = 1;\r | |
445 | else if (buf.tm_mday < 0 || buf.tm_mday > 31) {\r | |
446 | PyErr_SetString(PyExc_ValueError, "day of month out of range");\r | |
447 | return NULL;\r | |
448 | }\r | |
449 | if (buf.tm_hour < 0 || buf.tm_hour > 23) {\r | |
450 | PyErr_SetString(PyExc_ValueError, "hour out of range");\r | |
451 | return NULL;\r | |
452 | }\r | |
453 | if (buf.tm_min < 0 || buf.tm_min > 59) {\r | |
454 | PyErr_SetString(PyExc_ValueError, "minute out of range");\r | |
455 | return NULL;\r | |
456 | }\r | |
457 | if (buf.tm_sec < 0 || buf.tm_sec > 61) {\r | |
458 | PyErr_SetString(PyExc_ValueError, "seconds out of range");\r | |
459 | return NULL;\r | |
460 | }\r | |
461 | /* tm_wday does not need checking of its upper-bound since taking\r | |
462 | ``% 7`` in gettmarg() automatically restricts the range. */\r | |
463 | if (buf.tm_wday < 0) {\r | |
464 | PyErr_SetString(PyExc_ValueError, "day of week out of range");\r | |
465 | return NULL;\r | |
466 | }\r | |
467 | if (buf.tm_yday == -1)\r | |
468 | buf.tm_yday = 0;\r | |
469 | else if (buf.tm_yday < 0 || buf.tm_yday > 365) {\r | |
470 | PyErr_SetString(PyExc_ValueError, "day of year out of range");\r | |
471 | return NULL;\r | |
472 | }\r | |
473 | /* Normalize tm_isdst just in case someone foolishly implements %Z\r | |
474 | based on the assumption that tm_isdst falls within the range of\r | |
475 | [-1, 1] */\r | |
476 | if (buf.tm_isdst < -1)\r | |
477 | buf.tm_isdst = -1;\r | |
478 | else if (buf.tm_isdst > 1)\r | |
479 | buf.tm_isdst = 1;\r | |
480 | \r | |
481 | #ifdef MS_WINDOWS\r | |
482 | /* check that the format string contains only valid directives */\r | |
483 | for(outbuf = strchr(fmt, '%');\r | |
484 | outbuf != NULL;\r | |
485 | outbuf = strchr(outbuf+2, '%'))\r | |
486 | {\r | |
487 | if (outbuf[1]=='#')\r | |
488 | ++outbuf; /* not documented by python, */\r | |
489 | if (outbuf[1]=='\0' ||\r | |
490 | !strchr("aAbBcdHIjmMpSUwWxXyYzZ%", outbuf[1]))\r | |
491 | {\r | |
492 | PyErr_SetString(PyExc_ValueError, "Invalid format string");\r | |
493 | return 0;\r | |
494 | }\r | |
495 | }\r | |
496 | #endif\r | |
497 | \r | |
498 | fmtlen = strlen(fmt);\r | |
499 | \r | |
500 | /* I hate these functions that presume you know how big the output\r | |
501 | * will be ahead of time...\r | |
502 | */\r | |
503 | for (i = 1024; ; i += i) {\r | |
504 | outbuf = (char *)malloc(i);\r | |
505 | if (outbuf == NULL) {\r | |
506 | return PyErr_NoMemory();\r | |
507 | }\r | |
508 | buflen = strftime(outbuf, i, fmt, &buf);\r | |
509 | if (buflen > 0 || i >= 256 * fmtlen) {\r | |
510 | /* If the buffer is 256 times as long as the format,\r | |
511 | it's probably not failing for lack of room!\r | |
512 | More likely, the format yields an empty result,\r | |
513 | e.g. an empty format, or %Z when the timezone\r | |
514 | is unknown. */\r | |
515 | PyObject *ret;\r | |
516 | ret = PyString_FromStringAndSize(outbuf, buflen);\r | |
517 | free(outbuf);\r | |
518 | return ret;\r | |
519 | }\r | |
520 | free(outbuf);\r | |
521 | #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)\r | |
522 | /* VisualStudio .NET 2005 does this properly */\r | |
523 | if (buflen == 0 && errno == EINVAL) {\r | |
524 | PyErr_SetString(PyExc_ValueError, "Invalid format string");\r | |
525 | return 0;\r | |
526 | }\r | |
527 | #endif\r | |
528 | \r | |
529 | }\r | |
530 | }\r | |
531 | \r | |
532 | PyDoc_STRVAR(strftime_doc,\r | |
533 | "strftime(format[, tuple]) -> string\n\\r | |
534 | \n\\r | |
535 | Convert a time tuple to a string according to a format specification.\n\\r | |
536 | See the library reference manual for formatting codes. When the time tuple\n\\r | |
537 | is not present, current time as returned by localtime() is used.");\r | |
538 | #endif /* HAVE_STRFTIME */\r | |
539 | \r | |
540 | static PyObject *\r | |
541 | time_strptime(PyObject *self, PyObject *args)\r | |
542 | {\r | |
543 | PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime");\r | |
544 | PyObject *strptime_result;\r | |
545 | \r | |
546 | if (!strptime_module)\r | |
547 | return NULL;\r | |
548 | strptime_result = PyObject_CallMethod(strptime_module,\r | |
549 | "_strptime_time", "O", args);\r | |
550 | Py_DECREF(strptime_module);\r | |
551 | return strptime_result;\r | |
552 | }\r | |
553 | \r | |
554 | PyDoc_STRVAR(strptime_doc,\r | |
555 | "strptime(string, format) -> struct_time\n\\r | |
556 | \n\\r | |
557 | Parse a string to a time tuple according to a format specification.\n\\r | |
558 | See the library reference manual for formatting codes (same as strftime()).");\r | |
559 | \r | |
560 | \r | |
561 | static PyObject *\r | |
562 | time_asctime(PyObject *self, PyObject *args)\r | |
563 | {\r | |
564 | PyObject *tup = NULL;\r | |
565 | struct tm buf;\r | |
566 | char *p;\r | |
567 | if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))\r | |
568 | return NULL;\r | |
569 | if (tup == NULL) {\r | |
570 | time_t tt = time(NULL);\r | |
571 | buf = *localtime(&tt);\r | |
572 | } else if (!gettmarg(tup, &buf))\r | |
573 | return NULL;\r | |
574 | p = asctime(&buf);\r | |
575 | if (p == NULL) {\r | |
576 | PyErr_SetString(PyExc_ValueError, "invalid time");\r | |
577 | return NULL;\r | |
578 | }\r | |
579 | if (p[24] == '\n')\r | |
580 | p[24] = '\0';\r | |
581 | return PyString_FromString(p);\r | |
582 | }\r | |
583 | \r | |
584 | PyDoc_STRVAR(asctime_doc,\r | |
585 | "asctime([tuple]) -> string\n\\r | |
586 | \n\\r | |
587 | Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\\r | |
588 | When the time tuple is not present, current time as returned by localtime()\n\\r | |
589 | is used.");\r | |
590 | \r | |
591 | static PyObject *\r | |
592 | time_ctime(PyObject *self, PyObject *args)\r | |
593 | {\r | |
594 | PyObject *ot = NULL;\r | |
595 | time_t tt;\r | |
596 | char *p;\r | |
597 | \r | |
598 | if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot))\r | |
599 | return NULL;\r | |
600 | if (ot == NULL || ot == Py_None)\r | |
601 | tt = time(NULL);\r | |
602 | else {\r | |
603 | double dt = PyFloat_AsDouble(ot);\r | |
604 | if (PyErr_Occurred())\r | |
605 | return NULL;\r | |
606 | tt = _PyTime_DoubleToTimet(dt);\r | |
607 | if (tt == (time_t)-1 && PyErr_Occurred())\r | |
608 | return NULL;\r | |
609 | }\r | |
610 | p = ctime(&tt);\r | |
611 | if (p == NULL) {\r | |
612 | PyErr_SetString(PyExc_ValueError, "unconvertible time");\r | |
613 | return NULL;\r | |
614 | }\r | |
615 | if (p[24] == '\n')\r | |
616 | p[24] = '\0';\r | |
617 | return PyString_FromString(p);\r | |
618 | }\r | |
619 | \r | |
620 | PyDoc_STRVAR(ctime_doc,\r | |
621 | "ctime(seconds) -> string\n\\r | |
622 | \n\\r | |
623 | Convert a time in seconds since the Epoch to a string in local time.\n\\r | |
624 | This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\\r | |
625 | not present, current time as returned by localtime() is used.");\r | |
626 | \r | |
627 | #ifdef HAVE_MKTIME\r | |
628 | static PyObject *\r | |
629 | time_mktime(PyObject *self, PyObject *tup)\r | |
630 | {\r | |
631 | struct tm buf;\r | |
632 | time_t tt;\r | |
633 | if (!gettmarg(tup, &buf))\r | |
634 | return NULL;\r | |
635 | buf.tm_wday = -1; /* sentinel; original value ignored */\r | |
636 | tt = mktime(&buf);\r | |
637 | /* Return value of -1 does not necessarily mean an error, but tm_wday\r | |
638 | * cannot remain set to -1 if mktime succeeded. */\r | |
639 | if (tt == (time_t)(-1) && buf.tm_wday == -1) {\r | |
640 | PyErr_SetString(PyExc_OverflowError,\r | |
641 | "mktime argument out of range");\r | |
642 | return NULL;\r | |
643 | }\r | |
644 | return PyFloat_FromDouble((double)tt);\r | |
645 | }\r | |
646 | \r | |
647 | PyDoc_STRVAR(mktime_doc,\r | |
648 | "mktime(tuple) -> floating point number\n\\r | |
649 | \n\\r | |
650 | Convert a time tuple in local time to seconds since the Epoch.");\r | |
651 | #endif /* HAVE_MKTIME */\r | |
652 | \r | |
653 | #ifdef HAVE_WORKING_TZSET\r | |
654 | static void inittimezone(PyObject *module);\r | |
655 | \r | |
656 | static PyObject *\r | |
657 | time_tzset(PyObject *self, PyObject *unused)\r | |
658 | {\r | |
659 | PyObject* m;\r | |
660 | \r | |
661 | m = PyImport_ImportModuleNoBlock("time");\r | |
662 | if (m == NULL) {\r | |
663 | return NULL;\r | |
664 | }\r | |
665 | \r | |
666 | tzset();\r | |
667 | \r | |
668 | /* Reset timezone, altzone, daylight and tzname */\r | |
669 | inittimezone(m);\r | |
670 | Py_DECREF(m);\r | |
671 | \r | |
672 | Py_INCREF(Py_None);\r | |
673 | return Py_None;\r | |
674 | }\r | |
675 | \r | |
676 | PyDoc_STRVAR(tzset_doc,\r | |
677 | "tzset()\n\\r | |
678 | \n\\r | |
679 | Initialize, or reinitialize, the local timezone to the value stored in\n\\r | |
680 | os.environ['TZ']. The TZ environment variable should be specified in\n\\r | |
681 | standard Unix timezone format as documented in the tzset man page\n\\r | |
682 | (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\\r | |
683 | fall back to UTC. If the TZ environment variable is not set, the local\n\\r | |
684 | timezone is set to the systems best guess of wallclock time.\n\\r | |
685 | Changing the TZ environment variable without calling tzset *may* change\n\\r | |
686 | the local timezone used by methods such as localtime, but this behaviour\n\\r | |
687 | should not be relied on.");\r | |
688 | #endif /* HAVE_WORKING_TZSET */\r | |
689 | \r | |
690 | static void\r | |
691 | inittimezone(PyObject *m) {\r | |
692 | /* This code moved from inittime wholesale to allow calling it from\r | |
693 | time_tzset. In the future, some parts of it can be moved back\r | |
694 | (for platforms that don't HAVE_WORKING_TZSET, when we know what they\r | |
695 | are), and the extraneous calls to tzset(3) should be removed.\r | |
696 | I haven't done this yet, as I don't want to change this code as\r | |
697 | little as possible when introducing the time.tzset and time.tzsetwall\r | |
698 | methods. This should simply be a method of doing the following once,\r | |
699 | at the top of this function and removing the call to tzset() from\r | |
700 | time_tzset():\r | |
701 | \r | |
702 | #ifdef HAVE_TZSET\r | |
703 | tzset()\r | |
704 | #endif\r | |
705 | \r | |
706 | And I'm lazy and hate C so nyer.\r | |
707 | */\r | |
708 | #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)\r | |
709 | tzset();\r | |
710 | #ifdef PYOS_OS2\r | |
711 | PyModule_AddIntConstant(m, "timezone", _timezone);\r | |
712 | #else /* !PYOS_OS2 */\r | |
713 | PyModule_AddIntConstant(m, "timezone", timezone);\r | |
714 | #endif /* PYOS_OS2 */\r | |
715 | #ifdef HAVE_ALTZONE\r | |
716 | PyModule_AddIntConstant(m, "altzone", altzone);\r | |
717 | #else\r | |
718 | #ifdef PYOS_OS2\r | |
719 | PyModule_AddIntConstant(m, "altzone", _timezone-3600);\r | |
720 | #else /* !PYOS_OS2 */\r | |
721 | PyModule_AddIntConstant(m, "altzone", timezone-3600);\r | |
722 | #endif /* PYOS_OS2 */\r | |
723 | #endif\r | |
724 | PyModule_AddIntConstant(m, "daylight", daylight);\r | |
725 | PyModule_AddObject(m, "tzname",\r | |
726 | Py_BuildValue("(zz)", tzname[0], tzname[1]));\r | |
727 | #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/\r | |
728 | #ifdef HAVE_STRUCT_TM_TM_ZONE\r | |
729 | {\r | |
730 | #define YEAR ((time_t)((365 * 24 + 6) * 3600))\r | |
731 | time_t t;\r | |
732 | struct tm *p;\r | |
733 | long janzone, julyzone;\r | |
734 | char janname[10], julyname[10];\r | |
735 | t = (time((time_t *)0) / YEAR) * YEAR;\r | |
736 | p = localtime(&t);\r | |
737 | janzone = -p->tm_gmtoff;\r | |
738 | strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9);\r | |
739 | janname[9] = '\0';\r | |
740 | t += YEAR/2;\r | |
741 | p = localtime(&t);\r | |
742 | julyzone = -p->tm_gmtoff;\r | |
743 | strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9);\r | |
744 | julyname[9] = '\0';\r | |
745 | \r | |
746 | if( janzone < julyzone ) {\r | |
747 | /* DST is reversed in the southern hemisphere */\r | |
748 | PyModule_AddIntConstant(m, "timezone", julyzone);\r | |
749 | PyModule_AddIntConstant(m, "altzone", janzone);\r | |
750 | PyModule_AddIntConstant(m, "daylight",\r | |
751 | janzone != julyzone);\r | |
752 | PyModule_AddObject(m, "tzname",\r | |
753 | Py_BuildValue("(zz)",\r | |
754 | julyname, janname));\r | |
755 | } else {\r | |
756 | PyModule_AddIntConstant(m, "timezone", janzone);\r | |
757 | PyModule_AddIntConstant(m, "altzone", julyzone);\r | |
758 | PyModule_AddIntConstant(m, "daylight",\r | |
759 | janzone != julyzone);\r | |
760 | PyModule_AddObject(m, "tzname",\r | |
761 | Py_BuildValue("(zz)",\r | |
762 | janname, julyname));\r | |
763 | }\r | |
764 | }\r | |
765 | #else\r | |
766 | #endif /* HAVE_STRUCT_TM_TM_ZONE */\r | |
767 | #ifdef __CYGWIN__\r | |
768 | tzset();\r | |
769 | PyModule_AddIntConstant(m, "timezone", _timezone);\r | |
770 | PyModule_AddIntConstant(m, "altzone", _timezone-3600);\r | |
771 | PyModule_AddIntConstant(m, "daylight", _daylight);\r | |
772 | PyModule_AddObject(m, "tzname",\r | |
773 | Py_BuildValue("(zz)", _tzname[0], _tzname[1]));\r | |
774 | #endif /* __CYGWIN__ */\r | |
775 | #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/\r | |
776 | }\r | |
777 | \r | |
778 | \r | |
779 | static PyMethodDef time_methods[] = {\r | |
780 | {"time", time_time, METH_NOARGS, time_doc},\r | |
781 | #ifdef HAVE_CLOCK\r | |
782 | {"clock", time_clock, METH_NOARGS, clock_doc},\r | |
783 | #endif\r | |
784 | {"sleep", time_sleep, METH_VARARGS, sleep_doc},\r | |
785 | {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc},\r | |
786 | {"localtime", time_localtime, METH_VARARGS, localtime_doc},\r | |
787 | {"asctime", time_asctime, METH_VARARGS, asctime_doc},\r | |
788 | {"ctime", time_ctime, METH_VARARGS, ctime_doc},\r | |
789 | #ifdef HAVE_MKTIME\r | |
790 | {"mktime", time_mktime, METH_O, mktime_doc},\r | |
791 | #endif\r | |
792 | #ifdef HAVE_STRFTIME\r | |
793 | {"strftime", time_strftime, METH_VARARGS, strftime_doc},\r | |
794 | #endif\r | |
795 | {"strptime", time_strptime, METH_VARARGS, strptime_doc},\r | |
796 | #ifdef HAVE_WORKING_TZSET\r | |
797 | {"tzset", time_tzset, METH_NOARGS, tzset_doc},\r | |
798 | #endif\r | |
799 | {NULL, NULL} /* sentinel */\r | |
800 | };\r | |
801 | \r | |
802 | \r | |
803 | PyDoc_STRVAR(module_doc,\r | |
804 | "This module provides various functions to manipulate time values.\n\\r | |
805 | \n\\r | |
806 | There are two standard representations of time. One is the number\n\\r | |
807 | of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\\r | |
808 | or a floating point number (to represent fractions of seconds).\n\\r | |
809 | The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\\r | |
810 | The actual value can be retrieved by calling gmtime(0).\n\\r | |
811 | \n\\r | |
812 | The other representation is a tuple of 9 integers giving local time.\n\\r | |
813 | The tuple items are:\n\\r | |
814 | year (four digits, e.g. 1998)\n\\r | |
815 | month (1-12)\n\\r | |
816 | day (1-31)\n\\r | |
817 | hours (0-23)\n\\r | |
818 | minutes (0-59)\n\\r | |
819 | seconds (0-59)\n\\r | |
820 | weekday (0-6, Monday is 0)\n\\r | |
821 | Julian day (day in the year, 1-366)\n\\r | |
822 | DST (Daylight Savings Time) flag (-1, 0 or 1)\n\\r | |
823 | If the DST flag is 0, the time is given in the regular time zone;\n\\r | |
824 | if it is 1, the time is given in the DST time zone;\n\\r | |
825 | if it is -1, mktime() should guess based on the date and time.\n\\r | |
826 | \n\\r | |
827 | Variables:\n\\r | |
828 | \n\\r | |
829 | timezone -- difference in seconds between UTC and local standard time\n\\r | |
830 | altzone -- difference in seconds between UTC and local DST time\n\\r | |
831 | daylight -- whether local time should reflect DST\n\\r | |
832 | tzname -- tuple of (standard time zone name, DST time zone name)\n\\r | |
833 | \n\\r | |
834 | Functions:\n\\r | |
835 | \n\\r | |
836 | time() -- return current time in seconds since the Epoch as a float\n\\r | |
837 | clock() -- return CPU time since process start as a float\n\\r | |
838 | sleep() -- delay for a number of seconds given as a float\n\\r | |
839 | gmtime() -- convert seconds since Epoch to UTC tuple\n\\r | |
840 | localtime() -- convert seconds since Epoch to local time tuple\n\\r | |
841 | asctime() -- convert time tuple to string\n\\r | |
842 | ctime() -- convert time in seconds to string\n\\r | |
843 | mktime() -- convert local time tuple to seconds since Epoch\n\\r | |
844 | strftime() -- convert time tuple to string according to format specification\n\\r | |
845 | strptime() -- parse string to time tuple according to format specification\n\\r | |
846 | tzset() -- change the local timezone");\r | |
847 | \r | |
848 | \r | |
849 | PyMODINIT_FUNC\r | |
850 | inittime(void)\r | |
851 | {\r | |
852 | PyObject *m;\r | |
853 | char *p;\r | |
854 | m = Py_InitModule3("time", time_methods, module_doc);\r | |
855 | if (m == NULL)\r | |
856 | return;\r | |
857 | \r | |
858 | /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */\r | |
859 | p = Py_GETENV("PYTHONY2K");\r | |
860 | PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p));\r | |
861 | /* If an embedded interpreter is shutdown and reinitialized the old\r | |
862 | moddict was not decrefed on shutdown and the next import of this\r | |
863 | module leads to a leak. Conditionally decref here to prevent that.\r | |
864 | */\r | |
865 | Py_XDECREF(moddict);\r | |
866 | /* Squirrel away the module's dictionary for the y2k check */\r | |
867 | moddict = PyModule_GetDict(m);\r | |
868 | Py_INCREF(moddict);\r | |
869 | \r | |
870 | /* Set, or reset, module variables like time.timezone */\r | |
871 | inittimezone(m);\r | |
872 | \r | |
873 | #ifdef MS_WINDOWS\r | |
874 | /* Helper to allow interrupts for Windows.\r | |
875 | If Ctrl+C event delivered while not sleeping\r | |
876 | it will be ignored.\r | |
877 | */\r | |
878 | main_thread = PyThread_get_thread_ident();\r | |
879 | hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL);\r | |
880 | SetConsoleCtrlHandler( PyCtrlHandler, TRUE);\r | |
881 | #endif /* MS_WINDOWS */\r | |
882 | if (!initialized) {\r | |
883 | PyStructSequence_InitType(&StructTimeType,\r | |
884 | &struct_time_type_desc);\r | |
885 | }\r | |
886 | Py_INCREF(&StructTimeType);\r | |
887 | PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);\r | |
888 | initialized = 1;\r | |
889 | }\r | |
890 | \r | |
891 | \r | |
892 | /* Implement floattime() for various platforms */\r | |
893 | \r | |
894 | static double\r | |
895 | floattime(void)\r | |
896 | {\r | |
897 | /* There are three ways to get the time:\r | |
898 | (1) gettimeofday() -- resolution in microseconds\r | |
899 | (2) ftime() -- resolution in milliseconds\r | |
900 | (3) time() -- resolution in seconds\r | |
901 | In all cases the return value is a float in seconds.\r | |
902 | Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may\r | |
903 | fail, so we fall back on ftime() or time().\r | |
904 | Note: clock resolution does not imply clock accuracy! */\r | |
905 | #ifdef HAVE_GETTIMEOFDAY\r | |
906 | {\r | |
907 | struct timeval t;\r | |
908 | #ifdef GETTIMEOFDAY_NO_TZ\r | |
909 | if (gettimeofday(&t) == 0)\r | |
910 | return (double)t.tv_sec + t.tv_usec*0.000001;\r | |
911 | #else /* !GETTIMEOFDAY_NO_TZ */\r | |
912 | if (gettimeofday(&t, (struct timezone *)NULL) == 0)\r | |
913 | return (double)t.tv_sec + t.tv_usec*0.000001;\r | |
914 | #endif /* !GETTIMEOFDAY_NO_TZ */\r | |
915 | }\r | |
916 | \r | |
917 | #endif /* !HAVE_GETTIMEOFDAY */\r | |
918 | {\r | |
919 | #if defined(HAVE_FTIME)\r | |
920 | struct timeb t;\r | |
921 | ftime(&t);\r | |
922 | return (double)t.time + (double)t.millitm * (double)0.001;\r | |
923 | #else /* !HAVE_FTIME */\r | |
924 | time_t secs;\r | |
925 | time(&secs);\r | |
926 | return (double)secs;\r | |
927 | #endif /* !HAVE_FTIME */\r | |
928 | }\r | |
929 | }\r | |
930 | \r | |
931 | \r | |
932 | /* Implement floatsleep() for various platforms.\r | |
933 | When interrupted (or when another error occurs), return -1 and\r | |
934 | set an exception; else return 0. */\r | |
935 | \r | |
936 | static int\r | |
937 | floatsleep(double secs)\r | |
938 | {\r | |
939 | /* XXX Should test for MS_WINDOWS first! */\r | |
940 | #if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__)\r | |
941 | struct timeval t;\r | |
942 | double frac;\r | |
943 | frac = fmod(secs, 1.0);\r | |
944 | secs = floor(secs);\r | |
945 | t.tv_sec = (long)secs;\r | |
946 | t.tv_usec = (long)(frac*1000000.0);\r | |
947 | Py_BEGIN_ALLOW_THREADS\r | |
948 | if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {\r | |
949 | #ifdef EINTR\r | |
950 | if (errno != EINTR) {\r | |
951 | #else\r | |
952 | if (1) {\r | |
953 | #endif\r | |
954 | Py_BLOCK_THREADS\r | |
955 | PyErr_SetFromErrno(PyExc_IOError);\r | |
956 | return -1;\r | |
957 | }\r | |
958 | }\r | |
959 | Py_END_ALLOW_THREADS\r | |
960 | #elif defined(__WATCOMC__) && !defined(__QNX__)\r | |
961 | /* XXX Can't interrupt this sleep */\r | |
962 | Py_BEGIN_ALLOW_THREADS\r | |
963 | delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */\r | |
964 | Py_END_ALLOW_THREADS\r | |
965 | #elif defined(MS_WINDOWS)\r | |
966 | {\r | |
967 | double millisecs = secs * 1000.0;\r | |
968 | unsigned long ul_millis;\r | |
969 | \r | |
970 | if (millisecs > (double)ULONG_MAX) {\r | |
971 | PyErr_SetString(PyExc_OverflowError,\r | |
972 | "sleep length is too large");\r | |
973 | return -1;\r | |
974 | }\r | |
975 | Py_BEGIN_ALLOW_THREADS\r | |
976 | /* Allow sleep(0) to maintain win32 semantics, and as decreed\r | |
977 | * by Guido, only the main thread can be interrupted.\r | |
978 | */\r | |
979 | ul_millis = (unsigned long)millisecs;\r | |
980 | if (ul_millis == 0 ||\r | |
981 | main_thread != PyThread_get_thread_ident())\r | |
982 | Sleep(ul_millis);\r | |
983 | else {\r | |
984 | DWORD rc;\r | |
985 | ResetEvent(hInterruptEvent);\r | |
986 | rc = WaitForSingleObject(hInterruptEvent, ul_millis);\r | |
987 | if (rc == WAIT_OBJECT_0) {\r | |
988 | /* Yield to make sure real Python signal\r | |
989 | * handler called.\r | |
990 | */\r | |
991 | Sleep(1);\r | |
992 | Py_BLOCK_THREADS\r | |
993 | errno = EINTR;\r | |
994 | PyErr_SetFromErrno(PyExc_IOError);\r | |
995 | return -1;\r | |
996 | }\r | |
997 | }\r | |
998 | Py_END_ALLOW_THREADS\r | |
999 | }\r | |
1000 | #elif defined(PYOS_OS2)\r | |
1001 | /* This Sleep *IS* Interruptable by Exceptions */\r | |
1002 | Py_BEGIN_ALLOW_THREADS\r | |
1003 | if (DosSleep(secs * 1000) != NO_ERROR) {\r | |
1004 | Py_BLOCK_THREADS\r | |
1005 | PyErr_SetFromErrno(PyExc_IOError);\r | |
1006 | return -1;\r | |
1007 | }\r | |
1008 | Py_END_ALLOW_THREADS\r | |
1009 | #elif defined(__BEOS__)\r | |
1010 | /* This sleep *CAN BE* interrupted. */\r | |
1011 | {\r | |
1012 | if( secs <= 0.0 ) {\r | |
1013 | return;\r | |
1014 | }\r | |
1015 | \r | |
1016 | Py_BEGIN_ALLOW_THREADS\r | |
1017 | /* BeOS snooze() is in microseconds... */\r | |
1018 | if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) {\r | |
1019 | Py_BLOCK_THREADS\r | |
1020 | PyErr_SetFromErrno( PyExc_IOError );\r | |
1021 | return -1;\r | |
1022 | }\r | |
1023 | Py_END_ALLOW_THREADS\r | |
1024 | }\r | |
1025 | #elif defined(RISCOS)\r | |
1026 | if (secs <= 0.0)\r | |
1027 | return 0;\r | |
1028 | Py_BEGIN_ALLOW_THREADS\r | |
1029 | /* This sleep *CAN BE* interrupted. */\r | |
1030 | if ( riscos_sleep(secs) )\r | |
1031 | return -1;\r | |
1032 | Py_END_ALLOW_THREADS\r | |
1033 | #elif defined(PLAN9)\r | |
1034 | {\r | |
1035 | double millisecs = secs * 1000.0;\r | |
1036 | if (millisecs > (double)LONG_MAX) {\r | |
1037 | PyErr_SetString(PyExc_OverflowError, "sleep length is too large");\r | |
1038 | return -1;\r | |
1039 | }\r | |
1040 | /* This sleep *CAN BE* interrupted. */\r | |
1041 | Py_BEGIN_ALLOW_THREADS\r | |
1042 | if(sleep((long)millisecs) < 0){\r | |
1043 | Py_BLOCK_THREADS\r | |
1044 | PyErr_SetFromErrno(PyExc_IOError);\r | |
1045 | return -1;\r | |
1046 | }\r | |
1047 | Py_END_ALLOW_THREADS\r | |
1048 | }\r | |
1049 | #else\r | |
1050 | /* XXX Can't interrupt this sleep */\r | |
1051 | Py_BEGIN_ALLOW_THREADS\r | |
1052 | sleep((int)secs);\r | |
1053 | Py_END_ALLOW_THREADS\r | |
1054 | #endif\r | |
1055 | \r | |
1056 | return 0;\r | |
1057 | }\r | |
1058 | \r | |
1059 | /* export floattime to socketmodule.c */\r | |
1060 | PyAPI_FUNC(double)\r | |
1061 | _PyTime_FloatTime(void)\r | |
1062 | {\r | |
1063 | return floattime();\r | |
1064 | }\r |