blob: 77b170d78a579807fd803c5d679a337462606871 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Time module */
33
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000034#include "Python.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000035
Guido van Rossum99d90c01996-08-08 19:17:45 +000036#ifdef HAVE_SELECT
37#include "mymath.h"
38#endif
39
Guido van Rossum6d946f91992-08-14 13:49:30 +000040#ifdef macintosh
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include <time.h>
42#else
43#include <sys/types.h>
Guido van Rossum6d946f91992-08-14 13:49:30 +000044#endif
45
Guido van Rossumb6775db1994-08-01 11:34:53 +000046#ifdef QUICKWIN
47#include <io.h>
48#endif
49
50#ifdef HAVE_UNISTD_H
Guido van Rossum2762f251992-03-27 17:22:13 +000051#include <unistd.h>
52#endif
53
Guido van Rossumb6775db1994-08-01 11:34:53 +000054#ifdef HAVE_SELECT
55#include "myselect.h"
56#else
57#include "mytime.h"
58#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#ifdef HAVE_FTIME
61#include <sys/timeb.h>
Guido van Rossum52174571996-12-09 18:38:52 +000062#ifndef MS_WINDOWS
Guido van Rossum1bb126f1996-12-06 20:17:44 +000063extern int ftime();
Guido van Rossum52174571996-12-09 18:38:52 +000064#endif /* MS_WINDOWS */
65#endif /* HAVE_FTIME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossumbceeac81996-05-23 22:53:47 +000067#ifdef __WATCOMC__
68#include <i86.h>
69#else
Guido van Rossumcac6c721996-09-06 13:34:02 +000070#ifdef MS_WINDOWS
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <windows.h>
Guido van Rossumb2fb3641996-09-07 00:47:35 +000072#ifdef MS_WIN16
73/* These overrides not needed for Win32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#define timezone _timezone
Guido van Rossumcc081121995-03-14 15:05:41 +000075#define tzname _tzname
76#define daylight _daylight
77#define altzone _altzone
Guido van Rossumb2fb3641996-09-07 00:47:35 +000078#endif /* MS_WIN16 */
Guido van Rossumcac6c721996-09-06 13:34:02 +000079#endif /* MS_WINDOWS */
80#endif /* !__WATCOMC__ */
Guido van Rossum234f9421993-06-17 12:35:49 +000081
82/* Forward declarations */
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000083static int floatsleep Py_PROTO((double));
84static double floattime Py_PROTO(());
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000086static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087time_time(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000088 PyObject *self;
89 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090{
Guido van Rossumb6775db1994-08-01 11:34:53 +000091 double secs;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000092 if (!PyArg_NoArgs(args))
Guido van Rossuma2b7f401993-01-04 09:09:59 +000093 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +000094 secs = floattime();
95 if (secs == 0.0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000096 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma2b7f401993-01-04 09:09:59 +000097 return NULL;
98 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000099 return PyFloat_FromDouble(secs);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000100}
101
102#ifdef HAVE_CLOCK
103
104#ifndef CLOCKS_PER_SEC
Guido van Rossum1b66a4f1996-02-25 04:50:33 +0000105#ifdef CLK_TCK
106#define CLOCKS_PER_SEC CLK_TCK
107#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000108#define CLOCKS_PER_SEC 1000000
109#endif
Guido van Rossum1b66a4f1996-02-25 04:50:33 +0000110#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000111
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000112static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000113time_clock(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000114 PyObject *self;
115 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000116{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000117 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 return NULL;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000119 return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000121#endif /* HAVE_CLOCK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000123static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124time_sleep(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000125 PyObject *self;
126 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127{
Guido van Rossum775f4da1993-01-09 17:18:52 +0000128 double secs;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000129 if (!PyArg_Parse(args, "d", &secs))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 return NULL;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000131 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000132 if (floatsleep(secs) != 0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000133 Py_BLOCK_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 return NULL;
135 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000136 Py_END_ALLOW_THREADS
137 Py_INCREF(Py_None);
138 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139}
140
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000141static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000142time_convert(when, function)
143 time_t when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000144 struct tm * (*function) Py_PROTO((const time_t *));
Guido van Rossum234f9421993-06-17 12:35:49 +0000145{
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000146 struct tm *p;
147 errno = 0;
148 p = function(&when);
149 if (p == NULL) {
150#ifdef EINVAL
Guido van Rossum0b1ff661996-11-02 17:31:22 +0000151 if (errno == 0)
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000152 errno = EINVAL;
153#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000154 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000155 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000156 return Py_BuildValue("(iiiiiiiii)",
Guido van Rossum234f9421993-06-17 12:35:49 +0000157 p->tm_year + 1900,
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000158 p->tm_mon + 1, /* Want January == 1 */
Guido van Rossum234f9421993-06-17 12:35:49 +0000159 p->tm_mday,
160 p->tm_hour,
161 p->tm_min,
162 p->tm_sec,
163 (p->tm_wday + 6) % 7, /* Want Monday == 0 */
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000164 p->tm_yday + 1, /* Want January, 1 == 1 */
Guido van Rossum234f9421993-06-17 12:35:49 +0000165 p->tm_isdst);
166}
167
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000168static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000169time_gmtime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000170 PyObject *self;
171 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000172{
173 double when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000174 if (!PyArg_Parse(args, "d", &when))
Guido van Rossum234f9421993-06-17 12:35:49 +0000175 return NULL;
176 return time_convert((time_t)when, gmtime);
177}
178
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000179static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000180time_localtime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000181 PyObject *self;
182 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000183{
184 double when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000185 if (!PyArg_Parse(args, "d", &when))
Guido van Rossum234f9421993-06-17 12:35:49 +0000186 return NULL;
187 return time_convert((time_t)when, localtime);
188}
189
Guido van Rossum9e90a671993-06-24 11:10:19 +0000190static int
191gettmarg(args, p)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000192 PyObject *args;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000193 struct tm *p;
194{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000195 if (!PyArg_Parse(args, "(iiiiiiiii)",
Guido van Rossum9e90a671993-06-24 11:10:19 +0000196 &p->tm_year,
197 &p->tm_mon,
198 &p->tm_mday,
199 &p->tm_hour,
200 &p->tm_min,
201 &p->tm_sec,
202 &p->tm_wday,
203 &p->tm_yday,
204 &p->tm_isdst))
205 return 0;
206 if (p->tm_year >= 1900)
207 p->tm_year -= 1900;
208 p->tm_mon--;
209 p->tm_wday = (p->tm_wday + 1) % 7;
210 p->tm_yday--;
211 return 1;
212}
213
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000214#ifdef HAVE_STRFTIME
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000215static PyObject *
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000216time_strftime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000217 PyObject *self;
218 PyObject *args;
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000219{
220 struct tm buf;
221 const char *fmt;
222 char *outbuf = 0;
223 int i;
224
225 if (!PyArg_ParseTuple(args, "s(iiiiiiiii)",
226 &fmt,
227 &(buf.tm_year),
228 &(buf.tm_mon),
229 &(buf.tm_mday),
230 &(buf.tm_hour),
231 &(buf.tm_min),
232 &(buf.tm_sec),
233 &(buf.tm_wday),
234 &(buf.tm_yday),
235 &(buf.tm_isdst)))
236 return NULL;
237 if (buf.tm_year >= 1900)
238 buf.tm_year -= 1900;
239 buf.tm_mon--;
240 buf.tm_wday = (buf.tm_wday + 1) % 7;
241 buf.tm_yday--;
242 /* I hate these functions that presume you know how big the output */
243 /* will be ahead of time... */
244 for (i = 1024 ; i < 8192 ; i += 1024) {
245 outbuf = malloc(i);
246 if (outbuf == NULL) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000247 return PyErr_NoMemory();
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000248 }
249 if (strftime(outbuf, i-1, fmt, &buf) != 0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000250 PyObject *ret;
251 ret = PyString_FromString(outbuf);
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000252 free(outbuf);
253 return ret;
254 }
255 free(outbuf);
256 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000257 return PyErr_NoMemory();
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000258}
259#endif /* HAVE_STRFTIME */
260
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000261static PyObject *
Guido van Rossum9e90a671993-06-24 11:10:19 +0000262time_asctime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000263 PyObject *self;
264 PyObject *args;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000265{
266 struct tm buf;
267 char *p;
268 if (!gettmarg(args, &buf))
269 return NULL;
270 p = asctime(&buf);
271 if (p[24] == '\n')
272 p[24] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000273 return PyString_FromString(p);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000274}
275
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000276static PyObject *
Guido van Rossum9e90a671993-06-24 11:10:19 +0000277time_ctime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000278 PyObject *self;
279 PyObject *args;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000280{
281 double dt;
282 time_t tt;
283 char *p;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000284 if (!PyArg_Parse(args, "d", &dt))
Guido van Rossum9e90a671993-06-24 11:10:19 +0000285 return NULL;
Guido van Rossumcac6c721996-09-06 13:34:02 +0000286 tt = (time_t)dt;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000287 p = ctime(&tt);
288 if (p[24] == '\n')
289 p[24] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000290 return PyString_FromString(p);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000291}
292
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000293static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000294time_mktime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000295 PyObject *self;
296 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000297{
298 struct tm buf;
Guido van Rossumbceeac81996-05-23 22:53:47 +0000299 time_t tt;
300 tt = time(&tt);
301 buf = *localtime(&tt);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000302 if (!gettmarg(args, &buf))
Guido van Rossum234f9421993-06-17 12:35:49 +0000303 return NULL;
Guido van Rossumbceeac81996-05-23 22:53:47 +0000304 tt = mktime(&buf);
305 if (tt == (time_t)(-1)) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000306 PyErr_SetString(PyExc_OverflowError,
307 "mktime argument out of range");
Guido van Rossumbceeac81996-05-23 22:53:47 +0000308 return NULL;
309 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000310 return PyFloat_FromDouble((double)tt);
Guido van Rossum234f9421993-06-17 12:35:49 +0000311}
312
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000313static PyMethodDef time_methods[] = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314 {"time", time_time},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000315#ifdef HAVE_CLOCK
316 {"clock", time_clock},
317#endif
318 {"sleep", time_sleep},
Guido van Rossum234f9421993-06-17 12:35:49 +0000319 {"gmtime", time_gmtime},
320 {"localtime", time_localtime},
Guido van Rossum9e90a671993-06-24 11:10:19 +0000321 {"asctime", time_asctime},
322 {"ctime", time_ctime},
Guido van Rossum234f9421993-06-17 12:35:49 +0000323 {"mktime", time_mktime},
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000324#ifdef HAVE_STRFTIME
Guido van Rossum5416e201996-02-13 00:14:09 +0000325 {"strftime", time_strftime, 1},
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000326#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327 {NULL, NULL} /* sentinel */
328};
329
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000330static void
331ins(d, name, v)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000332 PyObject *d;
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000333 char *name;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000334 PyObject *v;
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000335{
336 if (v == NULL)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000337 Py_FatalError("Can't initialize time module -- NULL value");
338 if (PyDict_SetItemString(d, name, v) != 0)
339 Py_FatalError(
Guido van Rossum52174571996-12-09 18:38:52 +0000340 "Can't initialize time module -- PyDict_SetItemString failed");
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000341 Py_DECREF(v);
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000342}
343
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344void
345inittime()
346{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000347 PyObject *m, *d;
348 m = Py_InitModule("time", time_methods);
349 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000350#ifdef HAVE_TZNAME
Guido van Rossum234f9421993-06-17 12:35:49 +0000351 tzset();
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000352 ins(d, "timezone", PyInt_FromLong((long)timezone));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000353#ifdef HAVE_ALTZONE
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000354 ins(d, "altzone", PyInt_FromLong((long)altzone));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000355#else
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000356 ins(d, "altzone", PyInt_FromLong((long)timezone-3600));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000357#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000358 ins(d, "daylight", PyInt_FromLong((long)daylight));
359 ins(d, "tzname", Py_BuildValue("(zz)", tzname[0], tzname[1]));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000360#else /* !HAVE_TZNAME */
361#if HAVE_TM_ZONE
Guido van Rossum234f9421993-06-17 12:35:49 +0000362 {
363#define YEAR ((time_t)((365 * 24 + 6) * 3600))
364 time_t t;
365 struct tm *p;
366 long winterzone, summerzone;
367 char wintername[10], summername[10];
Guido van Rossumb6775db1994-08-01 11:34:53 +0000368 /* XXX This won't work on the southern hemisphere.
369 XXX Anybody got a better idea? */
Guido van Rossum234f9421993-06-17 12:35:49 +0000370 t = (time((time_t *)0) / YEAR) * YEAR;
371 p = localtime(&t);
372 winterzone = -p->tm_gmtoff;
373 strncpy(wintername, p->tm_zone ? p->tm_zone : " ", 9);
374 wintername[9] = '\0';
375 t += YEAR/2;
376 p = localtime(&t);
377 summerzone = -p->tm_gmtoff;
378 strncpy(summername, p->tm_zone ? p->tm_zone : " ", 9);
379 summername[9] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000380 ins(d, "timezone", PyInt_FromLong(winterzone));
381 ins(d, "altzone", PyInt_FromLong(summerzone));
382 ins(d, "daylight",
383 PyInt_FromLong((long)(winterzone != summerzone)));
384 ins(d, "tzname",
385 Py_BuildValue("(zz)", wintername, summername));
Guido van Rossum234f9421993-06-17 12:35:49 +0000386 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000387#endif /* HAVE_TM_ZONE */
388#endif /* !HAVE_TZNAME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389}
390
391
Guido van Rossumb6775db1994-08-01 11:34:53 +0000392/* Implement floattime() for various platforms */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393
Guido van Rossumb6775db1994-08-01 11:34:53 +0000394static double
395floattime()
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000396{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000397 /* There are three ways to get the time:
398 (1) gettimeofday() -- resolution in microseconds
399 (2) ftime() -- resolution in milliseconds
400 (3) time() -- resolution in seconds
401 In all cases the return value is a float in seconds.
402 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
403 fail, so we fall back on ftime() or time().
404 Note: clock resolution does not imply clock accuracy! */
405#ifdef HAVE_GETTIMEOFDAY
406 {
Guido van Rossum426035c1991-02-19 12:27:35 +0000407 struct timeval t;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000408#ifdef GETTIMEOFDAY_NO_TZ
409 if (gettimeofday(&t) == 0)
410 return (double)t.tv_sec + t.tv_usec*0.000001;
411#else /* !GETTIMEOFDAY_NO_TZ */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000412 if (gettimeofday(&t, (struct timezone *)NULL) == 0)
413 return (double)t.tv_sec + t.tv_usec*0.000001;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000414#endif /* !GETTIMEOFDAY_NO_TZ */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000415 }
416#endif /* !HAVE_GETTIMEOFDAY */
417 {
418#ifdef HAVE_FTIME
419 struct timeb t;
420 ftime(&t);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000421 return (double)t.time + (double)t.millitm * (double)0.001;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000422#else /* !HAVE_FTIME */
423 time_t secs;
424 time(&secs);
425 return (double)secs;
426#endif /* !HAVE_FTIME */
427 }
Guido van Rossum426035c1991-02-19 12:27:35 +0000428}
429
Guido van Rossumb6775db1994-08-01 11:34:53 +0000430
431/* Implement floatsleep() for various platforms.
432 When interrupted (or when another error occurs), return -1 and
433 set an exception; else return 0. */
434
435static int
Guido van Rossuma320fd31995-03-09 12:14:15 +0000436#ifdef MPW
437floatsleep(double secs)
438#else
Guido van Rossum775f4da1993-01-09 17:18:52 +0000439floatsleep(secs)
440 double secs;
Guido van Rossuma320fd31995-03-09 12:14:15 +0000441#endif /* MPW */
Guido van Rossum426035c1991-02-19 12:27:35 +0000442{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000443#ifdef HAVE_SELECT
Guido van Rossum426035c1991-02-19 12:27:35 +0000444 struct timeval t;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000445 double frac;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000446 frac = fmod(secs, 1.0);
447 secs = floor(secs);
448 t.tv_sec = (long)secs;
449 t.tv_usec = (long)(frac*1000000.0);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000450 if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000451 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000452 return -1;
453 }
454#else /* !HAVE_SELECT */
455#ifdef macintosh
456#define MacTicks (* (long *)0x16A)
457 long deadline;
458 deadline = MacTicks + (long)(secs * 60.0);
459 while (MacTicks < deadline) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000460 if (PyErr_CheckSignals())
Guido van Rossumb6775db1994-08-01 11:34:53 +0000461 return -1;
462 }
463#else /* !macintosh */
Guido van Rossumbceeac81996-05-23 22:53:47 +0000464#ifdef __WATCOMC__
465 /* XXX Can't interrupt this sleep */
466 delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
467#else /* !__WATCOMC__ */
Guido van Rossume22e6441993-07-09 10:51:31 +0000468#ifdef MSDOS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000469 struct timeb t1, t2;
470 double frac;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000471 extern double fmod Py_PROTO((double, double));
472 extern double floor Py_PROTO((double));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000473 if (secs <= 0.0)
474 return;
475 frac = fmod(secs, 1.0);
476 secs = floor(secs);
477 ftime(&t1);
478 t2.time = t1.time + (int)secs;
479 t2.millitm = t1.millitm + (int)(frac*1000.0);
480 while (t2.millitm >= 1000) {
481 t2.time++;
482 t2.millitm -= 1000;
483 }
484 for (;;) {
485#ifdef QUICKWIN
486 _wyield();
Guido van Rossum80c9d881991-04-16 08:47:51 +0000487#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000488 if (PyErr_CheckSignals())
Guido van Rossumb6775db1994-08-01 11:34:53 +0000489 return -1;
490 ftime(&t1);
491 if (t1.time > t2.time ||
492 t1.time == t2.time && t1.millitm >= t2.millitm)
493 break;
494 }
495#else /* !MSDOS */
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000496#ifdef MS_WIN32
Guido van Rossumb6775db1994-08-01 11:34:53 +0000497 /* XXX Can't interrupt this sleep */
498 Sleep((int)(secs*1000));
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000499#else /* !MS_WIN32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000500 /* XXX Can't interrupt this sleep */
501 sleep((int)secs);
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000502#endif /* !MS_WIN32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000503#endif /* !MSDOS */
Guido van Rossumbceeac81996-05-23 22:53:47 +0000504#endif /* !__WATCOMC__ */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000505#endif /* !macintosh */
506#endif /* !HAVE_SELECT */
507 return 0;
Guido van Rossum80c9d881991-04-16 08:47:51 +0000508}