Move setting of ioready 'wait' earlier in call chain, to
[python/dscho.git] / Modules / timemodule.c
blob745ba8c8fbc4bd4f4d0c306a45457a0d7255a1dc
2 /* Time module */
4 #include "Python.h"
5 #include "structseq.h"
7 #include <ctype.h>
9 #ifdef macintosh
10 #include <time.h>
11 #include <OSUtils.h>
12 #else
13 #include <sys/types.h>
14 #endif
16 #ifdef QUICKWIN
17 #include <io.h>
18 #endif
20 #ifdef HAVE_FTIME
21 #include <sys/timeb.h>
22 #if !defined(MS_WINDOWS) && !defined(PYOS_OS2)
23 extern int ftime(struct timeb *);
24 #endif /* MS_WINDOWS */
25 #endif /* HAVE_FTIME */
27 #if defined(__WATCOMC__) && !defined(__QNX__)
28 #include <i86.h>
29 #else
30 #ifdef MS_WINDOWS
31 #define WIN32_LEAN_AND_MEAN
32 #include <windows.h>
33 #include "pythread.h"
35 /* helper to allow us to interrupt sleep() on Windows*/
36 static HANDLE hInterruptEvent = NULL;
37 static BOOL WINAPI PyCtrlHandler(DWORD dwCtrlType)
39 SetEvent(hInterruptEvent);
40 /* allow other default handlers to be called.
41 Default Python handler will setup the
42 KeyboardInterrupt exception.
44 return FALSE;
46 static long main_thread;
49 #if defined(__BORLANDC__)
50 /* These overrides not needed for Win32 */
51 #define timezone _timezone
52 #define tzname _tzname
53 #define daylight _daylight
54 #endif /* __BORLANDC__ */
55 #endif /* MS_WINDOWS */
56 #endif /* !__WATCOMC__ || __QNX__ */
58 #if defined(MS_WINDOWS) && !defined(MS_WIN64) && !defined(__BORLANDC__)
59 /* Win32 has better clock replacement
60 XXX Win64 does not yet, but might when the platform matures. */
61 #undef HAVE_CLOCK /* We have our own version down below */
62 #endif /* MS_WINDOWS && !MS_WIN64 */
64 #if defined(PYOS_OS2)
65 #define INCL_DOS
66 #define INCL_ERRORS
67 #include <os2.h>
68 #endif
70 #if defined(PYCC_VACPP)
71 #include <sys/time.h>
72 #endif
74 #ifdef __BEOS__
75 #include <time.h>
76 /* For bigtime_t, snooze(). - [cjh] */
77 #include <support/SupportDefs.h>
78 #include <kernel/OS.h>
79 #endif
81 /* Forward declarations */
82 static int floatsleep(double);
83 static double floattime(void);
85 /* For Y2K check */
86 static PyObject *moddict;
88 #ifdef macintosh
89 /* Our own timezone. We have enough information to deduce whether
90 ** DST is on currently, but unfortunately we cannot put it to good
91 ** use because we don't know the rules (and that is needed to have
92 ** localtime() return correct tm_isdst values for times other than
93 ** the current time. So, we cop out and only tell the user the current
94 ** timezone.
96 static long timezone;
98 static void
99 initmactimezone(void)
101 MachineLocation loc;
102 long delta;
104 ReadLocation(&loc);
106 if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0)
107 return;
109 delta = loc.u.gmtDelta & 0x00FFFFFF;
111 if (delta & 0x00800000)
112 delta |= 0xFF000000;
114 timezone = -delta;
116 #endif /* macintosh */
119 static PyObject *
120 time_time(PyObject *self, PyObject *args)
122 double secs;
123 if (!PyArg_ParseTuple(args, ":time"))
124 return NULL;
125 secs = floattime();
126 if (secs == 0.0) {
127 PyErr_SetFromErrno(PyExc_IOError);
128 return NULL;
130 return PyFloat_FromDouble(secs);
133 PyDoc_STRVAR(time_doc,
134 "time() -> floating point number\n\
136 Return the current time in seconds since the Epoch.\n\
137 Fractions of a second may be present if the system clock provides them.");
139 #ifdef HAVE_CLOCK
141 #ifndef CLOCKS_PER_SEC
142 #ifdef CLK_TCK
143 #define CLOCKS_PER_SEC CLK_TCK
144 #else
145 #define CLOCKS_PER_SEC 1000000
146 #endif
147 #endif
149 static PyObject *
150 time_clock(PyObject *self, PyObject *args)
152 if (!PyArg_ParseTuple(args, ":clock"))
153 return NULL;
154 return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
156 #endif /* HAVE_CLOCK */
158 #if defined(MS_WINDOWS) && !defined(MS_WIN64) && !defined(__BORLANDC__)
159 /* Due to Mark Hammond and Tim Peters */
160 static PyObject *
161 time_clock(PyObject *self, PyObject *args)
163 static LARGE_INTEGER ctrStart;
164 static double divisor = 0.0;
165 LARGE_INTEGER now;
166 double diff;
168 if (!PyArg_ParseTuple(args, ":clock"))
169 return NULL;
171 if (divisor == 0.0) {
172 LARGE_INTEGER freq;
173 QueryPerformanceCounter(&ctrStart);
174 if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) {
175 /* Unlikely to happen - this works on all intel
176 machines at least! Revert to clock() */
177 return PyFloat_FromDouble(clock());
179 divisor = (double)freq.QuadPart;
181 QueryPerformanceCounter(&now);
182 diff = (double)(now.QuadPart - ctrStart.QuadPart);
183 return PyFloat_FromDouble(diff / divisor);
186 #define HAVE_CLOCK /* So it gets included in the methods */
187 #endif /* MS_WINDOWS && !MS_WIN64 */
189 #ifdef HAVE_CLOCK
190 PyDoc_STRVAR(clock_doc,
191 "clock() -> floating point number\n\
193 Return the CPU time or real time since the start of the process or since\n\
194 the first call to clock(). This has as much precision as the system\n\
195 records.");
196 #endif
198 static PyObject *
199 time_sleep(PyObject *self, PyObject *args)
201 double secs;
202 if (!PyArg_ParseTuple(args, "d:sleep", &secs))
203 return NULL;
204 if (floatsleep(secs) != 0)
205 return NULL;
206 Py_INCREF(Py_None);
207 return Py_None;
210 PyDoc_STRVAR(sleep_doc,
211 "sleep(seconds)\n\
213 Delay execution for a given number of seconds. The argument may be\n\
214 a floating point number for subsecond precision.");
216 static PyStructSequence_Field struct_time_type_fields[] = {
217 {"tm_year", NULL},
218 {"tm_mon", NULL},
219 {"tm_mday", NULL},
220 {"tm_hour", NULL},
221 {"tm_min", NULL},
222 {"tm_sec", NULL},
223 {"tm_wday", NULL},
224 {"tm_yday", NULL},
225 {"tm_isdst", NULL},
229 static PyStructSequence_Desc struct_time_type_desc = {
230 "time.struct_time",
231 NULL,
232 struct_time_type_fields,
236 static PyTypeObject StructTimeType;
238 static PyObject *
239 tmtotuple(struct tm *p)
241 PyObject *v = PyStructSequence_New(&StructTimeType);
242 if (v == NULL)
243 return NULL;
245 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
247 SET(0, p->tm_year + 1900);
248 SET(1, p->tm_mon + 1); /* Want January == 1 */
249 SET(2, p->tm_mday);
250 SET(3, p->tm_hour);
251 SET(4, p->tm_min);
252 SET(5, p->tm_sec);
253 SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
254 SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */
255 SET(8, p->tm_isdst);
256 #undef SET
257 if (PyErr_Occurred()) {
258 Py_XDECREF(v);
259 return NULL;
262 return v;
265 static PyObject *
266 time_convert(time_t when, struct tm * (*function)(const time_t *))
268 struct tm *p;
269 errno = 0;
270 p = function(&when);
271 if (p == NULL) {
272 #ifdef EINVAL
273 if (errno == 0)
274 errno = EINVAL;
275 #endif
276 return PyErr_SetFromErrno(PyExc_ValueError);
278 return tmtotuple(p);
281 static PyObject *
282 time_gmtime(PyObject *self, PyObject *args)
284 double when;
285 if (PyTuple_Size(args) == 0)
286 when = floattime();
287 if (!PyArg_ParseTuple(args, "|d:gmtime", &when))
288 return NULL;
289 return time_convert((time_t)when, gmtime);
292 PyDoc_STRVAR(gmtime_doc,
293 "gmtime([seconds]) -> (tm_year, tm_mon, tm_day, tm_hour, tm_min,\n\
294 tm_sec, tm_wday, tm_yday, tm_isdst)\n\
296 Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
297 GMT). When 'seconds' is not passed in, convert the current time instead.");
299 static PyObject *
300 time_localtime(PyObject *self, PyObject *args)
302 double when;
303 if (PyTuple_Size(args) == 0)
304 when = floattime();
305 if (!PyArg_ParseTuple(args, "|d:localtime", &when))
306 return NULL;
307 return time_convert((time_t)when, localtime);
310 PyDoc_STRVAR(localtime_doc,
311 "localtime([seconds]) -> (tm_year,tm_mon,tm_day,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)\n\
313 Convert seconds since the Epoch to a time tuple expressing local time.\n\
314 When 'seconds' is not passed in, convert the current time instead.");
316 static int
317 gettmarg(PyObject *args, struct tm *p)
319 int y;
320 memset((void *) p, '\0', sizeof(struct tm));
322 if (!PyArg_Parse(args, "(iiiiiiiii)",
324 &p->tm_mon,
325 &p->tm_mday,
326 &p->tm_hour,
327 &p->tm_min,
328 &p->tm_sec,
329 &p->tm_wday,
330 &p->tm_yday,
331 &p->tm_isdst))
332 return 0;
333 if (y < 1900) {
334 PyObject *accept = PyDict_GetItemString(moddict,
335 "accept2dyear");
336 if (accept == NULL || !PyInt_Check(accept) ||
337 PyInt_AsLong(accept) == 0) {
338 PyErr_SetString(PyExc_ValueError,
339 "year >= 1900 required");
340 return 0;
342 if (69 <= y && y <= 99)
343 y += 1900;
344 else if (0 <= y && y <= 68)
345 y += 2000;
346 else {
347 PyErr_SetString(PyExc_ValueError,
348 "year out of range");
349 return 0;
352 p->tm_year = y - 1900;
353 p->tm_mon--;
354 p->tm_wday = (p->tm_wday + 1) % 7;
355 p->tm_yday--;
356 return 1;
359 #ifdef HAVE_STRFTIME
360 static PyObject *
361 time_strftime(PyObject *self, PyObject *args)
363 PyObject *tup = NULL;
364 struct tm buf;
365 const char *fmt;
366 size_t fmtlen, buflen;
367 char *outbuf = 0;
368 size_t i;
370 memset((void *) &buf, '\0', sizeof(buf));
372 if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup))
373 return NULL;
375 if (tup == NULL) {
376 time_t tt = time(NULL);
377 buf = *localtime(&tt);
378 } else if (!gettmarg(tup, &buf))
379 return NULL;
381 fmtlen = strlen(fmt);
383 /* I hate these functions that presume you know how big the output
384 * will be ahead of time...
386 for (i = 1024; ; i += i) {
387 outbuf = malloc(i);
388 if (outbuf == NULL) {
389 return PyErr_NoMemory();
391 buflen = strftime(outbuf, i, fmt, &buf);
392 if (buflen > 0 || i >= 256 * fmtlen) {
393 /* If the buffer is 256 times as long as the format,
394 it's probably not failing for lack of room!
395 More likely, the format yields an empty result,
396 e.g. an empty format, or %Z when the timezone
397 is unknown. */
398 PyObject *ret;
399 ret = PyString_FromStringAndSize(outbuf, buflen);
400 free(outbuf);
401 return ret;
403 free(outbuf);
407 PyDoc_STRVAR(strftime_doc,
408 "strftime(format[, tuple]) -> string\n\
410 Convert a time tuple to a string according to a format specification.\n\
411 See the library reference manual for formatting codes. When the time tuple\n\
412 is not present, current time as returned by localtime() is used.");
413 #endif /* HAVE_STRFTIME */
415 #undef HAVE_STRPTIME
416 #ifdef HAVE_STRPTIME
418 #if 0
419 /* Enable this if it's not declared in <time.h> */
420 extern char *strptime(const char *, const char *, struct tm *);
421 #endif
423 static PyObject *
424 time_strptime(PyObject *self, PyObject *args)
426 struct tm tm;
427 char *fmt = "%a %b %d %H:%M:%S %Y";
428 char *buf;
429 char *s;
431 if (!PyArg_ParseTuple(args, "s|s:strptime", &buf, &fmt))
432 return NULL;
433 memset((void *) &tm, '\0', sizeof(tm));
434 s = strptime(buf, fmt, &tm);
435 if (s == NULL) {
436 PyErr_SetString(PyExc_ValueError, "format mismatch");
437 return NULL;
439 while (*s && isspace(Py_CHARMASK(*s)))
440 s++;
441 if (*s) {
442 PyErr_Format(PyExc_ValueError,
443 "unconverted data remains: '%.400s'", s);
444 return NULL;
446 return tmtotuple(&tm);
449 #endif /* HAVE_STRPTIME */
451 #ifndef HAVE_STRPTIME
453 static PyObject *
454 time_strptime(PyObject *self, PyObject *args)
456 PyObject *strptime_module = PyImport_ImportModule("_strptime");
458 if (!strptime_module)
459 return NULL;
460 return PyObject_CallMethod(strptime_module, "strptime", "O", args);
463 #endif /* !HAVE_STRPTIME */
465 PyDoc_STRVAR(strptime_doc,
466 "strptime(string, format) -> tuple\n\
468 Parse a string to a time tuple according to a format specification.\n\
469 See the library reference manual for formatting codes (same as strftime()).");
472 static PyObject *
473 time_asctime(PyObject *self, PyObject *args)
475 PyObject *tup = NULL;
476 struct tm buf;
477 char *p;
478 if (!PyArg_ParseTuple(args, "|O:asctime", &tup))
479 return NULL;
480 if (tup == NULL) {
481 time_t tt = time(NULL);
482 buf = *localtime(&tt);
483 } else if (!gettmarg(tup, &buf))
484 return NULL;
485 p = asctime(&buf);
486 if (p[24] == '\n')
487 p[24] = '\0';
488 return PyString_FromString(p);
491 PyDoc_STRVAR(asctime_doc,
492 "asctime([tuple]) -> string\n\
494 Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
495 When the time tuple is not present, current time as returned by localtime()\n\
496 is used.");
498 static PyObject *
499 time_ctime(PyObject *self, PyObject *args)
501 double dt;
502 time_t tt;
503 char *p;
505 if (PyTuple_Size(args) == 0)
506 tt = time(NULL);
507 else {
508 if (!PyArg_ParseTuple(args, "|d:ctime", &dt))
509 return NULL;
510 tt = (time_t)dt;
512 p = ctime(&tt);
513 if (p == NULL) {
514 PyErr_SetString(PyExc_ValueError, "unconvertible time");
515 return NULL;
517 if (p[24] == '\n')
518 p[24] = '\0';
519 return PyString_FromString(p);
522 PyDoc_STRVAR(ctime_doc,
523 "ctime(seconds) -> string\n\
525 Convert a time in seconds since the Epoch to a string in local time.\n\
526 This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
527 not present, current time as returned by localtime() is used.");
529 #ifdef HAVE_MKTIME
530 static PyObject *
531 time_mktime(PyObject *self, PyObject *args)
533 PyObject *tup;
534 struct tm buf;
535 time_t tt;
536 if (!PyArg_ParseTuple(args, "O:mktime", &tup))
537 return NULL;
538 tt = time(&tt);
539 buf = *localtime(&tt);
540 if (!gettmarg(tup, &buf))
541 return NULL;
542 tt = mktime(&buf);
543 if (tt == (time_t)(-1)) {
544 PyErr_SetString(PyExc_OverflowError,
545 "mktime argument out of range");
546 return NULL;
548 return PyFloat_FromDouble((double)tt);
551 PyDoc_STRVAR(mktime_doc,
552 "mktime(tuple) -> floating point number\n\
554 Convert a time tuple in local time to seconds since the Epoch.");
555 #endif /* HAVE_MKTIME */
557 static PyMethodDef time_methods[] = {
558 {"time", time_time, METH_VARARGS, time_doc},
559 #ifdef HAVE_CLOCK
560 {"clock", time_clock, METH_VARARGS, clock_doc},
561 #endif
562 {"sleep", time_sleep, METH_VARARGS, sleep_doc},
563 {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc},
564 {"localtime", time_localtime, METH_VARARGS, localtime_doc},
565 {"asctime", time_asctime, METH_VARARGS, asctime_doc},
566 {"ctime", time_ctime, METH_VARARGS, ctime_doc},
567 #ifdef HAVE_MKTIME
568 {"mktime", time_mktime, METH_VARARGS, mktime_doc},
569 #endif
570 #ifdef HAVE_STRFTIME
571 {"strftime", time_strftime, METH_VARARGS, strftime_doc},
572 #endif
573 {"strptime", time_strptime, METH_VARARGS, strptime_doc},
574 {NULL, NULL} /* sentinel */
578 PyDoc_STRVAR(module_doc,
579 "This module provides various functions to manipulate time values.\n\
581 There are two standard representations of time. One is the number\n\
582 of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\
583 or a floating point number (to represent fractions of seconds).\n\
584 The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
585 The actual value can be retrieved by calling gmtime(0).\n\
587 The other representation is a tuple of 9 integers giving local time.\n\
588 The tuple items are:\n\
589 year (four digits, e.g. 1998)\n\
590 month (1-12)\n\
591 day (1-31)\n\
592 hours (0-23)\n\
593 minutes (0-59)\n\
594 seconds (0-59)\n\
595 weekday (0-6, Monday is 0)\n\
596 Julian day (day in the year, 1-366)\n\
597 DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
598 If the DST flag is 0, the time is given in the regular time zone;\n\
599 if it is 1, the time is given in the DST time zone;\n\
600 if it is -1, mktime() should guess based on the date and time.\n\
602 Variables:\n\
604 timezone -- difference in seconds between UTC and local standard time\n\
605 altzone -- difference in seconds between UTC and local DST time\n\
606 daylight -- whether local time should reflect DST\n\
607 tzname -- tuple of (standard time zone name, DST time zone name)\n\
609 Functions:\n\
611 time() -- return current time in seconds since the Epoch as a float\n\
612 clock() -- return CPU time since process start as a float\n\
613 sleep() -- delay for a number of seconds given as a float\n\
614 gmtime() -- convert seconds since Epoch to UTC tuple\n\
615 localtime() -- convert seconds since Epoch to local time tuple\n\
616 asctime() -- convert time tuple to string\n\
617 ctime() -- convert time in seconds to string\n\
618 mktime() -- convert local time tuple to seconds since Epoch\n\
619 strftime() -- convert time tuple to string according to format specification\n\
620 strptime() -- parse string to time tuple according to format specification");
623 PyMODINIT_FUNC
624 inittime(void)
626 PyObject *m;
627 char *p;
628 m = Py_InitModule3("time", time_methods, module_doc);
630 /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
631 p = Py_GETENV("PYTHONY2K");
632 PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p));
633 /* Squirrel away the module's dictionary for the y2k check */
634 moddict = PyModule_GetDict(m);
635 Py_INCREF(moddict);
636 #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
637 tzset();
638 #ifdef PYOS_OS2
639 PyModule_AddIntConstant(m, "timezone", _timezone);
640 #else /* !PYOS_OS2 */
641 PyModule_AddIntConstant(m, "timezone", timezone);
642 #endif /* PYOS_OS2 */
643 #ifdef HAVE_ALTZONE
644 PyModule_AddIntConstant(m, "altzone", altzone);
645 #else
646 #ifdef PYOS_OS2
647 PyModule_AddIntConstant(m, "altzone", _timezone-3600);
648 #else /* !PYOS_OS2 */
649 PyModule_AddIntConstant(m, "altzone", timezone-3600);
650 #endif /* PYOS_OS2 */
651 #endif
652 PyModule_AddIntConstant(m, "daylight", daylight);
653 PyModule_AddObject(m, "tzname",
654 Py_BuildValue("(zz)", tzname[0], tzname[1]));
655 #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
656 #ifdef HAVE_STRUCT_TM_TM_ZONE
658 #define YEAR ((time_t)((365 * 24 + 6) * 3600))
659 time_t t;
660 struct tm *p;
661 long janzone, julyzone;
662 char janname[10], julyname[10];
663 t = (time((time_t *)0) / YEAR) * YEAR;
664 p = localtime(&t);
665 janzone = -p->tm_gmtoff;
666 strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9);
667 janname[9] = '\0';
668 t += YEAR/2;
669 p = localtime(&t);
670 julyzone = -p->tm_gmtoff;
671 strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9);
672 julyname[9] = '\0';
674 if( janzone < julyzone ) {
675 /* DST is reversed in the southern hemisphere */
676 PyModule_AddIntConstant(m, "timezone", julyzone);
677 PyModule_AddIntConstant(m, "altzone", janzone);
678 PyModule_AddIntConstant(m, "daylight",
679 janzone != julyzone);
680 PyModule_AddObject(m, "tzname",
681 Py_BuildValue("(zz)",
682 julyname, janname));
683 } else {
684 PyModule_AddIntConstant(m, "timezone", janzone);
685 PyModule_AddIntConstant(m, "altzone", julyzone);
686 PyModule_AddIntConstant(m, "daylight",
687 janzone != julyzone);
688 PyModule_AddObject(m, "tzname",
689 Py_BuildValue("(zz)",
690 janname, julyname));
693 #else
694 #ifdef macintosh
695 /* The only thing we can obtain is the current timezone
696 ** (and whether dst is currently _active_, but that is not what
697 ** we're looking for:-( )
699 initmactimezone();
700 PyModule_AddIntConstant(m, "timezone", timezone);
701 PyModule_AddIntConstant(m, "altzone", timezone);
702 PyModule_AddIntConstant(m, "daylight", 0);
703 PyModule_AddObject(m, "tzname", Py_BuildValue("(zz)", "", ""));
704 #endif /* macintosh */
705 #endif /* HAVE_STRUCT_TM_TM_ZONE */
706 #ifdef __CYGWIN__
707 tzset();
708 PyModule_AddIntConstant(m, "timezone", _timezone);
709 PyModule_AddIntConstant(m, "altzone", _timezone);
710 PyModule_AddIntConstant(m, "daylight", _daylight);
711 PyModule_AddObject(m, "tzname",
712 Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
713 #endif /* __CYGWIN__ */
714 #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
715 #ifdef MS_WINDOWS
716 /* Helper to allow interrupts for Windows.
717 If Ctrl+C event delivered while not sleeping
718 it will be ignored.
720 main_thread = PyThread_get_thread_ident();
721 hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
722 SetConsoleCtrlHandler( PyCtrlHandler, TRUE);
723 #endif /* MS_WINDOWS */
724 PyStructSequence_InitType(&StructTimeType, &struct_time_type_desc);
725 Py_INCREF(&StructTimeType);
726 PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
730 /* Implement floattime() for various platforms */
732 static double
733 floattime(void)
735 /* There are three ways to get the time:
736 (1) gettimeofday() -- resolution in microseconds
737 (2) ftime() -- resolution in milliseconds
738 (3) time() -- resolution in seconds
739 In all cases the return value is a float in seconds.
740 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
741 fail, so we fall back on ftime() or time().
742 Note: clock resolution does not imply clock accuracy! */
743 #ifdef HAVE_GETTIMEOFDAY
745 struct timeval t;
746 #ifdef GETTIMEOFDAY_NO_TZ
747 if (gettimeofday(&t) == 0)
748 return (double)t.tv_sec + t.tv_usec*0.000001;
749 #else /* !GETTIMEOFDAY_NO_TZ */
750 if (gettimeofday(&t, (struct timezone *)NULL) == 0)
751 return (double)t.tv_sec + t.tv_usec*0.000001;
752 #endif /* !GETTIMEOFDAY_NO_TZ */
754 #endif /* !HAVE_GETTIMEOFDAY */
756 #if defined(HAVE_FTIME)
757 struct timeb t;
758 ftime(&t);
759 return (double)t.time + (double)t.millitm * (double)0.001;
760 #else /* !HAVE_FTIME */
761 time_t secs;
762 time(&secs);
763 return (double)secs;
764 #endif /* !HAVE_FTIME */
769 /* Implement floatsleep() for various platforms.
770 When interrupted (or when another error occurs), return -1 and
771 set an exception; else return 0. */
773 static int
774 floatsleep(double secs)
776 /* XXX Should test for MS_WINDOWS first! */
777 #if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__)
778 struct timeval t;
779 double frac;
780 frac = fmod(secs, 1.0);
781 secs = floor(secs);
782 t.tv_sec = (long)secs;
783 t.tv_usec = (long)(frac*1000000.0);
784 Py_BEGIN_ALLOW_THREADS
785 if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
786 #ifdef EINTR
787 if (errno != EINTR) {
788 #else
789 if (1) {
790 #endif
791 Py_BLOCK_THREADS
792 PyErr_SetFromErrno(PyExc_IOError);
793 return -1;
796 Py_END_ALLOW_THREADS
797 #elif defined(macintosh)
798 #define MacTicks (* (long *)0x16A)
799 long deadline;
800 deadline = MacTicks + (long)(secs * 60.0);
801 while (MacTicks < deadline) {
802 /* XXX Should call some yielding function here */
803 if (PyErr_CheckSignals())
804 return -1;
806 #elif defined(__WATCOMC__) && !defined(__QNX__)
807 /* XXX Can't interrupt this sleep */
808 Py_BEGIN_ALLOW_THREADS
809 delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
810 Py_END_ALLOW_THREADS
811 #elif defined(MS_WINDOWS)
813 double millisecs = secs * 1000.0;
814 unsigned long ul_millis;
816 if (millisecs > (double)ULONG_MAX) {
817 PyErr_SetString(PyExc_OverflowError,
818 "sleep length is too large");
819 return -1;
821 Py_BEGIN_ALLOW_THREADS
822 /* Allow sleep(0) to maintain win32 semantics, and as decreed
823 * by Guido, only the main thread can be interrupted.
825 ul_millis = (unsigned long)millisecs;
826 if (ul_millis == 0 ||
827 main_thread != PyThread_get_thread_ident())
828 Sleep(ul_millis);
829 else {
830 DWORD rc;
831 ResetEvent(hInterruptEvent);
832 rc = WaitForSingleObject(hInterruptEvent, ul_millis);
833 if (rc == WAIT_OBJECT_0) {
834 /* Yield to make sure real Python signal
835 * handler called.
837 Sleep(1);
838 Py_BLOCK_THREADS
839 errno = EINTR;
840 PyErr_SetFromErrno(PyExc_IOError);
841 return -1;
844 Py_END_ALLOW_THREADS
846 #elif defined(PYOS_OS2)
847 /* This Sleep *IS* Interruptable by Exceptions */
848 Py_BEGIN_ALLOW_THREADS
849 if (DosSleep(secs * 1000) != NO_ERROR) {
850 Py_BLOCK_THREADS
851 PyErr_SetFromErrno(PyExc_IOError);
852 return -1;
854 Py_END_ALLOW_THREADS
855 #elif defined(__BEOS__)
856 /* This sleep *CAN BE* interrupted. */
858 if( secs <= 0.0 ) {
859 return;
862 Py_BEGIN_ALLOW_THREADS
863 /* BeOS snooze() is in microseconds... */
864 if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) {
865 Py_BLOCK_THREADS
866 PyErr_SetFromErrno( PyExc_IOError );
867 return -1;
869 Py_END_ALLOW_THREADS
871 #elif defined(RISCOS)
872 if (secs <= 0.0)
873 return 0;
874 Py_BEGIN_ALLOW_THREADS
875 /* This sleep *CAN BE* interrupted. */
876 if ( sleep(secs) )
877 return -1;
878 Py_END_ALLOW_THREADS
879 #elif defined(PLAN9)
881 double millisecs = secs * 1000.0;
882 if (millisecs > (double)LONG_MAX) {
883 PyErr_SetString(PyExc_OverflowError, "sleep length is too large");
884 return -1;
886 /* This sleep *CAN BE* interrupted. */
887 Py_BEGIN_ALLOW_THREADS
888 if(sleep((long)millisecs) < 0){
889 Py_BLOCK_THREADS
890 PyErr_SetFromErrno(PyExc_IOError);
891 return -1;
893 Py_END_ALLOW_THREADS
895 #else
896 /* XXX Can't interrupt this sleep */
897 Py_BEGIN_ALLOW_THREADS
898 sleep((int)secs);
899 Py_END_ALLOW_THREADS
900 #endif
902 return 0;