--- a/uptime.c Thu Nov 11 22:42:45 2010 +0100
+++ b/uptime.c Sat Nov 13 17:51:20 2010 +0100
@@ -54,15 +54,72 @@
.next = &info_uptime_experimental,
};
+guint hz = 0;
+long long unsigned int mstime = 0;
time_t starttime = 0;
+gboolean proc_used = FALSE;
+
+static int sys_uptime (void)
+{
+ GString *line = g_string_new (NULL);
+ GError *error = NULL;
+ GIOStatus ret;
+ int sec, ssec;
+ GIOChannel *channel = g_io_channel_new_file ("/proc/uptime", "r", &error);
+ if (!channel) {
+ g_string_free (line, TRUE);
+ scr_log_print (LPRINT_LOGNORM,
+ "Cannot open system uptime for reading.");
+ return 0;
+ }
+ g_io_channel_set_close_on_unref (channel, TRUE);
+
+ ret = g_io_channel_read_line_string (channel, line, NULL, &error);
+ if (ret != G_IO_STATUS_NORMAL) {
+ if (error) {
+ scr_log_print (LPRINT_LOGNORM,
+ "uptime: System uptime reading error: %s.",
+ error -> message);
+ g_error_free (error);
+ }
+ g_io_channel_unref (channel);
+ g_string_free (line, TRUE);
+ return 0;
+ }
+ g_io_channel_unref (channel);
+ if (sscanf (line -> str, "%d.%ds", &sec, &ssec) != 2) {
+ scr_log_print (LPRINT_LOGNORM,
+ "Unable to parse system uptime.");
+ g_string_free (line, TRUE);
+ return 0;
+ }
+ return (sec * hz) + (ssec * hz)/100;
+}
void do_uptime (char *arg)
{
GString *line = g_string_new (NULL);
- guint seconds = time (NULL) - starttime;
- guint minutes = seconds / 60;
- guint hours = minutes / 60;
- guint days = hours / 24;
+ guint seconds;
+ guint minutes;
+ guint hours;
+ guint days;
+ time_t now = time (NULL);
+
+ if (proc_used && settings_opt_get_int ("uptime_use_proc")) {
+ int sysup = sys_uptime();
+ if (!sysup) {
+ g_string_free (line, TRUE);
+ scr_log_print (LPRINT_NORMAL, "Uptime not available :-(");
+ return;
+ }
+ seconds = (sysup - mstime) / hz;
+ } else {
+ seconds = now - starttime;
+ }
+
+ minutes = seconds / 60;
+ hours = minutes / 60;
+ days = hours / 24;
seconds %= 60;
minutes %= 60;
hours %= 24;
@@ -83,9 +140,10 @@
gchar *g_module_check_init (GModule *module)
{
+ starttime = time (NULL);
+
if (settings_opt_get_int ("uptime_use_proc")) {
- long long unsigned int mstime = 0;
- long long unsigned int kbtime = 0;
+ //long long unsigned int kbtime = 0;
GError *error = NULL;
GString *line;
GIOChannel *channel = g_io_channel_new_file ("/proc/self/stat", "r", &error);
@@ -97,7 +155,7 @@
line = g_string_new (NULL);
if (g_io_channel_read_line_string (channel, line, NULL, &error) != G_IO_STATUS_NORMAL) {
if (error) {
- scr_log_print (LPRINT_DEBUG, "uptime: Own stats reading error: %s.", error -> message);
+ scr_log_print (LPRINT_LOGNORM, "uptime: Own stats reading error: %s.", error -> message);
g_error_free (error);
}
g_io_channel_unref (channel);
@@ -110,6 +168,7 @@
g_string_free (line, TRUE);
return "Missing ) in own stats";
}
+ p++;
while (*p && isspace (*p)) p++;
while (*p && isalpha (*p)) p++; // state (%c)
while (*p && isspace (*p)) p++;
@@ -160,36 +219,12 @@
g_string_free (line, TRUE);
return "Malformed own start time.";
}
-
- channel = g_io_channel_new_file ("/proc/stat", "r", &error);
- if (!channel) {
- g_string_free (line, TRUE);
- return "Cannot open system stats for reading";
- }
- g_io_channel_set_close_on_unref (channel, TRUE);
-
- while (TRUE) {
- GIOStatus ret = g_io_channel_read_line_string (channel, line, NULL, &error);
- if (ret != G_IO_STATUS_NORMAL) {
- if (error) {
- scr_log_print (LPRINT_DEBUG, "uptime: System stats reading error: %s.", error -> message);
- g_error_free (error);
- }
- g_io_channel_unref (channel);
- g_string_free (line, TRUE);
- return "Error reading system stats.";
- }
- if (sscanf (line -> str, "btime %llu", &kbtime))
- break;
- }
- g_io_channel_unref (channel);
-
g_string_free (line, TRUE);
- guint hz = sysconf(_SC_CLK_TCK);
- starttime = kbtime + (mstime / hz);
- } else
- starttime = time (NULL);
+ hz = sysconf(_SC_CLK_TCK);
+ if (hz && mstime)
+ proc_used = TRUE;
+ }
cmd_add ("uptime", "", 0, 0, do_uptime, NULL);
return NULL;