timemodule.c revision a1abb728bc0d3898539ea89effa7906a50366f1a
1/*********************************************************** 2Copyright (c) 2000, BeOpen.com. 3Copyright (c) 1995-2000, Corporation for National Research Initiatives. 4Copyright (c) 1990-1995, Stichting Mathematisch Centrum. 5All rights reserved. 6 7See the file "Misc/COPYRIGHT" for information on usage and 8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. 9******************************************************************/ 10 11/* Time module */ 12 13#include "Python.h" 14 15#include <ctype.h> 16 17#ifdef macintosh 18#include <time.h> 19#include <OSUtils.h> 20#ifdef USE_GUSI2 21/* GUSI, the I/O library which has the time() function and such uses the 22** Mac epoch of 1904. MSL, the C library which has localtime() and so uses 23** the ANSI epoch of 1900. 24*/ 25#define GUSI_TO_MSL_EPOCH (4*365*24*60*60) 26#endif /* USE_GUSI2 */ 27#else 28#include <sys/types.h> 29#endif 30 31#ifdef QUICKWIN 32#include <io.h> 33#endif 34 35#ifdef HAVE_UNISTD_H 36#include <unistd.h> 37#endif 38 39#ifdef HAVE_FTIME 40#include <sys/timeb.h> 41#if !defined(MS_WINDOWS) && !defined(PYOS_OS2) 42extern int ftime(struct timeb *); 43#endif /* MS_WINDOWS */ 44#endif /* HAVE_FTIME */ 45 46#if defined(__WATCOMC__) && !defined(__QNX__) 47#include <i86.h> 48#else 49#ifdef MS_WINDOWS 50#include <windows.h> 51#ifdef MS_WIN16 52/* These overrides not needed for Win32 */ 53#define timezone _timezone 54#define tzname _tzname 55#define daylight _daylight 56#define altzone _altzone 57#endif /* MS_WIN16 */ 58#endif /* MS_WINDOWS */ 59#endif /* !__WATCOMC__ || __QNX__ */ 60 61#if defined(MS_WIN32) && !defined(MS_WIN64) 62/* Win32 has better clock replacement 63 XXX Win64 does not yet, but might when the platform matures. */ 64#include <largeint.h> 65#undef HAVE_CLOCK /* We have our own version down below */ 66#endif /* MS_WIN32 && !MS_WIN64 */ 67 68#if defined(PYCC_VACPP) 69#include <sys/time.h> 70#endif 71 72#ifdef __BEOS__ 73/* For bigtime_t, snooze(). - [cjh] */ 74#include <support/SupportDefs.h> 75#include <kernel/OS.h> 76#ifndef CLOCKS_PER_SEC 77/* C'mon, fix the bloody headers... - [cjh] */ 78#define CLOCKS_PER_SEC 1000 79#endif 80#endif 81 82/* Forward declarations */ 83static int floatsleep(double); 84static double floattime(void); 85 86/* For Y2K check */ 87static PyObject *moddict; 88 89#ifdef macintosh 90/* Our own timezone. We have enough information to deduce whether 91** DST is on currently, but unfortunately we cannot put it to good 92** use because we don't know the rules (and that is needed to have 93** localtime() return correct tm_isdst values for times other than 94** the current time. So, we cop out and only tell the user the current 95** timezone. 96*/ 97static long timezone; 98 99static void 100initmactimezone(void) 101{ 102 MachineLocation loc; 103 long delta; 104 105 ReadLocation(&loc); 106 107 if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0) 108 return; 109 110 delta = loc.u.gmtDelta & 0x00FFFFFF; 111 112 if (delta & 0x00800000) 113 delta |= 0xFF000000; 114 115 timezone = -delta; 116} 117#endif /* macintosh */ 118 119 120static PyObject * 121time_time(PyObject *self, PyObject *args) 122{ 123 double secs; 124 if (!PyArg_NoArgs(args)) 125 return NULL; 126 secs = floattime(); 127 if (secs == 0.0) { 128 PyErr_SetFromErrno(PyExc_IOError); 129 return NULL; 130 } 131 return PyFloat_FromDouble(secs); 132} 133 134static char time_doc[] = 135"time() -> floating point number\n\ 136\n\ 137Return the current time in seconds since the Epoch.\n\ 138Fractions of a second may be present if the system clock provides them."; 139 140#ifdef HAVE_CLOCK 141 142#ifndef CLOCKS_PER_SEC 143#ifdef CLK_TCK 144#define CLOCKS_PER_SEC CLK_TCK 145#else 146#define CLOCKS_PER_SEC 1000000 147#endif 148#endif 149 150static PyObject * 151time_clock(PyObject *self, PyObject *args) 152{ 153 if (!PyArg_NoArgs(args)) 154 return NULL; 155 return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC); 156} 157#endif /* HAVE_CLOCK */ 158 159#if defined(MS_WIN32) && !defined(MS_WIN64) 160/* Due to Mark Hammond */ 161static PyObject * 162time_clock(PyObject *self, PyObject *args) 163{ 164 static LARGE_INTEGER ctrStart; 165 static LARGE_INTEGER divisor = {0,0}; 166 LARGE_INTEGER now, diff, rem; 167 168 if (!PyArg_NoArgs(args)) 169 return NULL; 170 171 if (LargeIntegerEqualToZero(divisor)) { 172 QueryPerformanceCounter(&ctrStart); 173 if (!QueryPerformanceFrequency(&divisor) || 174 LargeIntegerEqualToZero(divisor)) { 175 /* Unlikely to happen - 176 this works on all intel machines at least! 177 Revert to clock() */ 178 return PyFloat_FromDouble(clock()); 179 } 180 } 181 QueryPerformanceCounter(&now); 182 diff = LargeIntegerSubtract(now, ctrStart); 183 diff = LargeIntegerDivide(diff, divisor, &rem); 184 /* XXX - we assume both divide results fit in 32 bits. This is 185 true on Intels. First person who can afford a machine that 186 doesnt deserves to fix it :-) 187 */ 188 return PyFloat_FromDouble((double)diff.LowPart + 189 ((double)rem.LowPart / (double)divisor.LowPart)); 190} 191 192#define HAVE_CLOCK /* So it gets included in the methods */ 193#endif /* MS_WIN32 && !MS_WIN64 */ 194 195#ifdef HAVE_CLOCK 196static char clock_doc[] = 197"clock() -> floating point number\n\ 198\n\ 199Return the CPU time or real time since the start of the process or since\n\ 200the first call to clock(). This has as much precision as the system records."; 201#endif 202 203static PyObject * 204time_sleep(PyObject *self, PyObject *args) 205{ 206 double secs; 207 if (!PyArg_Parse(args, "d", &secs)) 208 return NULL; 209 if (floatsleep(secs) != 0) 210 return NULL; 211 Py_INCREF(Py_None); 212 return Py_None; 213} 214 215static char sleep_doc[] = 216"sleep(seconds)\n\ 217\n\ 218Delay execution for a given number of seconds. The argument may be\n\ 219a floating point number for subsecond precision."; 220 221static PyObject * 222tmtotuple(struct tm *p) 223{ 224 return Py_BuildValue("(iiiiiiiii)", 225 p->tm_year + 1900, 226 p->tm_mon + 1, /* Want January == 1 */ 227 p->tm_mday, 228 p->tm_hour, 229 p->tm_min, 230 p->tm_sec, 231 (p->tm_wday + 6) % 7, /* Want Monday == 0 */ 232 p->tm_yday + 1, /* Want January, 1 == 1 */ 233 p->tm_isdst); 234} 235 236static PyObject * 237time_convert(time_t when, struct tm * (*function)(const time_t *)) 238{ 239 struct tm *p; 240 errno = 0; 241#if defined(macintosh) && defined(USE_GUSI204) 242 when = when + GUSI_TO_MSL_EPOCH; 243#endif 244 p = function(&when); 245 if (p == NULL) { 246#ifdef EINVAL 247 if (errno == 0) 248 errno = EINVAL; 249#endif 250 return PyErr_SetFromErrno(PyExc_IOError); 251 } 252 return tmtotuple(p); 253} 254 255static PyObject * 256time_gmtime(PyObject *self, PyObject *args) 257{ 258 double when; 259 if (!PyArg_Parse(args, "d", &when)) 260 return NULL; 261 return time_convert((time_t)when, gmtime); 262} 263 264static char gmtime_doc[] = 265"gmtime(seconds) -> tuple\n\ 266\n\ 267Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a. GMT)."; 268 269static PyObject * 270time_localtime(PyObject *self, PyObject *args) 271{ 272 double when; 273 if (!PyArg_Parse(args, "d", &when)) 274 return NULL; 275 return time_convert((time_t)when, localtime); 276} 277 278static char localtime_doc[] = 279"localtime(seconds) -> tuple\n\ 280Convert seconds since the Epoch to a time tuple expressing local time."; 281 282static int 283gettmarg(PyObject *args, struct tm *p) 284{ 285 int y; 286 memset((void *) p, '\0', sizeof(struct tm)); 287 288 if (!PyArg_Parse(args, "(iiiiiiiii)", 289 &y, 290 &p->tm_mon, 291 &p->tm_mday, 292 &p->tm_hour, 293 &p->tm_min, 294 &p->tm_sec, 295 &p->tm_wday, 296 &p->tm_yday, 297 &p->tm_isdst)) 298 return 0; 299 if (y < 1900) { 300 PyObject *accept = PyDict_GetItemString(moddict, 301 "accept2dyear"); 302 if (accept == NULL || !PyInt_Check(accept) || 303 PyInt_AsLong(accept) == 0) { 304 PyErr_SetString(PyExc_ValueError, 305 "year >= 1900 required"); 306 return 0; 307 } 308 if (69 <= y && y <= 99) 309 y += 1900; 310 else if (0 <= y && y <= 68) 311 y += 2000; 312 else { 313 PyErr_SetString(PyExc_ValueError, 314 "year out of range (00-99, 1900-*)"); 315 return 0; 316 } 317 } 318 p->tm_year = y - 1900; 319 p->tm_mon--; 320 p->tm_wday = (p->tm_wday + 1) % 7; 321 p->tm_yday--; 322 return 1; 323} 324 325#ifdef HAVE_STRFTIME 326static PyObject * 327time_strftime(PyObject *self, PyObject *args) 328{ 329 PyObject *tup; 330 struct tm buf; 331 const char *fmt; 332 size_t fmtlen, buflen; 333 char *outbuf = 0; 334 size_t i; 335 336 memset((void *) &buf, '\0', sizeof(buf)); 337 338 if (!PyArg_ParseTuple(args, "sO:strftime", &fmt, &tup) 339 || !gettmarg(tup, &buf)) 340 return NULL; 341 fmtlen = strlen(fmt); 342 343 /* I hate these functions that presume you know how big the output 344 * will be ahead of time... 345 */ 346 for (i = 1024; ; i += i) { 347 outbuf = malloc(i); 348 if (outbuf == NULL) { 349 return PyErr_NoMemory(); 350 } 351 buflen = strftime(outbuf, i, fmt, &buf); 352 if (buflen > 0 || i >= 256 * fmtlen) { 353 /* If the buffer is 256 times as long as the format, 354 it's probably not failing for lack of room! 355 More likely, the format yields an empty result, 356 e.g. an empty format, or %Z when the timezone 357 is unknown. */ 358 PyObject *ret; 359 ret = PyString_FromStringAndSize(outbuf, buflen); 360 free(outbuf); 361 return ret; 362 } 363 free(outbuf); 364 } 365} 366 367static char strftime_doc[] = 368"strftime(format, tuple) -> string\n\ 369\n\ 370Convert a time tuple to a string according to a format specification.\n\ 371See the library reference manual for formatting codes."; 372#endif /* HAVE_STRFTIME */ 373 374#ifdef HAVE_STRPTIME 375 376#if 0 377/* Enable this if it's not declared in <time.h> */ 378extern char *strptime(const char *, const char *, struct tm *); 379#endif 380 381static PyObject * 382time_strptime(PyObject *self, PyObject *args) 383{ 384 struct tm tm; 385 char *fmt = "%a %b %d %H:%M:%S %Y"; 386 char *buf; 387 char *s; 388 389 if (!PyArg_ParseTuple(args, "s|s:strptime", &buf, &fmt)) 390 return NULL; 391 memset((void *) &tm, '\0', sizeof(tm)); 392 s = strptime(buf, fmt, &tm); 393 if (s == NULL) { 394 PyErr_SetString(PyExc_ValueError, "format mismatch"); 395 return NULL; 396 } 397 while (*s && isspace(*s)) 398 s++; 399 if (*s) { 400 PyErr_Format(PyExc_ValueError, 401 "unconverted data remains: '%.400s'", s); 402 return NULL; 403 } 404 return tmtotuple(&tm); 405} 406 407static char strptime_doc[] = 408"strptime(string, format) -> tuple\n\ 409Parse a string to a time tuple according to a format specification.\n\ 410See the library reference manual for formatting codes (same as strftime())."; 411#endif /* HAVE_STRPTIME */ 412 413static PyObject * 414time_asctime(PyObject *self, PyObject *args) 415{ 416 PyObject *tup; 417 struct tm buf; 418 char *p; 419 if (!PyArg_ParseTuple(args, "O:asctime", &tup)) 420 return NULL; 421 if (!gettmarg(tup, &buf)) 422 return NULL; 423 p = asctime(&buf); 424 if (p[24] == '\n') 425 p[24] = '\0'; 426 return PyString_FromString(p); 427} 428 429static char asctime_doc[] = 430"asctime(tuple) -> string\n\ 431\n\ 432Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'."; 433 434static PyObject * 435time_ctime(PyObject *self, PyObject *args) 436{ 437 double dt; 438 time_t tt; 439 char *p; 440 if (!PyArg_Parse(args, "d", &dt)) 441 return NULL; 442 tt = (time_t)dt; 443#if defined(macintosh) && defined(USE_GUSI204) 444 tt = tt + GUSI_TO_MSL_EPOCH; 445#endif 446 p = ctime(&tt); 447 if (p == NULL) { 448 PyErr_SetString(PyExc_ValueError, "unconvertible time"); 449 return NULL; 450 } 451 if (p[24] == '\n') 452 p[24] = '\0'; 453 return PyString_FromString(p); 454} 455 456static char ctime_doc[] = 457"ctime(seconds) -> string\n\ 458\n\ 459Convert a time in seconds since the Epoch to a string in local time.\n\ 460This is equivalent to asctime(localtime(seconds))."; 461 462#ifdef HAVE_MKTIME 463static PyObject * 464time_mktime(PyObject *self, PyObject *args) 465{ 466 PyObject *tup; 467 struct tm buf; 468 time_t tt; 469 if (!PyArg_ParseTuple(args, "O:mktime", &tup)) 470 return NULL; 471 tt = time(&tt); 472 buf = *localtime(&tt); 473 if (!gettmarg(tup, &buf)) 474 return NULL; 475 tt = mktime(&buf); 476 if (tt == (time_t)(-1)) { 477 PyErr_SetString(PyExc_OverflowError, 478 "mktime argument out of range"); 479 return NULL; 480 } 481#if defined(macintosh) && defined(USE_GUSI2) 482 tt = tt - GUSI_TO_MSL_EPOCH; 483#endif 484 return PyFloat_FromDouble((double)tt); 485} 486 487static char mktime_doc[] = 488"mktime(tuple) -> floating point number\n\ 489\n\ 490Convert a time tuple in local time to seconds since the Epoch."; 491#endif /* HAVE_MKTIME */ 492 493static PyMethodDef time_methods[] = { 494 {"time", time_time, METH_OLDARGS, time_doc}, 495#ifdef HAVE_CLOCK 496 {"clock", time_clock, METH_OLDARGS, clock_doc}, 497#endif 498 {"sleep", time_sleep, METH_OLDARGS, sleep_doc}, 499 {"gmtime", time_gmtime, METH_OLDARGS, gmtime_doc}, 500 {"localtime", time_localtime, METH_OLDARGS, localtime_doc}, 501 {"asctime", time_asctime, METH_VARARGS, asctime_doc}, 502 {"ctime", time_ctime, METH_OLDARGS, ctime_doc}, 503#ifdef HAVE_MKTIME 504 {"mktime", time_mktime, METH_VARARGS, mktime_doc}, 505#endif 506#ifdef HAVE_STRFTIME 507 {"strftime", time_strftime, METH_VARARGS, strftime_doc}, 508#endif 509#ifdef HAVE_STRPTIME 510 {"strptime", time_strptime, METH_VARARGS, strptime_doc}, 511#endif 512 {NULL, NULL} /* sentinel */ 513}; 514 515static void 516ins(PyObject *d, char *name, PyObject *v) 517{ 518 if (v == NULL) 519 Py_FatalError("Can't initialize time module -- NULL value"); 520 if (PyDict_SetItemString(d, name, v) != 0) 521 Py_FatalError( 522 "Can't initialize time module -- PyDict_SetItemString failed"); 523 Py_DECREF(v); 524} 525 526static char module_doc[] = 527"This module provides various functions to manipulate time values.\n\ 528\n\ 529There are two standard representations of time. One is the number\n\ 530of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\ 531or a floating point number (to represent fractions of seconds).\n\ 532The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\ 533The actual value can be retrieved by calling gmtime(0).\n\ 534\n\ 535The other representation is a tuple of 9 integers giving local time.\n\ 536The tuple items are:\n\ 537 year (four digits, e.g. 1998)\n\ 538 month (1-12)\n\ 539 day (1-31)\n\ 540 hours (0-23)\n\ 541 minutes (0-59)\n\ 542 seconds (0-59)\n\ 543 weekday (0-6, Monday is 0)\n\ 544 Julian day (day in the year, 1-366)\n\ 545 DST (Daylight Savings Time) flag (-1, 0 or 1)\n\ 546If the DST flag is 0, the time is given in the regular time zone;\n\ 547if it is 1, the time is given in the DST time zone;\n\ 548if it is -1, mktime() should guess based on the date and time.\n\ 549\n\ 550Variables:\n\ 551\n\ 552timezone -- difference in seconds between UTC and local standard time\n\ 553altzone -- difference in seconds between UTC and local DST time\n\ 554daylight -- whether local time should reflect DST\n\ 555tzname -- tuple of (standard time zone name, DST time zone name)\n\ 556\n\ 557Functions:\n\ 558\n\ 559time() -- return current time in seconds since the Epoch as a float\n\ 560clock() -- return CPU time since process start as a float\n\ 561sleep() -- delay for a number of seconds given as a float\n\ 562gmtime() -- convert seconds since Epoch to UTC tuple\n\ 563localtime() -- convert seconds since Epoch to local time tuple\n\ 564asctime() -- convert time tuple to string\n\ 565ctime() -- convert time in seconds to string\n\ 566mktime() -- convert local time tuple to seconds since Epoch\n\ 567strftime() -- convert time tuple to string according to format specification\n\ 568strptime() -- parse string to time tuple according to format specification\n\ 569"; 570 571 572DL_EXPORT(void) 573inittime(void) 574{ 575 PyObject *m, *d; 576 char *p; 577 m = Py_InitModule3("time", time_methods, module_doc); 578 d = PyModule_GetDict(m); 579 /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */ 580 p = getenv("PYTHONY2K"); 581 ins(d, "accept2dyear", PyInt_FromLong((long) (!p || !*p))); 582 /* Squirrel away the module's dictionary for the y2k check */ 583 Py_INCREF(d); 584 moddict = d; 585#if defined(HAVE_TZNAME) && !defined(__GLIBC__) 586 tzset(); 587#ifdef PYOS_OS2 588 ins(d, "timezone", PyInt_FromLong((long)_timezone)); 589#else /* !PYOS_OS2 */ 590 ins(d, "timezone", PyInt_FromLong((long)timezone)); 591#endif /* PYOS_OS2 */ 592#ifdef HAVE_ALTZONE 593 ins(d, "altzone", PyInt_FromLong((long)altzone)); 594#else 595#ifdef PYOS_OS2 596 ins(d, "altzone", PyInt_FromLong((long)_timezone-3600)); 597#else /* !PYOS_OS2 */ 598 ins(d, "altzone", PyInt_FromLong((long)timezone-3600)); 599#endif /* PYOS_OS2 */ 600#endif 601 ins(d, "daylight", PyInt_FromLong((long)daylight)); 602 ins(d, "tzname", Py_BuildValue("(zz)", tzname[0], tzname[1])); 603#else /* !HAVE_TZNAME || __GLIBC__ */ 604#ifdef HAVE_TM_ZONE 605 { 606#define YEAR ((time_t)((365 * 24 + 6) * 3600)) 607 time_t t; 608 struct tm *p; 609 long janzone, julyzone; 610 char janname[10], julyname[10]; 611 t = (time((time_t *)0) / YEAR) * YEAR; 612 p = localtime(&t); 613 janzone = -p->tm_gmtoff; 614 strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9); 615 janname[9] = '\0'; 616 t += YEAR/2; 617 p = localtime(&t); 618 julyzone = -p->tm_gmtoff; 619 strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9); 620 julyname[9] = '\0'; 621 622 if( janzone < julyzone ) { 623 /* DST is reversed in the southern hemisphere */ 624 ins(d, "timezone", PyInt_FromLong(julyzone)); 625 ins(d, "altzone", PyInt_FromLong(janzone)); 626 ins(d, "daylight", 627 PyInt_FromLong((long)(janzone != julyzone))); 628 ins(d, "tzname", 629 Py_BuildValue("(zz)", julyname, janname)); 630 } else { 631 ins(d, "timezone", PyInt_FromLong(janzone)); 632 ins(d, "altzone", PyInt_FromLong(julyzone)); 633 ins(d, "daylight", 634 PyInt_FromLong((long)(janzone != julyzone))); 635 ins(d, "tzname", 636 Py_BuildValue("(zz)", janname, julyname)); 637 } 638 } 639#else 640#ifdef macintosh 641 /* The only thing we can obtain is the current timezone 642 ** (and whether dst is currently _active_, but that is not what 643 ** we're looking for:-( ) 644 */ 645 initmactimezone(); 646 ins(d, "timezone", PyInt_FromLong(timezone)); 647 ins(d, "altzone", PyInt_FromLong(timezone)); 648 ins(d, "daylight", PyInt_FromLong((long)0)); 649 ins(d, "tzname", Py_BuildValue("(zz)", "", "")); 650#endif /* macintosh */ 651#endif /* HAVE_TM_ZONE */ 652#endif /* !HAVE_TZNAME || __GLIBC__ */ 653 if (PyErr_Occurred()) 654 Py_FatalError("Can't initialize time module"); 655} 656 657 658/* Implement floattime() for various platforms */ 659 660static double 661floattime(void) 662{ 663 /* There are three ways to get the time: 664 (1) gettimeofday() -- resolution in microseconds 665 (2) ftime() -- resolution in milliseconds 666 (3) time() -- resolution in seconds 667 In all cases the return value is a float in seconds. 668 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may 669 fail, so we fall back on ftime() or time(). 670 Note: clock resolution does not imply clock accuracy! */ 671#ifdef HAVE_GETTIMEOFDAY 672 { 673 struct timeval t; 674#ifdef GETTIMEOFDAY_NO_TZ 675 if (gettimeofday(&t) == 0) 676 return (double)t.tv_sec + t.tv_usec*0.000001; 677#else /* !GETTIMEOFDAY_NO_TZ */ 678 if (gettimeofday(&t, (struct timezone *)NULL) == 0) 679 return (double)t.tv_sec + t.tv_usec*0.000001; 680#endif /* !GETTIMEOFDAY_NO_TZ */ 681 } 682#endif /* !HAVE_GETTIMEOFDAY */ 683 { 684#if defined(HAVE_FTIME) 685 struct timeb t; 686 ftime(&t); 687 return (double)t.time + (double)t.millitm * (double)0.001; 688#else /* !HAVE_FTIME */ 689 time_t secs; 690 time(&secs); 691 return (double)secs; 692#endif /* !HAVE_FTIME */ 693 } 694} 695 696 697/* Implement floatsleep() for various platforms. 698 When interrupted (or when another error occurs), return -1 and 699 set an exception; else return 0. */ 700 701static int 702floatsleep(double secs) 703{ 704/* XXX Should test for MS_WIN32 first! */ 705#if defined(HAVE_SELECT) && !defined(__BEOS__) 706 struct timeval t; 707 double frac; 708 frac = fmod(secs, 1.0); 709 secs = floor(secs); 710 t.tv_sec = (long)secs; 711 t.tv_usec = (long)(frac*1000000.0); 712 Py_BEGIN_ALLOW_THREADS 713 if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) { 714#ifdef EINTR 715 if (errno != EINTR) { 716#else 717 if (1) { 718#endif 719 Py_BLOCK_THREADS 720 PyErr_SetFromErrno(PyExc_IOError); 721 return -1; 722 } 723 } 724 Py_END_ALLOW_THREADS 725#else /* !HAVE_SELECT || __BEOS__ */ 726#ifdef macintosh 727#define MacTicks (* (long *)0x16A) 728 long deadline; 729 deadline = MacTicks + (long)(secs * 60.0); 730 while (MacTicks < deadline) { 731 /* XXX Should call some yielding function here */ 732 if (PyErr_CheckSignals()) 733 return -1; 734 } 735#else /* !macintosh */ 736#if defined(__WATCOMC__) && !defined(__QNX__) 737 /* XXX Can't interrupt this sleep */ 738 Py_BEGIN_ALLOW_THREADS 739 delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */ 740 Py_END_ALLOW_THREADS 741#else /* !__WATCOMC__ || __QNX__ */ 742#ifdef MSDOS 743 struct timeb t1, t2; 744 double frac; 745 extern double fmod(double, double); 746 extern double floor(double); 747 if (secs <= 0.0) 748 return; 749 frac = fmod(secs, 1.0); 750 secs = floor(secs); 751 ftime(&t1); 752 t2.time = t1.time + (int)secs; 753 t2.millitm = t1.millitm + (int)(frac*1000.0); 754 while (t2.millitm >= 1000) { 755 t2.time++; 756 t2.millitm -= 1000; 757 } 758 for (;;) { 759#ifdef QUICKWIN 760 Py_BEGIN_ALLOW_THREADS 761 _wyield(); 762 Py_END_ALLOW_THREADS 763#endif 764 if (PyErr_CheckSignals()) 765 return -1; 766 ftime(&t1); 767 if (t1.time > t2.time || 768 t1.time == t2.time && t1.millitm >= t2.millitm) 769 break; 770 } 771#else /* !MSDOS */ 772#ifdef MS_WIN32 773 { 774 double millisecs = secs * 1000.0; 775 if (millisecs > (double)ULONG_MAX) { 776 PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); 777 return -1; 778 } 779 /* XXX Can't interrupt this sleep */ 780 Py_BEGIN_ALLOW_THREADS 781 Sleep((unsigned long)millisecs); 782 Py_END_ALLOW_THREADS 783 } 784#else /* !MS_WIN32 */ 785#ifdef PYOS_OS2 786 /* This Sleep *IS* Interruptable by Exceptions */ 787 Py_BEGIN_ALLOW_THREADS 788 if (DosSleep(secs * 1000) != NO_ERROR) { 789 Py_BLOCK_THREADS 790 PyErr_SetFromErrno(PyExc_IOError); 791 return -1; 792 } 793 Py_END_ALLOW_THREADS 794#else /* !PYOS_OS2 */ 795#ifdef __BEOS__ 796 /* This sleep *CAN BE* interrupted. */ 797 { 798 if( secs <= 0.0 ) { 799 return; 800 } 801 802 Py_BEGIN_ALLOW_THREADS 803 /* BeOS snooze() is in microseconds... */ 804 if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) { 805 Py_BLOCK_THREADS 806 PyErr_SetFromErrno( PyExc_IOError ); 807 return -1; 808 } 809 Py_END_ALLOW_THREADS 810 } 811#else /* !__BEOS__ */ 812 /* XXX Can't interrupt this sleep */ 813 Py_BEGIN_ALLOW_THREADS 814 sleep((int)secs); 815 Py_END_ALLOW_THREADS 816#endif /* !__BEOS__ */ 817#endif /* !PYOS_OS2 */ 818#endif /* !MS_WIN32 */ 819#endif /* !MSDOS */ 820#endif /* !__WATCOMC__ || __QNX__ */ 821#endif /* !macintosh */ 822#endif /* !HAVE_SELECT */ 823 return 0; 824} 825