summaryrefslogtreecommitdiffstats
path: root/Python/pytime.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2012-03-02 21:54:03 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2012-03-02 21:54:03 (GMT)
commit643cd68ea4b8d33a6d0163ef693ef6518f76b88f (patch)
tree4dda5f7783635633cc2d092dd975461ba263d2c0 /Python/pytime.c
parent1c13f84f5554cecbdce8bf42dbfb609c1f72282a (diff)
downloadcpython-643cd68ea4b8d33a6d0163ef693ef6518f76b88f.zip
cpython-643cd68ea4b8d33a6d0163ef693ef6518f76b88f.tar.gz
cpython-643cd68ea4b8d33a6d0163ef693ef6518f76b88f.tar.bz2
Issue #13964: signal.sigtimedwait() timeout is now a float instead of a tuple
Add a private API to convert an int or float to a C timespec structure.
Diffstat (limited to 'Python/pytime.c')
-rw-r--r--Python/pytime.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/Python/pytime.c b/Python/pytime.c
index bec1c71..d23ce75 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -70,6 +70,51 @@ _PyTime_gettimeofday(_PyTime_timeval *tp)
#endif /* MS_WINDOWS */
}
+int
+_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec)
+{
+ if (PyFloat_Check(obj)) {
+ double d, intpart, floatpart, err;
+
+ d = PyFloat_AsDouble(obj);
+ floatpart = modf(d, &intpart);
+ if (floatpart < 0) {
+ floatpart = 1.0 + floatpart;
+ intpart -= 1.0;
+ }
+
+ *sec = (time_t)intpart;
+ err = intpart - (double)*sec;
+ if (err <= -1.0 || err >= 1.0)
+ goto overflow;
+
+ floatpart *= 1e9;
+ *nsec = (long)floatpart;
+ return 0;
+ }
+ else {
+#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
+ *sec = PyLong_AsLongLong(obj);
+#else
+ assert(sizeof(time_t) <= sizeof(long));
+ *sec = PyLong_AsLong(obj);
+#endif
+ if (*sec == -1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ goto overflow;
+ else
+ return -1;
+ }
+ *nsec = 0;
+ return 0;
+ }
+
+overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "timestamp out of range for platform time_t");
+ return -1;
+}
+
void
_PyTime_Init()
{