timemodule.c revision 446ccfe1ac97f5dc05a0ba89fc0a912981235099
1/*********************************************************** 2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, 3The Netherlands. 4 5 All Rights Reserved 6 7Permission to use, copy, modify, and distribute this software and its 8documentation for any purpose and without fee is hereby granted, 9provided that the above copyright notice appear in all copies and that 10both that copyright notice and this permission notice appear in 11supporting documentation, and that the names of Stichting Mathematisch 12Centrum or CWI or Corporation for National Research Initiatives or 13CNRI not be used in advertising or publicity pertaining to 14distribution of the software without specific, written prior 15permission. 16 17While CWI is the initial source for this software, a modified version 18is made available by the Corporation for National Research Initiatives 19(CNRI) at the Internet address ftp://ftp.python.org. 20 21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH 22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH 24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 28PERFORMANCE OF THIS SOFTWARE. 29 30******************************************************************/ 31 32/* Time module */ 33 34#include "Python.h" 35 36#include <ctype.h> 37 38#ifdef HAVE_SELECT 39#include "mymath.h" 40#endif 41 42#ifdef macintosh 43#include <time.h> 44#else 45#include <sys/types.h> 46#endif 47 48#ifdef QUICKWIN 49#include <io.h> 50#endif 51 52#ifdef HAVE_UNISTD_H 53#include <unistd.h> 54#endif 55 56#if defined(HAVE_SELECT) && !defined(__BEOS__) 57#include "myselect.h" 58#else 59#include "mytime.h" 60#endif 61 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) 68extern int ftime(); 69#endif /* MS_WINDOWS */ 70#endif /* HAVE_FTIME */ 71 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__ */ 86 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 */ 92 93#if defined(PYCC_VACPP) 94#include <sys/time.h> 95#endif 96 97#ifdef __BEOS__ 98/* For bigtime_t, snooze(). - [cjh] */ 99#include <support/SupportDefs.h> 100#include <kernel/OS.h> 101#endif 102 103/* Forward declarations */ 104static int floatsleep Py_PROTO((double)); 105static double floattime Py_PROTO(()); 106 107/* For Y2K check */ 108static PyObject *moddict; 109 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. 117*/ 118static long timezone; 119 120static void 121initmactimezone() 122{ 123 MachineLocation loc; 124 long delta; 125 126 ReadLocation(&loc); 127 128 if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0) 129 return; 130 131 delta = loc.u.gmtDelta & 0x00FFFFFF; 132 133 if (delta & 0x00800000) 134 delta |= 0xFF000000; 135 136 timezone = -delta; 137} 138#endif /* macintosh */ 139 140 141static PyObject * 142time_time(self, args) 143 PyObject *self; 144 PyObject *args; 145{ 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; 153 } 154 return PyFloat_FromDouble(secs); 155} 156 157static char time_doc[] = 158"time() -> floating point number\n\ 159\n\ 160Return the current time in seconds since the Epoch.\n\ 161Fractions of a second may be present if the system clock provides them."; 162 163#ifdef HAVE_CLOCK 164 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 172 173static PyObject * 174time_clock(self, args) 175 PyObject *self; 176 PyObject *args; 177{ 178 if (!PyArg_NoArgs(args)) 179 return NULL; 180 return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC); 181} 182#endif /* HAVE_CLOCK */ 183 184#ifdef MS_WIN32 185/* Due to Mark Hammond */ 186static PyObject * 187time_clock(self, args) 188 PyObject *self; 189 PyObject *args; 190{ 191 static LARGE_INTEGER ctrStart; 192 static LARGE_INTEGER divisor = {0,0}; 193 LARGE_INTEGER now, diff, rem; 194 195 if (!PyArg_NoArgs(args)) 196 return NULL; 197 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()); 206 } 207 } 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 :-) 214 */ 215 return PyFloat_FromDouble((double)diff.LowPart + 216 ((double)rem.LowPart / (double)divisor.LowPart)); 217} 218 219#define HAVE_CLOCK /* So it gets included in the methods */ 220#endif /* MS_WIN32 */ 221 222#ifdef HAVE_CLOCK 223static char clock_doc[] = 224"clock() -> floating point number\n\ 225\n\ 226Return the CPU time or real time since the start of the process or since\n\ 227the first call to clock(). This has as much precision as the system records."; 228#endif 229 230static PyObject * 231time_sleep(self, args) 232 PyObject *self; 233 PyObject *args; 234{ 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; 242} 243 244static char sleep_doc[] = 245"sleep(seconds)\n\ 246\n\ 247Delay execution for a given number of seconds. The argument may be\n\ 248a floating point number for subsecond precision."; 249 250static PyObject * 251tmtotuple(p) 252 struct tm *p; 253{ 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); 264} 265 266static PyObject * 267time_convert(when, function) 268 time_t when; 269 struct tm * (*function) Py_PROTO((const time_t *)); 270{ 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); 280 } 281 return tmtotuple(p); 282} 283 284static PyObject * 285time_gmtime(self, args) 286 PyObject *self; 287 PyObject *args; 288{ 289 double when; 290 if (!PyArg_Parse(args, "d", &when)) 291 return NULL; 292 return time_convert((time_t)when, gmtime); 293} 294 295static char gmtime_doc[] = 296"gmtime(seconds) -> tuple\n\ 297\n\ 298Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a. GMT)."; 299 300static PyObject * 301time_localtime(self, args) 302 PyObject *self; 303 PyObject *args; 304{ 305 double when; 306 if (!PyArg_Parse(args, "d", &when)) 307 return NULL; 308 return time_convert((time_t)when, localtime); 309} 310 311static char localtime_doc[] = 312"localtime(seconds) -> tuple\n\ 313Convert seconds since the Epoch to a time tuple expressing local time."; 314 315static int 316gettmarg(args, p) 317 PyObject *args; 318 struct tm *p; 319{ 320 int y; 321 memset((ANY *) p, '\0', sizeof(struct tm)); 322 323 if (!PyArg_Parse(args, "(iiiiiiiii)", 324 &y, 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; 342 } 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; 351 } 352 } 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; 358} 359 360#ifdef HAVE_STRFTIME 361static PyObject * 362time_strftime(self, args) 363 PyObject *self; 364 PyObject *args; 365{ 366 PyObject *tup; 367 struct tm buf; 368 const char *fmt; 369 char *outbuf = 0; 370 int i; 371 372 memset((ANY *) &buf, '\0', sizeof(buf)); 373 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... 378 */ 379 for (i = 1024 ; i <= 8192 ; i += 1024) { 380 outbuf = malloc(i); 381 if (outbuf == NULL) { 382 return PyErr_NoMemory(); 383 } 384 if (strftime(outbuf, i-1, fmt, &buf) != 0) { 385 PyObject *ret; 386 ret = PyString_FromString(outbuf); 387 free(outbuf); 388 return ret; 389 } 390 free(outbuf); 391 } 392 PyErr_SetString(PyExc_ValueError, 393 "bad strftime format or result too big"); 394 return NULL; 395} 396 397static char strftime_doc[] = 398"strftime(format, tuple) -> string\n\ 399\n\ 400Convert a time tuple to a string according to a format specification.\n\ 401See the library reference manual for formatting codes."; 402#endif /* HAVE_STRFTIME */ 403 404#ifdef HAVE_STRPTIME 405/* extern char *strptime(); /* Enable this if it's not declared in <time.h> */ 406 407static PyObject * 408time_strptime(self, args) 409 PyObject *self; 410 PyObject *args; 411{ 412 struct tm tm; 413 char *fmt = "%a %b %d %H:%M:%S %Y"; 414 char *buf; 415 char *s; 416 417 if (!PyArg_ParseTuple(args, "s|s", &buf, &fmt)) { 418 PyErr_SetString(PyExc_ValueError, "invalid argument"); 419 return NULL; 420 } 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; 426 } 427 while (*s && isspace(*s)) 428 s++; 429 if (*s) { 430 PyErr_Format(PyExc_ValueError, 431 "unconverted data remains: '%.400s'", s); 432 return NULL; 433 } 434 return tmtotuple(&tm); 435} 436 437static char strptime_doc[] = 438"strptime(string, format) -> tuple\n\ 439Parse a string to a time tuple according to a format specification.\n\ 440See the library reference manual for formatting codes (same as strftime())."; 441#endif /* HAVE_STRPTIME */ 442 443static PyObject * 444time_asctime(self, args) 445 PyObject *self; 446 PyObject *args; 447{ 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); 456} 457 458static char asctime_doc[] = 459"asctime(tuple) -> string\n\ 460\n\ 461Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'."; 462 463static PyObject * 464time_ctime(self, args) 465 PyObject *self; 466 PyObject *args; 467{ 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; 478 } 479 if (p[24] == '\n') 480 p[24] = '\0'; 481 return PyString_FromString(p); 482} 483 484static char ctime_doc[] = 485"ctime(seconds) -> string\n\ 486\n\ 487Convert a time in seconds since the Epoch to a string in local time.\n\ 488This is equivalent to asctime(localtime(seconds))."; 489 490#ifdef HAVE_MKTIME 491static PyObject * 492time_mktime(self, args) 493 PyObject *self; 494 PyObject *args; 495{ 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; 507 } 508 return PyFloat_FromDouble((double)tt); 509} 510 511static char mktime_doc[] = 512"mktime(tuple) -> floating point number\n\ 513\n\ 514Convert a time tuple in local time to seconds since the Epoch."; 515#endif /* HAVE_MKTIME */ 516 517static 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 */ 537}; 538 539static void 540ins(d, name, v) 541 PyObject *d; 542 char *name; 543 PyObject *v; 544{ 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); 551} 552 553static char module_doc[] = 554"This module provides various functions to manipulate time values.\n\ 555\n\ 556There are two standard representations of time. One is the number\n\ 557of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\ 558or a floating point number (to represent fractions of seconds).\n\ 559The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\ 560The actual value can be retrieved by calling gmtime(0).\n\ 561\n\ 562The other representation is a tuple of 9 integers giving local time.\n\ 563The 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\ 573If the DST flag is 0, the time is given in the regular time zone;\n\ 574if it is 1, the time is given in the DST time zone;\n\ 575if it is -1, mktime() should guess based on the date and time.\n\ 576\n\ 577Variables:\n\ 578\n\ 579timezone -- difference in seconds between UTC and local standard time\n\ 580altzone -- difference in seconds between UTC and local DST time\n\ 581daylight -- whether local time should reflect DST\n\ 582tzname -- tuple of (standard time zone name, DST time zone name)\n\ 583\n\ 584Functions:\n\ 585\n\ 586time() -- return current time in seconds since the Epoch as a float\n\ 587clock() -- return CPU time since process start as a float\n\ 588sleep() -- delay for a number of seconds given as a float\n\ 589gmtime() -- convert seconds since Epoch to UTC tuple\n\ 590localtime() -- convert seconds since Epoch to local time tuple\n\ 591asctime() -- convert time tuple to string\n\ 592ctime() -- convert time in seconds to string\n\ 593mktime() -- convert local time tuple to seconds since Epoch\n\ 594strftime() -- convert time tuple to string according to format specification\n\ 595strptime() -- parse string to time tuple according to format specification\n\ 596"; 597 598 599DL_EXPORT(void) 600inittime() 601{ 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 632 { 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)); 656 } 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:-( ) 662 */ 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"); 673} 674 675 676/* Implement floattime() for various platforms */ 677 678static double 679floattime() 680{ 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 690 { 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 */ 699 } 700#endif /* !HAVE_GETTIMEOFDAY */ 701 { 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 */ 711 } 712} 713 714 715/* Implement floatsleep() for various platforms. 716 When interrupted (or when another error occurs), return -1 and 717 set an exception; else return 0. */ 718 719static int 720#ifdef MPW 721floatsleep(double secs) 722#else 723 floatsleep(secs) 724 double secs; 725#endif /* MPW */ 726{ 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; 740 } 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; 751 } 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; 774 } 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; 787 } 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; 802 } 803 Py_END_ALLOW_THREADS 804#else /* !PYOS_OS2 */ 805#ifdef __BEOS__ 806 /* This sleep *CAN BE* interrupted. */ 807 { 808 bigtime_t frac, seconds; 809 810 extern double fmod Py_PROTO((double,double)); 811 extern double floor Py_PROTO((double)); 812 813 if( secs <= 0.0 ) { 814 return; 815 } 816 817 frac = (bigtime_t)fmod( secs, 1.0 ); 818 seconds = (bigtime_t)floor( secs ); 819 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; 825 } 826 Py_END_ALLOW_THREADS 827 } 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; 841} 842