# HG changeset patch # User Mikael Berthe # Date 1289667080 -3600 # Node ID af9ebb57baf65111886f0ba0cfd938b44bdde380 # Parent 6524d7d3061b2f7310acf2ee89cecbf82493445d (Hopefully) Fix usage of the proc filesystem diff -r 6524d7d3061b -r af9ebb57baf6 uptime.c --- 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;