diff --git a/Include/py_available.h b/Include/py_available.h new file mode 100644 index 00000000000000..7933d3a6246c8b --- /dev/null +++ b/Include/py_available.h @@ -0,0 +1,49 @@ +#ifndef Py_AVAILABLE_H +#define Py_AVAILABLE_H + +#include "Python.h" + +#ifdef __has_builtin +#if __has_builtin(__builtin_available) +#define HAVE_BUILTIN_AVAILABLE 1 +#endif +#endif + +#if __APPLE__ && HAVE_BUILTIN_AVAILABLE +#define HAVE_UTIMENSAT_RUNTIME __builtin_available(macos 10.13, ios 11, tvos 11, watchos 4, *) +#define HAVE_FUTIMENS_RUNTIME __builtin_available(macos 10.13, ios 11, tvos 11, watchos 4, *) +#define HAVE_PREADV_RUNTIME __builtin_available(macos 11.0, ios 14, tvos 14, watchos 7, *) +#define HAVE_PWRITEV_RUNTIME __builtin_available(macos 11.0, ios 14, tvos 14, watchos 7, *) +#define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macos 10.15, ios 13, tvos 13, watchos 6, *) +#define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macos 10.12, ios 10, tvos 10, watchos 3, *) +#define HAVE_CLOCK_SETTIME_RUNTIME __builtin_available(macos 10.12, ios 10, tvos 10, watchos 3, *) +#define HAVE_CLOCK_GETRES_RUNTIME __builtin_available(macos 10.12, ios 10, tvos 10, watchos 3, *) +#define HAVE_GETENTROPY_RUNTIME __builtin_available(macos 10.12, ios 10, tvos 10, watchos 3, *) +#else +#define HAVE_UTIMENSAT_RUNTIME 1 +#define HAVE_FUTIMENS_RUNTIME 1 +#define HAVE_PREADV_RUNTIME 1 +#define HAVE_PWRITEV_RUNTIME 1 +#define HAVE_POSIX_SPAWN_SETSID_RUNTIME 1 +#define HAVE_CLOCK_GETTIME_RUNTIME 1 +#define HAVE_CLOCK_SETTIME_RUNTIME 1 +#define HAVE_CLOCK_GETRES_RUNTIME 1 +#define HAVE_GETENTROPY_RUNTIME 1 +#endif + +static inline void +Py_delete_method(PyMethodDef *methods, size_t size, const char *name) +{ + int last_method_index = (size /sizeof(PyMethodDef)) - 1; + for (int i = last_method_index; i >= 0; i--) { + if ( methods[i].ml_name && 0==strcmp(methods[i].ml_name, name)) { + for (int j = i; methods[j].ml_name != NULL; j++) { + methods[j] = methods[j+1]; + } + break; + } + } +} + +#endif + diff --git a/Misc/NEWS.d/next/macOS/2020-07-21-06-03-19.bpo-41100.6Et7be.rst b/Misc/NEWS.d/next/macOS/2020-07-21-06-03-19.bpo-41100.6Et7be.rst new file mode 100644 index 00000000000000..b03a6febac362f --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2020-07-21-06-03-19.bpo-41100.6Et7be.rst @@ -0,0 +1 @@ +Add runtime checks so python can be built for Mac OS 10.10 using the latest Xcode \ No newline at end of file diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index efd99544f5a997..e659d20bf5734e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -42,6 +42,7 @@ #else # include "winreparse.h" #endif +#include "py_available.h" /* On android API level 21, 'AT_EACCESS' is not declared although * HAVE_FACCESSAT is defined. */ @@ -4826,9 +4827,14 @@ static int utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks) { #ifdef HAVE_UTIMENSAT - int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; - UTIME_TO_TIMESPEC; - return utimensat(dir_fd, path, time, flags); + if (HAVE_UTIMENSAT_RUNTIME) { + int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; + UTIME_TO_TIMESPEC; + return utimensat(dir_fd, path, time, flags); + } else { + PyErr_SetString(PyExc_NotImplementedError, "utimensat is not available"); + return -1; + } #elif defined(HAVE_FUTIMESAT) UTIME_TO_TIMEVAL; /* @@ -4841,7 +4847,16 @@ utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks) #endif } - #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter +static int +utime_dir_fd_converter(PyObject *o, void *p) +{ + if (HAVE_UTIMENSAT_RUNTIME) + return dir_fd_converter(o,p); + else + return dir_fd_unavailable(o, p); +} + + #define FUTIMENSAT_DIR_FD_CONVERTER utime_dir_fd_converter #else #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable #endif @@ -4852,12 +4867,15 @@ static int utime_fd(utime_t *ut, int fd) { #ifdef HAVE_FUTIMENS - UTIME_TO_TIMESPEC; - return futimens(fd, time); -#else - UTIME_TO_TIMEVAL; - return futimes(fd, time); + if (HAVE_FUTIMENS_RUNTIME) { + UTIME_TO_TIMESPEC; + return futimens(fd, time); + } else #endif + { + UTIME_TO_TIMEVAL; + return futimes(fd, time); + } } #define PATH_UTIME_HAVE_FD 1 @@ -4875,12 +4893,15 @@ static int utime_nofollow_symlinks(utime_t *ut, const char *path) { #ifdef HAVE_UTIMENSAT - UTIME_TO_TIMESPEC; - return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW); -#else - UTIME_TO_TIMEVAL; - return lutimes(path, time); + if (HAVE_FUTIMENS_RUNTIME) { + UTIME_TO_TIMESPEC; + return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW); + } else #endif + { + UTIME_TO_TIMEVAL; + return lutimes(path, time); + } } #endif @@ -4891,9 +4912,12 @@ static int utime_default(utime_t *ut, const char *path) { #ifdef HAVE_UTIMENSAT - UTIME_TO_TIMESPEC; - return utimensat(DEFAULT_DIR_FD, path, time, 0); -#elif defined(HAVE_UTIMES) + if (HAVE_UTIMENSAT_RUNTIME) { + UTIME_TO_TIMESPEC; + return utimensat(DEFAULT_DIR_FD, path, time, 0); + } +#endif +#if defined(HAVE_UTIMES) UTIME_TO_TIMEVAL; return utimes(path, time); #elif defined(HAVE_UTIME_H) @@ -5513,7 +5537,12 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg if (setsid) { #ifdef POSIX_SPAWN_SETSID - all_flags |= POSIX_SPAWN_SETSID; + if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) { + all_flags |= POSIX_SPAWN_SETSID; + } else { + argument_unavailable_error(func_name, "setsid"); + return -1; + } #elif defined(POSIX_SPAWN_SETSID_NP) all_flags |= POSIX_SPAWN_SETSID_NP; #else @@ -7168,7 +7197,8 @@ os_getgroups_impl(PyObject *module) * always first call getgroups with length 0 to get the actual number * of groups. */ - n = getgroups(0, NULL); + /* getgroups will not fill the last slot with a gid, so we need +1 */ + n = getgroups(0, NULL) + 1; if (n < 0) { return posix_error(); } else if (n <= MAX_GROUPS) { @@ -9255,6 +9285,12 @@ os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, int flags) /*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/ { + /* preadv method will be deleted if preadv is not available */ + #if __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunguarded-availability-new" + #endif + Py_ssize_t cnt, n; int async_err = 0; struct iovec *iov; @@ -9308,6 +9344,10 @@ os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, } return n; + + #if __clang__ + #pragma clang diagnostic pop + #endif } #endif /* HAVE_PREADV */ @@ -9850,6 +9890,12 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, int flags) /*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/ { + /* pwritev method will be deleted if preadv is not available */ + #if __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunguarded-availability-new" + #endif + Py_ssize_t cnt; Py_ssize_t result; int async_err = 0; @@ -9904,6 +9950,10 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, } return result; + + #if __clang__ + #pragma clang diagnostic pop + #endif } #endif /* HAVE_PWRITEV */ @@ -14156,9 +14206,7 @@ static PyMethodDef posix_methods[] = { OS_READ_METHODDEF OS_READV_METHODDEF OS_PREAD_METHODDEF - OS_PREADV_METHODDEF OS_WRITE_METHODDEF - OS_WRITEV_METHODDEF OS_PWRITE_METHODDEF OS_PWRITEV_METHODDEF OS_SENDFILE_METHODDEF @@ -14228,6 +14276,9 @@ static PyMethodDef posix_methods[] = { OS__ADD_DLL_DIRECTORY_METHODDEF OS__REMOVE_DLL_DIRECTORY_METHODDEF OS_WAITSTATUS_TO_EXITCODE_METHODDEF + + OS_PREADV_METHODDEF + OS_WRITEV_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -15070,6 +15121,10 @@ posixmodule_exec(PyObject *m) return -1; } for (const char * const *trace = have_functions; *trace; trace++) { + if (HAVE_UTIMENSAT_RUNTIME) {} else if (0==strcmp(*trace, "HAVE_UTIMENSAT")) continue; + if (HAVE_FUTIMENS_RUNTIME) {} else if (0==strcmp(*trace, "HAVE_FUTIMENS")) continue; + if (HAVE_PREADV_RUNTIME) {} else if (0==strcmp(*trace, "HAVE_PREADV")) continue; + if (HAVE_PWRITEV_RUNTIME) {} else if (0==strcmp(*trace, "HAVE_PWRITEV")) continue; PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL); if (!unicode) return -1; @@ -15100,9 +15155,21 @@ static struct PyModuleDef posixmodule = { .m_free = _posix_free, }; +static void +delete_method(const char *name) +{ + Py_delete_method(posix_methods, sizeof(posix_methods), name); +} + PyMODINIT_FUNC INITFUNC(void) { + #ifdef HAVE_PREADV + if (HAVE_PREADV_RUNTIME) {} else { delete_method("preadv"); } + #endif + #ifdef HAVE_PWRITEV + if (HAVE_PWRITEV_RUNTIME) {} else { delete_method("pwritev"); } + #endif return PyModuleDef_Init(&posixmodule); } diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 8a4d149befb52a..b1a2625879903c 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -1,6 +1,7 @@ /* Time module */ #include "Python.h" +#include "py_available.h" #include @@ -152,25 +153,30 @@ perf_counter(_Py_clock_info_t *info) static PyObject * time_clock_gettime(PyObject *self, PyObject *args) { - int ret; - struct timespec tp; - -#if defined(_AIX) && (SIZEOF_LONG == 8) - long clk_id; - if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) { -#else - int clk_id; - if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { -#endif - return NULL; - } + if (HAVE_CLOCK_GETTIME_RUNTIME) { + int ret; + struct timespec tp; + + #if defined(_AIX) && (SIZEOF_LONG == 8) + long clk_id; + if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) { + #else + int clk_id; + if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { + #endif + return NULL; + } - ret = clock_gettime((clockid_t)clk_id, &tp); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); + ret = clock_gettime((clockid_t)clk_id, &tp); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); + } else { + PyErr_SetString(PyExc_NotImplementedError, "clock_gettime is not available"); return NULL; } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); } PyDoc_STRVAR(clock_gettime_doc, @@ -181,24 +187,29 @@ Return the time of the specified clock clk_id."); static PyObject * time_clock_gettime_ns(PyObject *self, PyObject *args) { - int ret; - int clk_id; - struct timespec ts; - _PyTime_t t; + if (HAVE_CLOCK_GETTIME_RUNTIME) { + int ret; + int clk_id; + struct timespec ts; + _PyTime_t t; - if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { - return NULL; - } + if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { + return NULL; + } - ret = clock_gettime((clockid_t)clk_id, &ts); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - if (_PyTime_FromTimespec(&t, &ts) < 0) { + ret = clock_gettime((clockid_t)clk_id, &ts); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (_PyTime_FromTimespec(&t, &ts) < 0) { + return NULL; + } + return _PyTime_AsNanosecondsObject(t); + } else { + PyErr_SetString(PyExc_NotImplementedError, "clock_gettime is not available"); return NULL; } - return _PyTime_AsNanosecondsObject(t); } PyDoc_STRVAR(clock_gettime_ns_doc, @@ -211,27 +222,32 @@ Return the time of the specified clock clk_id as nanoseconds."); static PyObject * time_clock_settime(PyObject *self, PyObject *args) { - int clk_id; - PyObject *obj; - _PyTime_t t; - struct timespec tp; - int ret; - - if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) - return NULL; + if (HAVE_CLOCK_SETTIME_RUNTIME) { + int clk_id; + PyObject *obj; + _PyTime_t t; + struct timespec tp; + int ret; + + if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) + return NULL; - if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0) - return NULL; + if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0) + return NULL; - if (_PyTime_AsTimespec(t, &tp) == -1) - return NULL; + if (_PyTime_AsTimespec(t, &tp) == -1) + return NULL; - ret = clock_settime((clockid_t)clk_id, &tp); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); + ret = clock_settime((clockid_t)clk_id, &tp); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; + } else { + PyErr_SetString(PyExc_NotImplementedError, "clock_settime is not available"); return NULL; } - Py_RETURN_NONE; } PyDoc_STRVAR(clock_settime_doc, @@ -242,29 +258,34 @@ Set the time of the specified clock clk_id."); static PyObject * time_clock_settime_ns(PyObject *self, PyObject *args) { - int clk_id; - PyObject *obj; - _PyTime_t t; - struct timespec ts; - int ret; - - if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) { - return NULL; - } + if (HAVE_CLOCK_SETTIME_RUNTIME) { + int clk_id; + PyObject *obj; + _PyTime_t t; + struct timespec ts; + int ret; + + if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) { + return NULL; + } - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - if (_PyTime_AsTimespec(t, &ts) == -1) { - return NULL; - } + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (_PyTime_AsTimespec(t, &ts) == -1) { + return NULL; + } - ret = clock_settime((clockid_t)clk_id, &ts); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); + ret = clock_settime((clockid_t)clk_id, &ts); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; + } else { + PyErr_SetString(PyExc_NotImplementedError, "clock_settime is not available"); return NULL; } - Py_RETURN_NONE; } PyDoc_STRVAR(clock_settime_ns_doc, @@ -277,20 +298,25 @@ Set the time of the specified clock clk_id with nanoseconds."); static PyObject * time_clock_getres(PyObject *self, PyObject *args) { - int ret; - int clk_id; - struct timespec tp; + if (HAVE_CLOCK_GETRES_RUNTIME) { + int ret; + int clk_id; + struct timespec tp; - if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id)) - return NULL; + if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id)) + return NULL; - ret = clock_getres((clockid_t)clk_id, &tp); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); + ret = clock_getres((clockid_t)clk_id, &tp); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); + } else { + PyErr_SetString(PyExc_NotImplementedError, "clock_getres is not available"); return NULL; } - - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); } PyDoc_STRVAR(clock_getres_doc, @@ -1170,23 +1196,25 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)"; #endif - if (clock_gettime(clk_id, &ts) == 0) { - if (info) { - struct timespec res; - info->implementation = function; - info->monotonic = 1; - info->adjustable = 0; - if (clock_getres(clk_id, &res)) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; + if (HAVE_CLOCK_GETTIME_RUNTIME) { + if (clock_gettime(clk_id, &ts) == 0) { + if (info) { + struct timespec res; + info->implementation = function; + info->monotonic = 1; + info->adjustable = 0; + if (clock_getres(clk_id, &res)) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; } - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - } - if (_PyTime_FromTimespec(tp, &ts) < 0) { - return -1; + if (_PyTime_FromTimespec(tp, &ts) < 0) { + return -1; + } + return 0; } - return 0; } #endif @@ -1309,6 +1337,7 @@ sum of the kernel and user-space CPU time."); #if defined(MS_WINDOWS) #define HAVE_THREAD_TIME +#define HAVE_THREAD_TIME_RUNTIME 1 static int _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) { @@ -1349,6 +1378,7 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) #elif defined(_AIX) #define HAVE_THREAD_TIME +#define HAVE_THREAD_TIME_RUNTIME 1 static int _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) { @@ -1373,6 +1403,7 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) #define HAVE_THREAD_TIME +#define HAVE_THREAD_TIME_RUNTIME HAVE_CLOCK_GETTIME_RUNTIME static int _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) { @@ -1380,10 +1411,16 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID; const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)"; - if (clock_gettime(clk_id, &ts)) { - PyErr_SetFromErrno(PyExc_OSError); + if (HAVE_CLOCK_GETTIME_RUNTIME) { + if (clock_gettime(clk_id, &ts)) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + } else { + PyErr_SetString(PyExc_NotImplementedError, "clock_gettime is not available"); return -1; } + if (info) { struct timespec res; info->implementation = function; @@ -1694,17 +1731,6 @@ init_timezone(PyObject *m) static PyMethodDef time_methods[] = { {"time", time_time, METH_NOARGS, time_doc}, {"time_ns", time_time_ns, METH_NOARGS, time_ns_doc}, -#ifdef HAVE_CLOCK_GETTIME - {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, - {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc}, -#endif -#ifdef HAVE_CLOCK_SETTIME - {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, - {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc}, -#endif -#ifdef HAVE_CLOCK_GETRES - {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc}, -#endif #ifdef HAVE_PTHREAD_GETCPUCLOCKID {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc}, #endif @@ -1727,13 +1753,24 @@ static PyMethodDef time_methods[] = { {"monotonic_ns", time_monotonic_ns, METH_NOARGS, monotonic_ns_doc}, {"process_time", time_process_time, METH_NOARGS, process_time_doc}, {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc}, + {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, + {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc}, + {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, +#ifdef HAVE_CLOCK_GETTIME + {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, + {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc}, +#endif +#ifdef HAVE_CLOCK_SETTIME + {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, + {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc}, +#endif #ifdef HAVE_THREAD_TIME {"thread_time", time_thread_time, METH_NOARGS, thread_time_doc}, {"thread_time_ns", time_thread_time_ns, METH_NOARGS, thread_time_ns_doc}, #endif - {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, - {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc}, - {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, +#ifdef HAVE_CLOCK_GETRES + {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc}, +#endif {NULL, NULL} /* sentinel */ }; @@ -1874,9 +1911,42 @@ static struct PyModuleDef timemodule = { NULL }; +static void +delete_method(const char *name) +{ + Py_delete_method(time_methods, sizeof(time_methods), name); +} + PyMODINIT_FUNC PyInit_time(void) { + #ifdef HAVE_CLOCK_GETTIME + if (HAVE_CLOCK_GETTIME_RUNTIME) {} else { + delete_method("clock_gettime"); + delete_method("clock_gettime_ns"); + } + #endif + + #ifdef HAVE_CLOCK_SETTIME + if (HAVE_CLOCK_SETTIME_RUNTIME) {} else { + delete_method("clock_settime"); + delete_method("clock_settime_ns"); + } + #endif + + #ifdef HAVE_CLOCK_GETRES + if (HAVE_CLOCK_GETRES_RUNTIME) {} else { + delete_method("clock_getres"); + } + #endif + + #ifdef HAVE_THREAD_TIME + if (HAVE_THREAD_TIME_RUNTIME) {} else { + delete_method("thread_time"); + delete_method("thread_time_ns"); + } + #endif + return PyModuleDef_Init(&timemodule); } diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index 47369305ee88e9..69e1b1dcf22197 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -1,5 +1,6 @@ #include "Python.h" #include "pycore_initconfig.h" +#include "py_available.h" #ifdef MS_WINDOWS # include /* All sample MSDN wincrypt programs include the header below. It is at least @@ -225,13 +226,19 @@ py_getentropy(char *buffer, Py_ssize_t size, int raise) Py_ssize_t len = Py_MIN(size, 256); int res; - if (raise) { - Py_BEGIN_ALLOW_THREADS - res = getentropy(buffer, len); - Py_END_ALLOW_THREADS - } - else { - res = getentropy(buffer, len); + + if (HAVE_GETENTROPY_RUNTIME) { + if (raise) { + Py_BEGIN_ALLOW_THREADS + res = getentropy(buffer, len); + Py_END_ALLOW_THREADS + } + else { + res = getentropy(buffer, len); + } + } else { + getentropy_works = 0; + return 0; } if (res < 0) { diff --git a/Python/pytime.c b/Python/pytime.c index b121b432f428d7..7978e4b41206cc 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "py_available.h" #ifdef MS_WINDOWS #include /* struct timeval */ #endif @@ -683,59 +684,58 @@ pygettimeofday(_PyTime_t *tp, _Py_clock_info_t *info, int raise) #else /* MS_WINDOWS */ int err; -#ifdef HAVE_CLOCK_GETTIME - struct timespec ts; -#else - struct timeval tv; -#endif assert(info == NULL || raise); #ifdef HAVE_CLOCK_GETTIME - err = clock_gettime(CLOCK_REALTIME, &ts); - if (err) { - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); + if (HAVE_CLOCK_GETTIME_RUNTIME) { + struct timespec ts; + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err) { + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; + } + if (pytime_fromtimespec(tp, &ts, raise) < 0) { + return -1; } - return -1; - } - if (pytime_fromtimespec(tp, &ts, raise) < 0) { - return -1; - } - if (info) { - struct timespec res; - info->implementation = "clock_gettime(CLOCK_REALTIME)"; - info->monotonic = 0; - info->adjustable = 1; - if (clock_getres(CLOCK_REALTIME, &res) == 0) { - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + if (info) { + struct timespec res; + info->implementation = "clock_gettime(CLOCK_REALTIME)"; + info->monotonic = 0; + info->adjustable = 1; + if (clock_getres(CLOCK_REALTIME, &res) == 0) { + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + } + else { + info->resolution = 1e-9; + } } - else { - info->resolution = 1e-9; + } else +#endif /* HAVE_CLOCK_GETTIME */ + { + struct timeval tv; + /* test gettimeofday() */ + err = gettimeofday(&tv, (struct timezone *)NULL); + if (err) { + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; } - } -#else /* HAVE_CLOCK_GETTIME */ - - /* test gettimeofday() */ - err = gettimeofday(&tv, (struct timezone *)NULL); - if (err) { - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); + if (pytime_fromtimeval(tp, &tv, raise) < 0) { + return -1; } - return -1; - } - if (pytime_fromtimeval(tp, &tv, raise) < 0) { - return -1; - } - if (info) { - info->implementation = "gettimeofday()"; - info->resolution = 1e-6; - info->monotonic = 0; - info->adjustable = 1; + if (info) { + info->implementation = "gettimeofday()"; + info->resolution = 1e-6; + info->monotonic = 0; + info->adjustable = 1; + } } -#endif /* !HAVE_CLOCK_GETTIME */ #endif /* !MS_WINDOWS */ return 0; }