summaryrefslogtreecommitdiffstats
path: root/src/detection/uptime
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/uptime
Add the files
Diffstat (limited to 'src/detection/uptime')
-rw-r--r--src/detection/uptime/uptime.h11
-rw-r--r--src/detection/uptime/uptime_bsd.c27
-rw-r--r--src/detection/uptime/uptime_haiku.c8
-rw-r--r--src/detection/uptime/uptime_linux.c38
-rw-r--r--src/detection/uptime/uptime_sunos.c19
-rw-r--r--src/detection/uptime/uptime_windows.c17
6 files changed, 120 insertions, 0 deletions
diff --git a/src/detection/uptime/uptime.h b/src/detection/uptime/uptime.h
new file mode 100644
index 0000000..3f8631c
--- /dev/null
+++ b/src/detection/uptime/uptime.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "fastfetch.h"
+#include "modules/uptime/option.h"
+
+typedef struct FFUptimeResult {
+ uint64_t bootTime;
+ uint64_t uptime;
+} FFUptimeResult;
+
+const char* ffDetectUptime(FFUptimeResult* result);
diff --git a/src/detection/uptime/uptime_bsd.c b/src/detection/uptime/uptime_bsd.c
new file mode 100644
index 0000000..46943b0
--- /dev/null
+++ b/src/detection/uptime/uptime_bsd.c
@@ -0,0 +1,27 @@
+#include "uptime.h"
+#include "common/time.h"
+
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+const char* ffDetectUptime(FFUptimeResult* result) {
+#if __NetBSD__
+ struct timespec bootTime;
+#else
+ struct timeval bootTime;
+#endif
+ size_t bootTimeSize = sizeof(bootTime);
+ if (sysctl(
+ (int[]) { CTL_KERN, KERN_BOOTTIME }, 2, &bootTime, &bootTimeSize, NULL, 0) != 0) {
+ return "sysctl({CTL_KERN, KERN_BOOTTIME}) failed";
+ }
+
+#if __NetBSD__
+ result->bootTime = (uint64_t) bootTime.tv_sec * 1000 + (uint64_t) bootTime.tv_nsec / 1000000;
+#else
+ result->bootTime = (uint64_t) bootTime.tv_sec * 1000 + (uint64_t) bootTime.tv_usec / 1000;
+#endif
+ result->uptime = ffTimeGetNow() - result->bootTime;
+
+ return NULL;
+}
diff --git a/src/detection/uptime/uptime_haiku.c b/src/detection/uptime/uptime_haiku.c
new file mode 100644
index 0000000..bf5dd25
--- /dev/null
+++ b/src/detection/uptime/uptime_haiku.c
@@ -0,0 +1,8 @@
+#include "uptime.h"
+#include "common/time.h"
+
+const char* ffDetectUptime(FFUptimeResult* result) {
+ result->uptime = (uint64_t) system_time() / 1000;
+ result->bootTime = ffTimeGetNow() - result->uptime;
+ return NULL;
+}
diff --git a/src/detection/uptime/uptime_linux.c b/src/detection/uptime/uptime_linux.c
new file mode 100644
index 0000000..75c7768
--- /dev/null
+++ b/src/detection/uptime/uptime_linux.c
@@ -0,0 +1,38 @@
+#include "uptime.h"
+#include "common/time.h"
+#include "common/io.h"
+
+#include <inttypes.h>
+
+const char* ffDetectUptime(FFUptimeResult* result) {
+#ifndef __ANDROID__ // cat: /proc/uptime: Permission denied
+
+ // #620
+ char buf[64];
+ ssize_t nRead = ffReadFileData("/proc/uptime", ARRAY_SIZE(buf) - 1, buf);
+ if (nRead > 0) {
+ buf[nRead] = '\0';
+
+ char* err = NULL;
+ double sec = strtod(buf, &err);
+ if (err != buf) {
+ result->uptime = (uint64_t) (sec * 1000);
+ result->bootTime = ffTimeGetNow() - result->uptime;
+ return NULL;
+ }
+ }
+
+#endif
+#ifndef __GNU__
+ struct timespec uptime;
+ if (clock_gettime(CLOCK_BOOTTIME, &uptime) != 0) {
+ return "clock_gettime(CLOCK_BOOTTIME) failed";
+ }
+
+ result->uptime = (uint64_t) uptime.tv_sec * 1000 + (uint64_t) uptime.tv_nsec / 1000000;
+ result->bootTime = ffTimeGetNow() - result->uptime;
+ return NULL;
+#else
+ return "read(/proc/uptime) failed";
+#endif
+}
diff --git a/src/detection/uptime/uptime_sunos.c b/src/detection/uptime/uptime_sunos.c
new file mode 100644
index 0000000..2a37299
--- /dev/null
+++ b/src/detection/uptime/uptime_sunos.c
@@ -0,0 +1,19 @@
+#include "uptime.h"
+#include "common/time.h"
+
+#include <utmpx.h>
+
+const char* ffDetectUptime(FFUptimeResult* result) {
+ struct utmpx* ut;
+
+ setutxent();
+ while (NULL != (ut = getutxent())) {
+ if (ut->ut_type == BOOT_TIME) {
+ result->bootTime = (uint64_t) ut->ut_tv.tv_sec * 1000 + (uint64_t) ut->ut_tv.tv_usec / 1000000;
+ result->uptime = ffTimeGetNow() - result->bootTime;
+ break;
+ }
+ }
+ endutxent();
+ return NULL;
+}
diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c
new file mode 100644
index 0000000..695edad
--- /dev/null
+++ b/src/detection/uptime/uptime_windows.c
@@ -0,0 +1,17 @@
+#include "uptime.h"
+#include "common/time.h"
+#include "common/windows/nt.h"
+
+const char* ffDetectUptime(FFUptimeResult* result) {
+ // QueryInterruptTime with Win7 support
+ uint64_t interruptTime = ffKSystemTimeToUInt64(&SharedUserData->InterruptTime);
+
+ result->uptime = interruptTime / 10000; // Convert from 100-nanosecond intervals to milliseconds
+ result->bootTime = ffTimeGetNow() - result->uptime;
+
+ // Alternatively, `NtQuerySystemInformation(SystemTimeOfDayInformation)` reports the boot time directly,
+ // whose result exactly equals what WMI `Win32_OperatingSystem` reports
+ // with much lower accuracy (0.5 seconds)
+
+ return NULL;
+}