X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fbattery.c;h=d142982df4c7926a08bee11bf778a405d8253c19;hb=bc7992ed0693313a2b1fe282a5bf23f1cc9f8e42;hp=bdf461945c7e780be1ed0e7d383054b0c046c7c6;hpb=dc80c73c20ef0e69c3850fd9679a827ad79e61a1;p=collectd.git diff --git a/src/battery.c b/src/battery.c index bdf46194..d142982d 100644 --- a/src/battery.c +++ b/src/battery.c @@ -48,45 +48,12 @@ # include #endif -#if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H || KERNEL_LINUX -# define BATTERY_HAVE_READ 1 -#else -# define BATTERY_HAVE_READ 0 +#if !HAVE_IOKIT_IOKITLIB_H && !HAVE_IOKIT_PS_IOPOWERSOURCES_H && !KERNEL_LINUX +# error "No applicable input method." #endif #define INVALID_VALUE 47841.29 -static data_source_t data_source_charge[1] = -{ - {"value", DS_TYPE_GAUGE, 0, NAN} -}; - -static data_set_t charge_ds = -{ - "charge", 1, data_source_charge -}; - -static data_source_t data_source_current[1] = -{ - {"value", DS_TYPE_GAUGE, NAN, NAN} -}; - -static data_set_t current_ds = -{ - "current", 1, data_source_current -}; - -static data_source_t data_source_voltage[1] = -{ - {"value", DS_TYPE_GAUGE, NAN, NAN} -}; - -static data_set_t voltage_ds = -{ - "voltage", 1, data_source_voltage -}; - -#if BATTERY_HAVE_READ #if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H /* No global variables */ /* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ @@ -94,6 +61,7 @@ static data_set_t voltage_ds = #elif KERNEL_LINUX static int battery_pmu_num = 0; static char *battery_pmu_file = "/proc/pmu/battery_%i"; +static const char *battery_acpi_dir = "/proc/acpi/battery"; #endif /* KERNEL_LINUX */ static int battery_init (void) @@ -108,9 +76,9 @@ static int battery_init (void) for (battery_pmu_num = 0; ; battery_pmu_num++) { - len = snprintf (filename, sizeof (filename), battery_pmu_file, battery_pmu_num); + len = ssnprintf (filename, sizeof (filename), battery_pmu_file, battery_pmu_num); - if ((len >= sizeof (filename)) || (len < 0)) + if ((len < 0) || ((unsigned int)len >= sizeof (filename))) break; if (access (filename, R_OK)) @@ -130,12 +98,12 @@ static void battery_submit (const char *plugin_instance, const char *type, doubl vl.values = values; vl.values_len = 1; - vl.time = time (NULL); - strcpy (vl.host, hostname_g); - strcpy (vl.plugin, "battery"); - strcpy (vl.plugin_instance, plugin_instance); + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "battery", sizeof (vl.plugin)); + sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); + sstrncpy (vl.type, type, sizeof (vl.type)); - plugin_dispatch_values (type, &vl); + plugin_dispatch_values (&vl); } /* void battery_submit */ #if HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H @@ -345,6 +313,100 @@ static void get_via_generic_iokit (double *ret_charge, } #endif /* HAVE_IOKIT_IOKITLIB_H */ +#if KERNEL_LINUX +static int battery_read_acpi (const char *dir, const char *name, + void *user_data) +{ + double current = INVALID_VALUE; + double voltage = INVALID_VALUE; + double charge = INVALID_VALUE; + double *valptr = NULL; + int charging = 0; + + char filename[256]; + FILE *fh; + + char buffer[1024]; + char *fields[8]; + int numfields; + char *endptr; + int len; + + len = ssnprintf (filename, sizeof (filename), "%s/%s/state", battery_acpi_dir, name); + + if ((len < 0) || ((unsigned int)len >= sizeof (filename))) + return -1; + + if ((fh = fopen (filename, "r")) == NULL) { + char errbuf[1024]; + ERROR ("Cannot open `%s': %s", filename, + sstrerror (errno, errbuf, sizeof (errbuf))); + return -1; + } + + /* + * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state + * [11:00] <@tokkee> present: yes + * [11:00] <@tokkee> capacity state: ok + * [11:00] <@tokkee> charging state: charging + * [11:00] <@tokkee> present rate: 1724 mA + * [11:00] <@tokkee> remaining capacity: 4136 mAh + * [11:00] <@tokkee> present voltage: 12428 mV + */ + while (fgets (buffer, sizeof (buffer), fh) != NULL) + { + numfields = strsplit (buffer, fields, 8); + + if (numfields < 3) + continue; + + if ((strcmp (fields[0], "charging") == 0) + && (strcmp (fields[1], "state:") == 0)) + { + if (strcmp (fields[2], "charging") == 0) + charging = 1; + else + charging = 0; + continue; + } + + if ((strcmp (fields[0], "present") == 0) + && (strcmp (fields[1], "rate:") == 0)) + valptr = ¤t; + else if ((strcmp (fields[0], "remaining") == 0) + && (strcmp (fields[1], "capacity:") == 0)) + valptr = &charge; + else if ((strcmp (fields[0], "present") == 0) + && (strcmp (fields[1], "voltage:") == 0)) + valptr = &voltage; + else + continue; + + endptr = NULL; + errno = 0; + *valptr = strtod (fields[2], &endptr) / 1000.0; + + if ((fields[2] == endptr) || (errno != 0)) + *valptr = INVALID_VALUE; + } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ + + fclose (fh); + + if ((current != INVALID_VALUE) && (charging == 0)) + current *= -1; + + if (charge != INVALID_VALUE) + battery_submit ("0", "charge", charge); + if (current != INVALID_VALUE) + battery_submit ("0", "current", current); + if (voltage != INVALID_VALUE) + battery_submit ("0", "voltage", voltage); + + return 0; +} +#endif /* KERNEL_LINUX */ + + static int battery_read (void) { #if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H @@ -392,12 +454,12 @@ static int battery_read (void) double charge = INVALID_VALUE; double *valptr = NULL; - len = snprintf (filename, sizeof (filename), battery_pmu_file, i); - if ((len >= sizeof (filename)) || (len < 0)) + len = ssnprintf (filename, sizeof (filename), battery_pmu_file, i); + if ((len < 0) || ((unsigned int)len >= sizeof (filename))) continue; - len = snprintf (batnum_str, sizeof (batnum_str), "%i", i); - if ((len >= sizeof (batnum_str)) || (len < 0)) + len = ssnprintf (batnum_str, sizeof (batnum_str), "%i", i); + if ((len < 0) || ((unsigned int)len >= sizeof (batnum_str))) continue; if ((fh = fopen (filename, "r")) == NULL) @@ -444,131 +506,16 @@ static int battery_read (void) battery_submit ("0", "voltage", voltage); } - if (access ("/proc/acpi/battery", R_OK | X_OK) == 0) - { - double current = INVALID_VALUE; - double voltage = INVALID_VALUE; - double charge = INVALID_VALUE; - double *valptr = NULL; - int charging = 0; - - struct dirent *ent; - DIR *dh; - - if ((dh = opendir ("/proc/acpi/battery")) == NULL) - { - char errbuf[1024]; - ERROR ("Cannot open `/proc/acpi/battery': %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while ((ent = readdir (dh)) != NULL) - { - if (ent->d_name[0] == '.') - continue; - - len = snprintf (filename, sizeof (filename), - "/proc/acpi/battery/%s/state", - ent->d_name); - if ((len >= sizeof (filename)) || (len < 0)) - continue; - - if ((fh = fopen (filename, "r")) == NULL) - { - char errbuf[1024]; - ERROR ("Cannot open `%s': %s", filename, - sstrerror (errno, errbuf, - sizeof (errbuf))); - continue; - } + walk_directory (battery_acpi_dir, battery_read_acpi, + /* user_data = */ NULL); - /* - * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state - * [11:00] <@tokkee> present: yes - * [11:00] <@tokkee> capacity state: ok - * [11:00] <@tokkee> charging state: charging - * [11:00] <@tokkee> present rate: 1724 mA - * [11:00] <@tokkee> remaining capacity: 4136 mAh - * [11:00] <@tokkee> present voltage: 12428 mV - */ - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - numfields = strsplit (buffer, fields, 8); - - if (numfields < 3) - continue; - - if ((strcmp (fields[0], "present") == 0) - && (strcmp (fields[1], "rate:") == 0)) - valptr = ¤t; - else if ((strcmp (fields[0], "remaining") == 0) - && (strcmp (fields[1], "capacity:") == 0)) - valptr = &charge; - else if ((strcmp (fields[0], "present") == 0) - && (strcmp (fields[1], "voltage:") == 0)) - valptr = &voltage; - else - valptr = NULL; - - if ((strcmp (fields[0], "charging") == 0) - && (strcmp (fields[1], "state:") == 0)) - { - if (strcmp (fields[2], "charging") == 0) - charging = 1; - else - charging = 0; - } - - if (valptr != NULL) - { - char *endptr; - - endptr = NULL; - errno = 0; - - *valptr = strtod (fields[2], &endptr) / 1000.0; - - if ((fields[2] == endptr) || (errno != 0)) - *valptr = INVALID_VALUE; - } - } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ - - fclose (fh); - - if ((current != INVALID_VALUE) && (charging == 0)) - current *= -1; - - if (charge != INVALID_VALUE) - battery_submit ("0", "charge", charge); - if (current != INVALID_VALUE) - battery_submit ("0", "current", current); - if (voltage != INVALID_VALUE) - battery_submit ("0", "voltage", voltage); - } - - closedir (dh); - } #endif /* KERNEL_LINUX */ return (0); } -#endif /* BATTERY_HAVE_READ */ -void module_register (modreg_e load) +void module_register (void) { - if (load & MR_DATASETS) - { - plugin_register_data_set (&charge_ds); - plugin_register_data_set (¤t_ds); - plugin_register_data_set (&voltage_ds); - } - -#if BATTERY_HAVE_READ - if (load & MR_READ) - { - plugin_register_init ("battery", battery_init); - plugin_register_read ("battery", battery_read); - } -#endif /* BATTERY_HAVE_READ */ + plugin_register_init ("battery", battery_init); + plugin_register_read ("battery", battery_read); } /* void module_register */