|
22 | 22 | #ifdef HAVE_SYS_WAIT_H |
23 | 23 | # include <sys/wait.h> // W_STOPCODE |
24 | 24 | #endif |
| 25 | +#ifdef HAVE_SYS_SYSCTL_H |
| 26 | +# include <sys/sysctl.h> // sysctlbyname() |
| 27 | +#endif |
25 | 28 |
|
26 | 29 | #ifdef bool |
27 | 30 | # error "The public headers should not include <stdbool.h>, see gh-48924" |
@@ -2568,6 +2571,31 @@ toggle_reftrace_printer(PyObject *ob, PyObject *arg) |
2568 | 2571 | Py_RETURN_NONE; |
2569 | 2572 | } |
2570 | 2573 |
|
| 2574 | + |
| 2575 | +#ifdef HAVE_SYSCTLBYNAME |
| 2576 | +static PyObject* |
| 2577 | +uptime_bsd(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) |
| 2578 | +{ |
| 2579 | + struct timeval tv; |
| 2580 | + size_t size = sizeof(tv); |
| 2581 | + int res = sysctlbyname("kern.boottime", &tv, &size, NULL, 0); |
| 2582 | + if (res != 0) { |
| 2583 | + return PyErr_SetFromErrno(PyExc_OSError); |
| 2584 | + } |
| 2585 | + double boottime = (double)tv.tv_sec + tv.tv_usec * 1e-6; |
| 2586 | + |
| 2587 | + PyTime_t now_t; |
| 2588 | + if (PyTime_Time(&now_t) < 0) { |
| 2589 | + return NULL; |
| 2590 | + } |
| 2591 | + double now = PyTime_AsSecondsDouble(now_t); |
| 2592 | + |
| 2593 | + double uptime = now - boottime; |
| 2594 | + return PyFloat_FromDouble(uptime); |
| 2595 | +} |
| 2596 | +#endif |
| 2597 | + |
| 2598 | + |
2571 | 2599 | static PyMethodDef TestMethods[] = { |
2572 | 2600 | {"set_errno", set_errno, METH_VARARGS}, |
2573 | 2601 | {"test_config", test_config, METH_NOARGS}, |
@@ -2663,6 +2691,9 @@ static PyMethodDef TestMethods[] = { |
2663 | 2691 | {"test_atexit", test_atexit, METH_NOARGS}, |
2664 | 2692 | {"code_offset_to_line", _PyCFunction_CAST(code_offset_to_line), METH_FASTCALL}, |
2665 | 2693 | {"toggle_reftrace_printer", toggle_reftrace_printer, METH_O}, |
| 2694 | +#ifdef HAVE_SYSCTLBYNAME |
| 2695 | + {"uptime_bsd", uptime_bsd, METH_NOARGS}, |
| 2696 | +#endif |
2666 | 2697 | {NULL, NULL} /* sentinel */ |
2667 | 2698 | }; |
2668 | 2699 |
|
|
0 commit comments