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