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