From ed48a03b21630019181a324fff40d2426551253c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 29 Sep 2017 23:39:32 -0700 Subject: QSysInfo: add a function that returns the boot ID [ChangeLog][QtCore][QSysInfo] Added machineUniqueId() and bootUniqueId(). Task-number: QTBUG-63425 Change-Id: I0b48fc8e90304e0dacc3fffd14e91064020d165b Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne Reviewed-by: Edward Welbourne --- src/corelib/global/qglobal.cpp | 44 ++++++++++++++++++++++++++++++++++++++++-- src/corelib/global/qsysinfo.h | 1 + 2 files changed, 43 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 62d4624878..619436e3db 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2873,7 +2873,7 @@ enum { this ID is usually permanent and it matches the D-Bus machine ID, except for nodes without their own storage (replicated nodes). - \sa machineHostName() + \sa machineHostName(), bootUniqueId() */ QByteArray QSysInfo::machineUniqueId() { @@ -2894,7 +2894,7 @@ QByteArray QSysInfo::machineUniqueId() return QByteArray(uuid, uuidlen); # endif #elif defined(Q_OS_UNIX) - // the modern name on Linux is /etc/machine-id, but that path is + // The modern name on Linux is /etc/machine-id, but that path is // unlikely to exist on non-Linux (non-systemd) systems. The old // path is more than enough. static const char fullfilename[] = "/usr/local/var/lib/dbus/machine-id"; @@ -2930,6 +2930,46 @@ QByteArray QSysInfo::machineUniqueId() return cache; } +/*! + \since 5.10 + + Returns a unique ID for this machine's boot, if one can be determined. If + no unique ID could be determined, this function returns an empty byte + array. This value is expected to change after every boot and can be + considered globally unique. + + This function is currently only implemented for Linux and Apple operating + systems. + + \sa machineUniqueId() +*/ +QByteArray QSysInfo::bootUniqueId() +{ + // the boot unique ID cannot change + static const QByteArray cache = []() { +#ifdef Q_OS_LINUX + // use low-level API here for simplicity + int fd = qt_safe_open("/proc/sys/kernel/random/boot_id", O_RDONLY); + if (fd != -1) { + char uuid[UuidStringLen]; + qint64 len = qt_safe_read(fd, uuid, sizeof(uuid)); + qt_safe_close(fd); + if (len == UuidStringLen) + return QByteArray(uuid, UuidStringLen); + } +#elif defined(Q_OS_DARWIN) + // "kern.bootsessionuuid" is only available by name + char uuid[UuidStringLen]; + size_t uuidlen = sizeof(uuid); + if (sysctlbyname("kern.bootsessionuuid", uuid, &uuidlen, nullptr, 0) == 0 + && uuidlen == sizeof(uuid)) + return QByteArray(uuid, uuidlen); +#endif + return QByteArray(); + }(); + return cache; +}; + /*! \macro void Q_ASSERT(bool test) \relates diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h index 1415dc8cd5..a3fa0fcb27 100644 --- a/src/corelib/global/qsysinfo.h +++ b/src/corelib/global/qsysinfo.h @@ -241,6 +241,7 @@ QT_WARNING_POP static QString machineHostName(); static QByteArray machineUniqueId(); + static QByteArray bootUniqueId(); }; #undef QT_SYSINFO_DEPRECATED_X -- cgit v1.2.3