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