Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions Lib/test/pythoninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,18 @@ def uptime_linux():
return


def uptime_bsd():
# Get sysctlbyname("kern.boottime")
try:
import _testcapi
except ImportError:
return None
try:
return _testcapi.uptime_bsd()
except (AttributeError, OSError):
return None


def uptime_windows():
try:
import _winapi
Expand All @@ -1093,7 +1105,7 @@ def uptime_windows():


def get_uptime():
for func in (uptime_boottime, uptime_linux, uptime_windows):
for func in (uptime_boottime, uptime_linux, uptime_bsd, uptime_windows):
uptime = func()
if uptime is not None:
return uptime
Expand All @@ -1107,9 +1119,15 @@ def get_machine_id():
if machine_guid:
return machine_guid

machine_id = read_first_line("/etc/machine-id")
if machine_id:
return machine_id
for filename in (
# https://www.freedesktop.org/software/systemd/man/latest/machine-id.html
"/etc/machine-id",
# BSD
"/etc/hostid",
):
machine_id = read_first_line(filename)
if machine_id:
return machine_id

return None

Expand All @@ -1119,7 +1137,6 @@ def collect_linux(info_add):
if boot_id:
info_add('system.boot_id', boot_id)

# https://www.freedesktop.org/software/systemd/man/latest/machine-id.html
machine_id = get_machine_id()
if machine_id:
info_add('system.machine_id', machine_id)
Expand Down
31 changes: 31 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h> // W_STOPCODE
#endif
#ifdef HAVE_SYS_SYSCTL_H
# include <sys/sysctl.h> // sysctlbyname()
#endif

#ifdef bool
# error "The public headers should not include <stdbool.h>, see gh-48924"
Expand Down Expand Up @@ -2970,6 +2973,31 @@ test_soft_deprecated_macros(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)
Py_RETURN_NONE;
}


#ifdef HAVE_SYSCTLBYNAME
static PyObject*
uptime_bsd(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
{
struct timeval tv;
size_t size = sizeof(tv);
int res = sysctlbyname("kern.boottime", &tv, &size, NULL, 0);
if (res != 0) {
return PyErr_SetFromErrno(PyExc_OSError);
}
double boottime = (double)tv.tv_sec + tv.tv_usec * 1e-6;

PyTime_t now_t;
if (PyTime_Time(&now_t) < 0) {
return NULL;
}
double now = PyTime_AsSecondsDouble(now_t);

double uptime = now - boottime;
return PyFloat_FromDouble(uptime);
}
#endif


static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
Expand Down Expand Up @@ -3076,6 +3104,9 @@ static PyMethodDef TestMethods[] = {
{"test_thread_state_ensure_detachment", test_thread_state_ensure_detachment, METH_NOARGS},
{"test_thread_state_ensure_detached_gilstate", test_thread_state_ensure_detached_gilstate, METH_NOARGS},
{"test_thread_state_release_with_destructor", test_thread_state_release_with_destructor, METH_NOARGS},
#ifdef HAVE_SYSCTLBYNAME
{"uptime_bsd", uptime_bsd, METH_NOARGS},
#endif
{NULL, NULL} /* sentinel */
};

Expand Down
12 changes: 12 additions & 0 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3163,7 +3163,8 @@ AC_CHECK_HEADERS([ \
sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \
sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/pidfd.h sys/poll.h \
sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \
sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h sys/timerfd.h \
sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysctl.h \
sys/sysmacros.h sys/termio.h sys/time.h sys/times.h sys/timerfd.h \
sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \
termios.h util.h utime.h utmp.h \
])
Expand Down Expand Up @@ -5431,7 +5432,7 @@ AC_CHECK_FUNCS([ \
setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \
sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \
sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \
sysconf sysctlbyname tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \
tmpnam tmpnam_r truncate ttyname_r umask uname unlinkat unlockpt utimensat utimes vfork \
wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \
])
Expand Down
6 changes: 6 additions & 0 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -1417,6 +1417,9 @@
/* Define to 1 if you have the 'sysconf' function. */
#undef HAVE_SYSCONF

/* Define to 1 if you have the 'sysctlbyname' function. */
#undef HAVE_SYSCTLBYNAME

/* Define to 1 if you have the <sysexits.h> header file. */
#undef HAVE_SYSEXITS_H

Expand Down Expand Up @@ -1521,6 +1524,9 @@
/* Define to 1 if you have the <sys/syscall.h> header file. */
#undef HAVE_SYS_SYSCALL_H

/* Define to 1 if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H

/* Define to 1 if you have the <sys/sysmacros.h> header file. */
#undef HAVE_SYS_SYSMACROS_H

Expand Down
Loading