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