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.

122 lines
3.3 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. int
  66. _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec)
  67. {
  68. if (PyFloat_Check(obj)) {
  69. double d, intpart, floatpart, err;
  70. d = PyFloat_AsDouble(obj);
  71. floatpart = modf(d, &intpart);
  72. if (floatpart < 0) {
  73. floatpart = 1.0 + floatpart;
  74. intpart -= 1.0;
  75. }
  76. *sec = (time_t)intpart;
  77. err = intpart - (double)*sec;
  78. if (err <= -1.0 || err >= 1.0)
  79. goto overflow;
  80. floatpart *= 1e9;
  81. *nsec = (long)floatpart;
  82. return 0;
  83. }
  84. else {
  85. #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
  86. *sec = PyLong_AsLongLong(obj);
  87. #else
  88. assert(sizeof(time_t) <= sizeof(long));
  89. *sec = PyLong_AsLong(obj);
  90. #endif
  91. if (*sec == -1 && PyErr_Occurred()) {
  92. if (PyErr_ExceptionMatches(PyExc_OverflowError))
  93. goto overflow;
  94. else
  95. return -1;
  96. }
  97. *nsec = 0;
  98. return 0;
  99. }
  100. overflow:
  101. PyErr_SetString(PyExc_OverflowError,
  102. "timestamp out of range for platform time_t");
  103. return -1;
  104. }
  105. void
  106. _PyTime_Init()
  107. {
  108. /* Do nothing. Needed to force linking. */
  109. }