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