X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fbattery.c;h=33ba29231556bc7feec6a00b35276931224100d1;hb=9b626288aff81c68fe19210a58b4a32eeefde9d3;hp=345f606e8f3f834b5398fd15b3c91308607fb4a0;hpb=4cf9eb921f5994d4515613efa8739ce445cfd9a1;p=collectd.git diff --git a/src/battery.c b/src/battery.c index 345f606e..33ba2923 100644 --- a/src/battery.c +++ b/src/battery.c @@ -23,6 +23,8 @@ #include "common.h" #include "plugin.h" +#include "utils_complain.h" + #if HAVE_MACH_MACH_TYPES_H # include #endif @@ -61,6 +63,7 @@ #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) @@ -75,7 +78,7 @@ 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 < 0) || ((unsigned int)len >= sizeof (filename))) break; @@ -97,12 +100,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 @@ -312,6 +315,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 __attribute__((unused)) *dir, + const char *name, void __attribute__((unused)) *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 @@ -341,6 +438,8 @@ static int battery_read (void) /* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ #elif KERNEL_LINUX + static c_complain_t acpi_dir_complaint = C_COMPLAIN_INIT_STATIC; + FILE *fh; char buffer[1024]; char filename[256]; @@ -359,11 +458,11 @@ static int battery_read (void) double charge = INVALID_VALUE; double *valptr = NULL; - len = snprintf (filename, sizeof (filename), battery_pmu_file, i); + 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); + len = ssnprintf (batnum_str, sizeof (batnum_str), "%i", i); if ((len < 0) || ((unsigned int)len >= sizeof (batnum_str))) continue; @@ -411,111 +510,18 @@ static int battery_read (void) battery_submit ("0", "voltage", voltage); } - if (access ("/proc/acpi/battery", R_OK | X_OK) == 0) + if (0 == access (battery_acpi_dir, R_OK)) + walk_directory (battery_acpi_dir, battery_read_acpi, + /* user_data = */ NULL); + else { - 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 < 0) || ((unsigned int)len >= sizeof (filename))) - continue; - - if ((fh = fopen (filename, "r")) == NULL) - { - char errbuf[1024]; - ERROR ("Cannot open `%s': %s", filename, - sstrerror (errno, errbuf, - sizeof (errbuf))); - continue; - } - - /* - * [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); + char errbuf[1024]; + c_complain_once (LOG_WARNING, &acpi_dir_complaint, + "battery plugin: Failed to access `%s': %s", + battery_acpi_dir, + sstrerror (errno, errbuf, sizeof (errbuf))); } + #endif /* KERNEL_LINUX */ return (0);