src/daemon/collectd.c: Fix implementation of the -B option.
[collectd.git] / src / uptime.c
index 96a227d..8b83cf9 100644 (file)
@@ -25,7 +25,7 @@
 #include "plugin.h"
 
 #if KERNEL_LINUX
-#define STAT_FILE "/proc/stat"
+#define UPTIME_FILE "/proc/uptime"
 /* Using /proc filesystem to retrieve the boot time, Linux only. */
 /* #endif KERNEL_LINUX */
 
@@ -86,46 +86,30 @@ static int uptime_init(void) /* {{{ */
  */
 
 #if KERNEL_LINUX
-  unsigned long starttime;
-  char buffer[1024];
-  int ret;
-  FILE *fh;
-
-  ret = 0;
-
-  fh = fopen(STAT_FILE, "r");
-
+  FILE *fh = fopen(UPTIME_FILE, "r");
   if (fh == NULL) {
     char errbuf[1024];
-    ERROR("uptime plugin: Cannot open " STAT_FILE ": %s",
+    ERROR("uptime plugin: Cannot open " UPTIME_FILE ": %s",
           sstrerror(errno, errbuf, sizeof(errbuf)));
-    return (-1);
+    return -1;
   }
 
-  while (fgets(buffer, 1024, fh) != NULL) {
-    /* look for the btime string and read the value */
-    ret = sscanf(buffer, "btime %lu", &starttime);
-    /* avoid further loops if btime has been found and read
-     * correctly (hopefully) */
-    if (ret == 1)
-      break;
+  double uptime_seconds = 0.0;
+  if (fscanf(fh, "%lf", &uptime_seconds) != 1) {
+    ERROR("uptime plugin: No value read from " UPTIME_FILE "");
+    fclose(fh);
+    return -1;
   }
 
   fclose(fh);
 
-  /* loop done, check if no value has been found/read */
-  if (ret != 1) {
-    ERROR("uptime plugin: No value read from " STAT_FILE "");
-    return (-1);
+  if (uptime_seconds == 0.0) {
+    ERROR("uptime plugin: uptime read from " UPTIME_FILE ", "
+          "but it is zero!");
+    return -1;
   }
 
-  boottime = (time_t)starttime;
-
-  if (boottime == 0) {
-    ERROR("uptime plugin: btime read from " STAT_FILE ", "
-          "but `boottime' is zero!");
-    return (-1);
-  }
+  boottime = time(NULL) - (long)uptime_seconds;
 /* #endif KERNEL_LINUX */
 
 #elif HAVE_LIBKSTAT
@@ -139,24 +123,24 @@ static int uptime_init(void) /* {{{ */
    * went fine. */
   if (kc == NULL) {
     ERROR("uptime plugin: kstat chain control structure not available.");
-    return (-1);
+    return -1;
   }
 
   ksp = kstat_lookup(kc, "unix", 0, "system_misc");
   if (ksp == NULL) {
     ERROR("uptime plugin: Cannot find unix:0:system_misc kstat.");
-    return (-1);
+    return -1;
   }
 
   if (kstat_read(kc, ksp, NULL) < 0) {
     ERROR("uptime plugin: kstat_read failed.");
-    return (-1);
+    return -1;
   }
 
   knp = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time");
   if (knp == NULL) {
     ERROR("uptime plugin: kstat_data_lookup (boot_time) failed.");
-    return (-1);
+    return -1;
   }
 
   boottime = (time_t)knp->value.ui32;
@@ -164,7 +148,7 @@ static int uptime_init(void) /* {{{ */
   if (boottime == 0) {
     ERROR("uptime plugin: kstat_data_lookup returned success, "
           "but `boottime' is zero!");
-    return (-1);
+    return -1;
   }
 /* #endif HAVE_LIBKSTAT */
 
@@ -183,7 +167,7 @@ static int uptime_init(void) /* {{{ */
     char errbuf[1024];
     ERROR("uptime plugin: No value read from sysctl interface: %s",
           sstrerror(errno, errbuf, sizeof(errbuf)));
-    return (-1);
+    return -1;
   }
 
   boottime = boottv.tv_sec;
@@ -191,7 +175,7 @@ static int uptime_init(void) /* {{{ */
   if (boottime == 0) {
     ERROR("uptime plugin: sysctl(3) returned success, "
           "but `boottime' is zero!");
-    return (-1);
+    return -1;
   }
 /* #endif HAVE_SYS_SYSCTL_H */
 
@@ -205,7 +189,7 @@ static int uptime_init(void) /* {{{ */
     char errbuf[1024];
     ERROR("uptime plugin: perfstat_cpu_total: %s",
           sstrerror(errno, errbuf, sizeof(errbuf)));
-    return (-1);
+    return -1;
   }
 
   hertz = sysconf(_SC_CLK_TCK);
@@ -215,7 +199,7 @@ static int uptime_init(void) /* {{{ */
   boottime = time(NULL) - cputotal.lbolt / hertz;
 #endif /* HAVE_PERFSTAT */
 
-  return (0);
+  return 0;
 } /* }}} int uptime_init */
 
 static int uptime_read(void) {
@@ -229,7 +213,7 @@ static int uptime_read(void) {
 
   uptime_submit(uptime);
 
-  return (0);
+  return 0;
 }
 
 void module_register(void) {