You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
4.5 KiB

14 years ago
  1. #include "Python.h"
  2. #ifdef MS_WINDOWS
  3. #include <windows.h>
  4. #endif
  5. #if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
  6. /*
  7. * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter
  8. * might fail on some platforms. This fallback is unwanted on MacOSX because
  9. * that makes it impossible to use a binary build on OSX 10.4 on earlier
  10. * releases of the OS. Therefore claim we don't support ftime.
  11. */
  12. # undef HAVE_FTIME
  13. #endif
  14. #if defined(HAVE_FTIME) && !defined(MS_WINDOWS)
  15. #include <sys/timeb.h>
  16. extern int ftime(struct timeb *);
  17. #endif
  18. void
  19. _PyTime_gettimeofday(_PyTime_timeval *tp)
  20. {
  21. #ifdef MS_WINDOWS
  22. FILETIME system_time;
  23. ULARGE_INTEGER large;
  24. ULONGLONG microseconds;
  25. GetSystemTimeAsFileTime(&system_time);
  26. large.u.LowPart = system_time.dwLowDateTime;
  27. large.u.HighPart = system_time.dwHighDateTime;
  28. /* 11,644,473,600,000,000: number of microseconds between
  29. the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
  30. days). */
  31. microseconds = large.QuadPart / 10 - 11644473600000000;
  32. tp->tv_sec = microseconds / 1000000;
  33. tp->tv_usec = microseconds % 1000000;
  34. #else
  35. /* There are three ways to get the time:
  36. (1) gettimeofday() -- resolution in microseconds
  37. (2) ftime() -- resolution in milliseconds
  38. (3) time() -- resolution in seconds
  39. In all cases the return value in a timeval struct.
  40. Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
  41. fail, so we fall back on ftime() or time().
  42. Note: clock resolution does not imply clock accuracy! */
  43. #ifdef HAVE_GETTIMEOFDAY
  44. #ifdef GETTIMEOFDAY_NO_TZ
  45. if (gettimeofday(tp) == 0)
  46. return;
  47. #else /* !GETTIMEOFDAY_NO_TZ */
  48. if (gettimeofday(tp, (struct timezone *)NULL) == 0)
  49. return;
  50. #endif /* !GETTIMEOFDAY_NO_TZ */
  51. #endif /* !HAVE_GETTIMEOFDAY */
  52. #if defined(HAVE_FTIME)
  53. {
  54. struct timeb t;
  55. ftime(&t);
  56. tp->tv_sec = t.time;
  57. tp->tv_usec = t.millitm * 1000;
  58. }
  59. #else /* !HAVE_FTIME */
  60. tp->tv_sec = time(NULL);
  61. tp->tv_usec = 0;
  62. #endif /* !HAVE_FTIME */
  63. #endif /* MS_WINDOWS */
  64. }
  65. static void
  66. error_time_t_overflow(void)
  67. {
  68. PyErr_SetString(PyExc_OverflowError,
  69. "timestamp out of range for platform time_t");
  70. }
  71. static time_t
  72. _PyLong_AsTime_t(PyObject *obj)
  73. {
  74. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  75. PY_LONG_LONG val;
  76. val = PyLong_AsLongLong(obj);
  77. #else
  78. long val;
  79. assert(sizeof(time_t) <= sizeof(long));
  80. val = PyLong_AsLong(obj);
  81. #endif
  82. if (val == -1 && PyErr_Occurred()) {
  83. if (PyErr_ExceptionMatches(PyExc_OverflowError))
  84. error_time_t_overflow();
  85. return -1;
  86. }
  87. return (time_t)val;
  88. }
  89. static int
  90. _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
  91. double denominator)
  92. {
  93. assert(denominator <= LONG_MAX);
  94. if (PyFloat_Check(obj)) {
  95. double d, intpart, err;
  96. /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
  97. volatile double floatpart;
  98. d = PyFloat_AsDouble(obj);
  99. floatpart = modf(d, &intpart);
  100. if (floatpart < 0) {
  101. floatpart = 1.0 + floatpart;
  102. intpart -= 1.0;
  103. }
  104. *sec = (time_t)intpart;
  105. err = intpart - (double)*sec;
  106. if (err <= -1.0 || err >= 1.0) {
  107. error_time_t_overflow();
  108. return -1;
  109. }
  110. floatpart *= denominator;
  111. *numerator = (long)floatpart;
  112. return 0;
  113. }
  114. else {
  115. *sec = _PyLong_AsTime_t(obj);
  116. if (*sec == (time_t)-1 && PyErr_Occurred())
  117. return -1;
  118. *numerator = 0;
  119. return 0;
  120. }
  121. }
  122. int
  123. _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec)
  124. {
  125. if (PyFloat_Check(obj)) {
  126. double d, intpart, err;
  127. d = PyFloat_AsDouble(obj);
  128. (void)modf(d, &intpart);
  129. *sec = (time_t)intpart;
  130. err = intpart - (double)*sec;
  131. if (err <= -1.0 || err >= 1.0) {
  132. error_time_t_overflow();
  133. return -1;
  134. }
  135. return 0;
  136. }
  137. else {
  138. *sec = _PyLong_AsTime_t(obj);
  139. if (*sec == (time_t)-1 && PyErr_Occurred())
  140. return -1;
  141. return 0;
  142. }
  143. }
  144. int
  145. _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec)
  146. {
  147. return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9);
  148. }
  149. int
  150. _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec)
  151. {
  152. return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6);
  153. }
  154. void
  155. _PyTime_Init()
  156. {
  157. /* Do nothing. Needed to force linking. */
  158. }