Clarify portability and main program.
[python/dscho.git] / Modules / timemodule.c
blob0a0322d4028021d7b720dc7c572ee5db11cc2754
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Time module */
34 #include "Python.h"
36 #include <ctype.h>
38 #ifdef HAVE_SELECT
39 #include "mymath.h"
40 #endif
42 #ifdef macintosh
43 #include <time.h>
44 #else
45 #include <sys/types.h>
46 #endif
48 #ifdef QUICKWIN
49 #include <io.h>
50 #endif
52 #ifdef HAVE_UNISTD_H
53 #include <unistd.h>
54 #endif
56 #if defined(HAVE_SELECT) && !defined(__BEOS__)
57 #include "myselect.h"
58 #else
59 #include "mytime.h"
60 #endif
62 #ifdef HAVE_FTIME
63 #ifndef __BEOS__
64 /* We have ftime(), but not in the headers (PR2). - [cjh] */
65 #include <sys/timeb.h>
66 #endif
67 #if !defined(MS_WINDOWS) && !defined(PYOS_OS2)
68 extern int ftime();
69 #endif /* MS_WINDOWS */
70 #endif /* HAVE_FTIME */
72 #if defined(__WATCOMC__) && !defined(__QNX__)
73 #include <i86.h>
74 #else
75 #ifdef MS_WINDOWS
76 #include <windows.h>
77 #ifdef MS_WIN16
78 /* These overrides not needed for Win32 */
79 #define timezone _timezone
80 #define tzname _tzname
81 #define daylight _daylight
82 #define altzone _altzone
83 #endif /* MS_WIN16 */
84 #endif /* MS_WINDOWS */
85 #endif /* !__WATCOMC__ || __QNX__ */
87 #ifdef MS_WIN32
88 /* Win32 has better clock replacement */
89 #include <largeint.h>
90 #undef HAVE_CLOCK /* We have our own version down below */
91 #endif /* MS_WIN32 */
93 #if defined(PYCC_VACPP)
94 #include <sys/time.h>
95 #endif
97 #ifdef __BEOS__
98 /* For bigtime_t, snooze(). - [cjh] */
99 #include <support/SupportDefs.h>
100 #include <kernel/OS.h>
101 #endif
103 /* Forward declarations */
104 static int floatsleep Py_PROTO((double));
105 static double floattime Py_PROTO(());
107 /* For Y2K check */
108 static PyObject *moddict;
110 #ifdef macintosh
111 /* Our own timezone. We have enough information to deduce whether
112 ** DST is on currently, but unfortunately we cannot put it to good
113 ** use because we don't know the rules (and that is needed to have
114 ** localtime() return correct tm_isdst values for times other than
115 ** the current time. So, we cop out and only tell the user the current
116 ** timezone.
118 static long timezone;
120 static void
121 initmactimezone()
123 MachineLocation loc;
124 long delta;
126 ReadLocation(&loc);
128 if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0)
129 return;
131 delta = loc.u.gmtDelta & 0x00FFFFFF;
133 if (delta & 0x00800000)
134 delta |= 0xFF000000;
136 timezone = -delta;
138 #endif /* macintosh */
141 static PyObject *
142 time_time(self, args)
143 PyObject *self;
144 PyObject *args;
146 double secs;
147 if (!PyArg_NoArgs(args))
148 return NULL;
149 secs = floattime();
150 if (secs == 0.0) {
151 PyErr_SetFromErrno(PyExc_IOError);
152 return NULL;
154 return PyFloat_FromDouble(secs);
157 static char time_doc[] =
158 "time() -> floating point number\n\
160 Return the current time in seconds since the Epoch.\n\
161 Fractions of a second may be present if the system clock provides them.";
163 #ifdef HAVE_CLOCK
165 #ifndef CLOCKS_PER_SEC
166 #ifdef CLK_TCK
167 #define CLOCKS_PER_SEC CLK_TCK
168 #else
169 #define CLOCKS_PER_SEC 1000000
170 #endif
171 #endif
173 static PyObject *
174 time_clock(self, args)
175 PyObject *self;
176 PyObject *args;
178 if (!PyArg_NoArgs(args))
179 return NULL;
180 return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
182 #endif /* HAVE_CLOCK */
184 #ifdef MS_WIN32
185 /* Due to Mark Hammond */
186 static PyObject *
187 time_clock(self, args)
188 PyObject *self;
189 PyObject *args;
191 static LARGE_INTEGER ctrStart;
192 static LARGE_INTEGER divisor = {0,0};
193 LARGE_INTEGER now, diff, rem;
195 if (!PyArg_NoArgs(args))
196 return NULL;
198 if (LargeIntegerEqualToZero(divisor)) {
199 QueryPerformanceCounter(&ctrStart);
200 if (!QueryPerformanceFrequency(&divisor) ||
201 LargeIntegerEqualToZero(divisor)) {
202 /* Unlikely to happen -
203 this works on all intel machines at least!
204 Revert to clock() */
205 return PyFloat_FromDouble(clock());
208 QueryPerformanceCounter(&now);
209 diff = LargeIntegerSubtract(now, ctrStart);
210 diff = LargeIntegerDivide(diff, divisor, &rem);
211 /* XXX - we assume both divide results fit in 32 bits. This is
212 true on Intels. First person who can afford a machine that
213 doesnt deserves to fix it :-)
215 return PyFloat_FromDouble((double)diff.LowPart +
216 ((double)rem.LowPart / (double)divisor.LowPart));
219 #define HAVE_CLOCK /* So it gets included in the methods */
220 #endif /* MS_WIN32 */
222 #ifdef HAVE_CLOCK
223 static char clock_doc[] =
224 "clock() -> floating point number\n\
226 Return the CPU time or real time since the start of the process or since\n\
227 the first call to clock(). This has as much precision as the system records.";
228 #endif
230 static PyObject *
231 time_sleep(self, args)
232 PyObject *self;
233 PyObject *args;
235 double secs;
236 if (!PyArg_Parse(args, "d", &secs))
237 return NULL;
238 if (floatsleep(secs) != 0)
239 return NULL;
240 Py_INCREF(Py_None);
241 return Py_None;
244 static char sleep_doc[] =
245 "sleep(seconds)\n\
247 Delay execution for a given number of seconds. The argument may be\n\
248 a floating point number for subsecond precision.";
250 static PyObject *
251 tmtotuple(p)
252 struct tm *p;
254 return Py_BuildValue("(iiiiiiiii)",
255 p->tm_year + 1900,
256 p->tm_mon + 1, /* Want January == 1 */
257 p->tm_mday,
258 p->tm_hour,
259 p->tm_min,
260 p->tm_sec,
261 (p->tm_wday + 6) % 7, /* Want Monday == 0 */
262 p->tm_yday + 1, /* Want January, 1 == 1 */
263 p->tm_isdst);
266 static PyObject *
267 time_convert(when, function)
268 time_t when;
269 struct tm * (*function) Py_PROTO((const time_t *));
271 struct tm *p;
272 errno = 0;
273 p = function(&when);
274 if (p == NULL) {
275 #ifdef EINVAL
276 if (errno == 0)
277 errno = EINVAL;
278 #endif
279 return PyErr_SetFromErrno(PyExc_IOError);
281 return tmtotuple(p);
284 static PyObject *
285 time_gmtime(self, args)
286 PyObject *self;
287 PyObject *args;
289 double when;
290 if (!PyArg_Parse(args, "d", &when))
291 return NULL;
292 return time_convert((time_t)when, gmtime);
295 static char gmtime_doc[] =
296 "gmtime(seconds) -> tuple\n\
298 Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a. GMT).";
300 static PyObject *
301 time_localtime(self, args)
302 PyObject *self;
303 PyObject *args;
305 double when;
306 if (!PyArg_Parse(args, "d", &when))
307 return NULL;
308 return time_convert((time_t)when, localtime);
311 static char localtime_doc[] =
312 "localtime(seconds) -> tuple\n\
313 Convert seconds since the Epoch to a time tuple expressing local time.";
315 static int
316 gettmarg(args, p)
317 PyObject *args;
318 struct tm *p;
320 int y;
321 memset((ANY *) p, '\0', sizeof(struct tm));
323 if (!PyArg_Parse(args, "(iiiiiiiii)",
325 &p->tm_mon,
326 &p->tm_mday,
327 &p->tm_hour,
328 &p->tm_min,
329 &p->tm_sec,
330 &p->tm_wday,
331 &p->tm_yday,
332 &p->tm_isdst))
333 return 0;
334 if (y < 1900) {
335 PyObject *accept = PyDict_GetItemString(moddict,
336 "accept2dyear");
337 if (accept == NULL || !PyInt_Check(accept) ||
338 PyInt_AsLong(accept) == 0) {
339 PyErr_SetString(PyExc_ValueError,
340 "year >= 1900 required");
341 return 0;
343 if (69 <= y && y <= 99)
344 y += 1900;
345 else if (0 <= y && y <= 68)
346 y += 2000;
347 else {
348 PyErr_SetString(PyExc_ValueError,
349 "year out of range (00-99, 1900-*)");
350 return 0;
353 p->tm_year = y - 1900;
354 p->tm_mon--;
355 p->tm_wday = (p->tm_wday + 1) % 7;
356 p->tm_yday--;
357 return 1;
360 #ifdef HAVE_STRFTIME
361 static PyObject *
362 time_strftime(self, args)
363 PyObject *self;
364 PyObject *args;
366 PyObject *tup;
367 struct tm buf;
368 const char *fmt;
369 char *outbuf = 0;
370 int i;
372 memset((ANY *) &buf, '\0', sizeof(buf));
374 if (!PyArg_ParseTuple(args, "sO", &fmt, &tup) || !gettmarg(tup, &buf))
375 return NULL;
376 /* I hate these functions that presume you know how big the output
377 * will be ahead of time...
379 for (i = 1024 ; i <= 8192 ; i += 1024) {
380 outbuf = malloc(i);
381 if (outbuf == NULL) {
382 return PyErr_NoMemory();
384 if (strftime(outbuf, i-1, fmt, &buf) != 0) {
385 PyObject *ret;
386 ret = PyString_FromString(outbuf);
387 free(outbuf);
388 return ret;
390 free(outbuf);
392 PyErr_SetString(PyExc_ValueError,
393 "bad strftime format or result too big");
394 return NULL;
397 static char strftime_doc[] =
398 "strftime(format, tuple) -> string\n\
400 Convert a time tuple to a string according to a format specification.\n\
401 See the library reference manual for formatting codes.";
402 #endif /* HAVE_STRFTIME */
404 #ifdef HAVE_STRPTIME
405 extern char *strptime(); /* In case it's not declared somehow */
407 static PyObject *
408 time_strptime(self, args)
409 PyObject *self;
410 PyObject *args;
412 struct tm tm;
413 char *fmt = "%a %b %d %H:%M:%S %Y";
414 char *buf;
415 char *s;
417 if (!PyArg_ParseTuple(args, "s|s", &buf, &fmt)) {
418 PyErr_SetString(PyExc_ValueError, "invalid argument");
419 return NULL;
421 memset((ANY *) &tm, '\0', sizeof(tm));
422 s = strptime(buf, fmt, &tm);
423 if (s == NULL) {
424 PyErr_SetString(PyExc_ValueError, "format mismatch");
425 return NULL;
427 while (*s && isspace(*s))
428 s++;
429 if (*s) {
430 PyErr_Format(PyExc_ValueError,
431 "unconverted data remains: '%.400s'", s);
432 return NULL;
434 return tmtotuple(&tm);
437 static char strptime_doc[] =
438 "strptime(format, string) -> tuple\n\
439 Parse a string to a time tuple according to a format specification.\n\
440 See the library reference manual for formatting codes (same as strftime()).";
441 #endif /* HAVE_STRPTIME */
443 static PyObject *
444 time_asctime(self, args)
445 PyObject *self;
446 PyObject *args;
448 struct tm buf;
449 char *p;
450 if (!gettmarg(args, &buf))
451 return NULL;
452 p = asctime(&buf);
453 if (p[24] == '\n')
454 p[24] = '\0';
455 return PyString_FromString(p);
458 static char asctime_doc[] =
459 "asctime(tuple) -> string\n\
461 Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.";
463 static PyObject *
464 time_ctime(self, args)
465 PyObject *self;
466 PyObject *args;
468 double dt;
469 time_t tt;
470 char *p;
471 if (!PyArg_Parse(args, "d", &dt))
472 return NULL;
473 tt = (time_t)dt;
474 p = ctime(&tt);
475 if (p == NULL) {
476 PyErr_SetString(PyExc_ValueError, "unconvertible time");
477 return NULL;
479 if (p[24] == '\n')
480 p[24] = '\0';
481 return PyString_FromString(p);
484 static char ctime_doc[] =
485 "ctime(seconds) -> string\n\
487 Convert a time in seconds since the Epoch to a string in local time.\n\
488 This is equivalent to asctime(localtime(seconds)).";
490 #ifdef HAVE_MKTIME
491 static PyObject *
492 time_mktime(self, args)
493 PyObject *self;
494 PyObject *args;
496 struct tm buf;
497 time_t tt;
498 tt = time(&tt);
499 buf = *localtime(&tt);
500 if (!gettmarg(args, &buf))
501 return NULL;
502 tt = mktime(&buf);
503 if (tt == (time_t)(-1)) {
504 PyErr_SetString(PyExc_OverflowError,
505 "mktime argument out of range");
506 return NULL;
508 return PyFloat_FromDouble((double)tt);
511 static char mktime_doc[] =
512 "mktime(tuple) -> floating point number\n\
514 Convert a time tuple in local time to seconds since the Epoch.";
515 #endif /* HAVE_MKTIME */
517 static PyMethodDef time_methods[] = {
518 {"time", time_time, 0, time_doc},
519 #ifdef HAVE_CLOCK
520 {"clock", time_clock, 0, clock_doc},
521 #endif
522 {"sleep", time_sleep, 0, sleep_doc},
523 {"gmtime", time_gmtime, 0, gmtime_doc},
524 {"localtime", time_localtime, 0, localtime_doc},
525 {"asctime", time_asctime, 0, asctime_doc},
526 {"ctime", time_ctime, 0, ctime_doc},
527 #ifdef HAVE_MKTIME
528 {"mktime", time_mktime, 0, mktime_doc},
529 #endif
530 #ifdef HAVE_STRFTIME
531 {"strftime", time_strftime, 1, strftime_doc},
532 #endif
533 #ifdef HAVE_STRPTIME
534 {"strptime", time_strptime, 1, strptime_doc},
535 #endif
536 {NULL, NULL} /* sentinel */
539 static void
540 ins(d, name, v)
541 PyObject *d;
542 char *name;
543 PyObject *v;
545 if (v == NULL)
546 Py_FatalError("Can't initialize time module -- NULL value");
547 if (PyDict_SetItemString(d, name, v) != 0)
548 Py_FatalError(
549 "Can't initialize time module -- PyDict_SetItemString failed");
550 Py_DECREF(v);
553 static char module_doc[] =
554 "This module provides various functions to manipulate time values.\n\
556 There are two standard representations of time. One is the number\n\
557 of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\
558 or a floating point number (to represent fractions of seconds).\n\
559 The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
560 The actual value can be retrieved by calling gmtime(0).\n\
562 The other representation is a tuple of 9 integers giving local time.\n\
563 The tuple items are:\n\
564 year (four digits, e.g. 1998)\n\
565 month (1-12)\n\
566 day (1-31)\n\
567 hours (0-23)\n\
568 minutes (0-59)\n\
569 seconds (0-61, to allow for leap seconds)\n\
570 weekday (0-6, Monday is 0)\n\
571 Julian day (day in the year, 1-366)\n\
572 DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
573 If the DST flag is 0, the time is given in the regular time zone;\n\
574 if it is 1, the time is given in the DST time zone;\n\
575 if it is -1, mktime() should guess based on the date and time.\n\
577 Variables:\n\
579 timezone -- difference in seconds between UTC and local standard time\n\
580 altzone -- difference in seconds between UTC and local DST time\n\
581 daylight -- whether local time should reflect DST\n\
582 tzname -- tuple of (standard time zone name, DST time zone name)\n\
584 Functions:\n\
586 time() -- return current time in seconds since the Epoch as a float\n\
587 clock() -- return CPU time since process start as a float\n\
588 sleep() -- delay for a number of seconds given as a float\n\
589 gmtime() -- convert seconds since Epoch to UTC tuple\n\
590 localtime() -- convert seconds since Epoch to local time tuple\n\
591 asctime() -- convert time tuple to string\n\
592 ctime() -- convert time in seconds to string\n\
593 mktime() -- convert local time tuple to seconds since Epoch\n\
594 strftime() -- convert time tuple to string according to format specification\n\
595 strptime() -- parse string to time tuple according to format specification\n\
599 void
600 inittime()
602 PyObject *m, *d;
603 char *p;
604 m = Py_InitModule3("time", time_methods, module_doc);
605 d = PyModule_GetDict(m);
606 /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
607 p = getenv("PYTHONY2K");
608 ins(d, "accept2dyear", PyInt_FromLong((long) (!p || !*p)));
609 /* Squirrel away the module's dictionary for the y2k check */
610 Py_INCREF(d);
611 moddict = d;
612 #ifdef HAVE_TZNAME
613 tzset();
614 #ifdef PYOS_OS2
615 ins(d, "timezone", PyInt_FromLong((long)_timezone));
616 #else /* !PYOS_OS2 */
617 ins(d, "timezone", PyInt_FromLong((long)timezone));
618 #endif /* PYOS_OS2 */
619 #ifdef HAVE_ALTZONE
620 ins(d, "altzone", PyInt_FromLong((long)altzone));
621 #else
622 #ifdef PYOS_OS2
623 ins(d, "altzone", PyInt_FromLong((long)_timezone-3600));
624 #else /* !PYOS_OS2 */
625 ins(d, "altzone", PyInt_FromLong((long)timezone-3600));
626 #endif /* PYOS_OS2 */
627 #endif
628 ins(d, "daylight", PyInt_FromLong((long)daylight));
629 ins(d, "tzname", Py_BuildValue("(zz)", tzname[0], tzname[1]));
630 #else /* !HAVE_TZNAME */
631 #if HAVE_TM_ZONE
633 #define YEAR ((time_t)((365 * 24 + 6) * 3600))
634 time_t t;
635 struct tm *p;
636 long winterzone, summerzone;
637 char wintername[10], summername[10];
638 /* XXX This won't work on the southern hemisphere.
639 XXX Anybody got a better idea? */
640 t = (time((time_t *)0) / YEAR) * YEAR;
641 p = localtime(&t);
642 winterzone = -p->tm_gmtoff;
643 strncpy(wintername, p->tm_zone ? p->tm_zone : " ", 9);
644 wintername[9] = '\0';
645 t += YEAR/2;
646 p = localtime(&t);
647 summerzone = -p->tm_gmtoff;
648 strncpy(summername, p->tm_zone ? p->tm_zone : " ", 9);
649 summername[9] = '\0';
650 ins(d, "timezone", PyInt_FromLong(winterzone));
651 ins(d, "altzone", PyInt_FromLong(summerzone));
652 ins(d, "daylight",
653 PyInt_FromLong((long)(winterzone != summerzone)));
654 ins(d, "tzname",
655 Py_BuildValue("(zz)", wintername, summername));
657 #else
658 #ifdef macintosh
659 /* The only thing we can obtain is the current timezone
660 ** (and whether dst is currently _active_, but that is not what
661 ** we're looking for:-( )
663 initmactimezone();
664 ins(d, "timezone", PyInt_FromLong(timezone));
665 ins(d, "altzone", PyInt_FromLong(timezone));
666 ins(d, "daylight", PyInt_FromLong((long)0));
667 ins(d, "tzname", Py_BuildValue("(zz)", "", ""));
668 #endif /* macintosh */
669 #endif /* HAVE_TM_ZONE */
670 #endif /* !HAVE_TZNAME */
671 if (PyErr_Occurred())
672 Py_FatalError("Can't initialize time module");
676 /* Implement floattime() for various platforms */
678 static double
679 floattime()
681 /* There are three ways to get the time:
682 (1) gettimeofday() -- resolution in microseconds
683 (2) ftime() -- resolution in milliseconds
684 (3) time() -- resolution in seconds
685 In all cases the return value is a float in seconds.
686 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
687 fail, so we fall back on ftime() or time().
688 Note: clock resolution does not imply clock accuracy! */
689 #ifdef HAVE_GETTIMEOFDAY
691 struct timeval t;
692 #ifdef GETTIMEOFDAY_NO_TZ
693 if (gettimeofday(&t) == 0)
694 return (double)t.tv_sec + t.tv_usec*0.000001;
695 #else /* !GETTIMEOFDAY_NO_TZ */
696 if (gettimeofday(&t, (struct timezone *)NULL) == 0)
697 return (double)t.tv_sec + t.tv_usec*0.000001;
698 #endif /* !GETTIMEOFDAY_NO_TZ */
700 #endif /* !HAVE_GETTIMEOFDAY */
702 #if defined(HAVE_FTIME) && !defined(__BEOS__)
703 struct timeb t;
704 ftime(&t);
705 return (double)t.time + (double)t.millitm * (double)0.001;
706 #else /* !HAVE_FTIME */
707 time_t secs;
708 time(&secs);
709 return (double)secs;
710 #endif /* !HAVE_FTIME */
715 /* Implement floatsleep() for various platforms.
716 When interrupted (or when another error occurs), return -1 and
717 set an exception; else return 0. */
719 static int
720 #ifdef MPW
721 floatsleep(double secs)
722 #else
723 floatsleep(secs)
724 double secs;
725 #endif /* MPW */
727 /* XXX Should test for MS_WIN32 first! */
728 #if defined(HAVE_SELECT) && !defined(__BEOS__)
729 struct timeval t;
730 double frac;
731 frac = fmod(secs, 1.0);
732 secs = floor(secs);
733 t.tv_sec = (long)secs;
734 t.tv_usec = (long)(frac*1000000.0);
735 Py_BEGIN_ALLOW_THREADS
736 if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
737 Py_BLOCK_THREADS
738 PyErr_SetFromErrno(PyExc_IOError);
739 return -1;
741 Py_END_ALLOW_THREADS
742 #else /* !HAVE_SELECT || __BEOS__ */
743 #ifdef macintosh
744 #define MacTicks (* (long *)0x16A)
745 long deadline;
746 deadline = MacTicks + (long)(secs * 60.0);
747 while (MacTicks < deadline) {
748 /* XXX Should call some yielding function here */
749 if (PyErr_CheckSignals())
750 return -1;
752 #else /* !macintosh */
753 #if defined(__WATCOMC__) && !defined(__QNX__)
754 /* XXX Can't interrupt this sleep */
755 Py_BEGIN_ALLOW_THREADS
756 delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
757 Py_END_ALLOW_THREADS
758 #else /* !__WATCOMC__ || __QNX__ */
759 #ifdef MSDOS
760 struct timeb t1, t2;
761 double frac;
762 extern double fmod Py_PROTO((double, double));
763 extern double floor Py_PROTO((double));
764 if (secs <= 0.0)
765 return;
766 frac = fmod(secs, 1.0);
767 secs = floor(secs);
768 ftime(&t1);
769 t2.time = t1.time + (int)secs;
770 t2.millitm = t1.millitm + (int)(frac*1000.0);
771 while (t2.millitm >= 1000) {
772 t2.time++;
773 t2.millitm -= 1000;
775 for (;;) {
776 #ifdef QUICKWIN
777 Py_BEGIN_ALLOW_THREADS
778 _wyield();
779 Py_END_ALLOW_THREADS
780 #endif
781 if (PyErr_CheckSignals())
782 return -1;
783 ftime(&t1);
784 if (t1.time > t2.time ||
785 t1.time == t2.time && t1.millitm >= t2.millitm)
786 break;
788 #else /* !MSDOS */
789 #ifdef MS_WIN32
790 /* XXX Can't interrupt this sleep */
791 Py_BEGIN_ALLOW_THREADS
792 Sleep((int)(secs*1000));
793 Py_END_ALLOW_THREADS
794 #else /* !MS_WIN32 */
795 #ifdef PYOS_OS2
796 /* This Sleep *IS* Interruptable by Exceptions */
797 Py_BEGIN_ALLOW_THREADS
798 if (DosSleep(secs * 1000) != NO_ERROR) {
799 Py_BLOCK_THREADS
800 PyErr_SetFromErrno(PyExc_IOError);
801 return -1;
803 Py_END_ALLOW_THREADS
804 #else /* !PYOS_OS2 */
805 #ifdef __BEOS__
806 /* This sleep *CAN BE* interrupted. */
808 bigtime_t frac, seconds;
810 extern double fmod Py_PROTO((double,double));
811 extern double floor Py_PROTO((double));
813 if( secs <= 0.0 ) {
814 return;
817 frac = (bigtime_t)fmod( secs, 1.0 );
818 seconds = (bigtime_t)floor( secs );
820 Py_BEGIN_ALLOW_THREADS
821 if( snooze( seconds * (bigtime_t)1000 + frac ) == B_INTERRUPTED ) {
822 Py_BLOCK_THREADS
823 PyErr_SetFromErrno( PyExc_IOError );
824 return -1;
826 Py_END_ALLOW_THREADS
828 #else /* !__BEOS__ */
829 /* XXX Can't interrupt this sleep */
830 Py_BEGIN_ALLOW_THREADS
831 sleep((int)secs);
832 Py_END_ALLOW_THREADS
833 #endif /* !__BEOS__ */
834 #endif /* !PYOS_OS2 */
835 #endif /* !MS_WIN32 */
836 #endif /* !MSDOS */
837 #endif /* !__WATCOMC__ || __QNX__ */
838 #endif /* !macintosh */
839 #endif /* !HAVE_SELECT */
840 return 0;