From 50bac8400624db1ca8dc96e8ae5489c9275f1f4f Mon Sep 17 00:00:00 2001 From: Nikos Ntarmos Date: Sat, 28 Mar 2009 21:53:02 +0200 Subject: [PATCH] Bringing FreeBSD up to date with latest commits Several things were broken after the switch to 1.7-rc branches. This diff fixes all compilations issues and updates some functions that were left empty previously. Signed-off-by: Nikos Ntarmos --- src/freebsd.c | 286 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 154 insertions(+), 132 deletions(-) diff --git a/src/freebsd.c b/src/freebsd.c index a34a01e..aa97608 100644 --- a/src/freebsd.c +++ b/src/freebsd.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -48,8 +49,13 @@ #include #include +#include #include "conky.h" +#include "freebsd.h" +#include "logging.h" +#include "top.h" +#include "diskio.h" #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) #define KELVTOC(x) ((x - 2732) / 10.0) @@ -61,11 +67,16 @@ inline void proc_find_top(struct process **cpu, struct process **mem); -u_int64_t diskio_prev = 0; static short cpu_setup = 0; -static short diskio_setup = 0; -static struct diskio_stat diskio_stats_[MAX_DISKIO_STATS]; -struct diskio_stat *diskio_stats = diskio_stats_; +static struct diskio_stat stats = { + .next = NULL, + .current = 0, + .current_read = 0, + .current_write = 0, + .last = UINT_MAX, + .last_read = UINT_MAX, + .last_write = UINT_MAX, +}; static int getsysctl(char *name, void *ptr, size_t len) { @@ -75,7 +86,7 @@ static int getsysctl(char *name, void *ptr, size_t len) return -1; } - if (nlen != len) { + if (nlen != len && errno == ENOMEM) { return -1; } @@ -369,84 +380,107 @@ double get_acpi_temperature(int fd) return KELVTOC(temp); } -void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item) -{ - int battime, batcapacity, batstate, ac; - char battery_status[64]; - char battery_time[64]; - - if (GETSYSCTL("hw.acpi.battery.time", battime)) { +static void get_battery_stats(int *battime, int *batcapacity, int *batstate, int *ac) { + if (battime && GETSYSCTL("hw.acpi.battery.time", *battime)) { fprintf(stderr, "Cannot read sysctl \"hw.acpi.battery.time\"\n"); } - if (GETSYSCTL("hw.acpi.battery.life", batcapacity)) { + if (batcapacity && GETSYSCTL("hw.acpi.battery.life", *batcapacity)) { fprintf(stderr, "Cannot read sysctl \"hw.acpi.battery.life\"\n"); } - - if (GETSYSCTL("hw.acpi.battery.state", batstate)) { + if (batstate && GETSYSCTL("hw.acpi.battery.state", *batstate)) { fprintf(stderr, "Cannot read sysctl \"hw.acpi.battery.state\"\n"); } - - if (GETSYSCTL("hw.acpi.acline", ac)) { + if (ac && GETSYSCTL("hw.acpi.acline", *ac)) { fprintf(stderr, "Cannot read sysctl \"hw.acpi.acline\"\n"); } +} - if (batstate == 1) { - if (battime != -1) { - snprintf(battery_status, sizeof(battery_status) - 1, - "remaining %d%%", batcapacity); - snprintf(battery_time, sizeof(battery_time) - 1, "%d:%2.2d", - battime / 60, battime % 60); - /* snprintf(buf, n, "remaining %d%% (%d:%2.2d)", batcapacity, - battime / 60, battime % 60); */ - } else { - /* no time estimate available yet */ - snprintf(battery_status, sizeof(battery_status) - 1, - "remaining %d%%", batcapacity); - } - /* snprintf(buf, n, "remaining %d%%", batcapacity); */ - if (ac == 1) { - fprintf(stderr, "Discharging while on AC!\n"); - } - } else { - snprintf(battery_status, sizeof(battery_status) - 1, - batstate == 2 ? "charging (%d%%)" : "charged (%d%%)", batcapacity); - /* snprintf(buf, n, - batstate == 2 ? "charging (%d%%)" : "charged (%d%%)", - batcapacity); */ - if (batstate != 2 && batstate != 0) { - fprintf(stderr, "Unknown battery state %d!\n", batstate); - } - if (ac == 0) { - fprintf(stderr, "Charging while not on AC!\n"); - } - } +void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item) +{ + int battime, batcapacity, batstate, ac; + char battery_status[64]; + char battery_time[64]; + + get_battery_stats(&battime, &batcapacity, &batstate, &ac); + + if (batstate != 1 && batstate != 2 && batstate != 0 && batstate != 7) + fprintf(stderr, "Unknown battery state %d!\n", batstate); + else if (batstate != 1 && ac == 0) + fprintf(stderr, "Battery charging while not on AC!\n"); + else if (batstate == 1 && ac == 1) + fprintf(stderr, "Battery discharing while on AC!\n"); switch (item) { - case BATTERY_STATUS: - snprintf(buf, n, "%s", battery_status); - break; case BATTERY_TIME: - snprintf(buf, n, "%s", battery_time); + if (batstate == 1 && battime != -1) + snprintf(buf, n, "%d:%2.2d", battime / 60, battime % 60); break; - default: + case BATTERY_STATUS: + if (batstate == 1) // Discharging + snprintf(buf, n, "remaining %d%%", batcapacity); + else + snprintf(buf, n, batstate == 2 ? "charging (%d%%)" : + (batstate == 7 ? "absent/on AC" : "charged (%d%%)"), + batcapacity); break; + default: + fprintf(stderr, "Unknown requested battery stat %d\n", item); + } +} + +static int check_bat(const char *bat) +{ + int batnum, numbatts; + char *endptr; + if (GETSYSCTL("hw.acpi.battery.units", numbatts)) { + fprintf(stderr, "Cannot read sysctl \"hw.acpi.battery.units\"\n"); + return -1; + } + if (numbatts <= 0) { + fprintf(stderr, "No battery unit detected\n"); + return -1; + } + if (!bat || (batnum = strtol(bat, &endptr, 10)) < 0 || + bat == endptr || batnum > numbatts) { + fprintf(stderr, "Wrong battery unit requested\n", bat); + return -1; } + return batnum; } int get_battery_perct(const char *bat) { - /* not implemented */ - return 0; + union acpi_battery_ioctl_arg battio; + int batnum, numbatts, acpifd; + int designcap, lastfulcap, batperct; + + if ((battio.unit = batnum = check_bat(bat)) < 0) + return 0; + if ((acpifd = open("/dev/acpi", O_RDONLY)) < 0) { + fprintf(stderr, "Can't open ACPI device\n"); + return 0; + } + if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) == -1) { + fprintf(stderr, "Unable to get info for battery unit %d\n", batnum); + return 0; + } + close(acpifd); + designcap = battio.bif.dcap; + lastfulcap = battio.bif.lfcap; + batperct = (designcap > 0 && lastfulcap > 0) ? + (int) (((float) lastfulcap / designcap) * 100) : 0; + return batperct > 100 ? 100 : batperct; } int get_battery_perct_bar(const char *bar) { - /* not implemented */ - return 0; + int batperct = get_battery_perct(bar); + return (int)(batperct * 2.56 - 1); } int open_acpi_temperature(const char *name) { + /* Not applicable for FreeBSD. */ return 0; } @@ -629,21 +663,19 @@ cleanup: void update_diskio() { - int devs_count, num_selected, num_selections, i; + int devs_count, num_selected, num_selections; struct device_selection *dev_select = NULL; long select_generation; int dn; static struct statinfo statinfo_cur; - u_int64_t diskio_current = 0; - u_int64_t writes = 0; + struct diskio_stat *cur; bzero(&statinfo_cur, sizeof(statinfo_cur)); - statinfo_cur.dinfo = (struct devinfo *) malloc(sizeof(struct devinfo)); - bzero(statinfo_cur.dinfo, sizeof(struct devinfo)); + statinfo_cur.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)); + stats.current = stats.current_read = stats.current_write = 0; - if (devstat_getdevs(NULL, &statinfo_cur) < 0) { + if (devstat_getdevs(NULL, &statinfo_cur) < 0) return; - } devs_count = statinfo_cur.dinfo->numdevs; if (devstat_selectdevs(&dev_select, &num_selected, &num_selections, @@ -657,33 +689,30 @@ void update_diskio() di = dev_select[dn].position; dev = &statinfo_cur.dinfo->devices[di]; - diskio_current += dev->bytes[DEVSTAT_READ] + dev->bytes[DEVSTAT_WRITE]; - - for (i = 0; i < MAX_DISKIO_STATS; i++) { - if (diskio_stats[i].dev && strcmp(dev_select[dn].device_name, - diskio_stats[i].dev) == 0) { - diskio_stats[i].current = (dev->bytes[DEVSTAT_READ] + - dev->bytes[DEVSTAT_WRITE] - diskio_stats[i].last) / 1024; - diskio_stats[i].current_read = (dev->bytes[DEVSTAT_READ] - - diskio_stats[i].last_read) / 1024; - diskio_stats[i].current_write = (dev->bytes[DEVSTAT_WRITE] - - diskio_stats[i].last_write) / 1024; - if (dev->bytes[DEVSTAT_READ] + dev->bytes[DEVSTAT_WRITE] - < diskio_stats[i].last) { - diskio_stats[i].current = 0; + for (cur = stats.next; cur; cur = cur->next) { + if (cur->dev && !strcmp(dev_select[dn].device_name, cur->dev)) { + cur->current = (dev->bytes[DEVSTAT_READ] + + dev->bytes[DEVSTAT_WRITE] - cur->last) / 1024; + cur->current_read = (dev->bytes[DEVSTAT_READ] - + cur->last_read) / 1024; + cur->current_write = (dev->bytes[DEVSTAT_WRITE] - + cur->last_write) / 1024; + if (dev->bytes[DEVSTAT_READ] + dev->bytes[DEVSTAT_WRITE] < + cur->last) { + cur->current = 0; } - if (dev->bytes[DEVSTAT_READ] < diskio_stats[i].last_read) { - diskio_stats[i].current_read = 0; - diskio_stats[i].current = diskio_stats[i].current_write; + if (dev->bytes[DEVSTAT_READ] < cur->last_read) { + cur->current_read = 0; + cur->current = cur->current_write; } - if (dev->bytes[DEVSTAT_WRITE] < diskio_stats[i].last_write) { - diskio_stats[i].current_write = 0; - diskio_stats[i].current = diskio_stats[i].current_read; + if (dev->bytes[DEVSTAT_WRITE] < cur->last_write) { + cur->current_write = 0; + cur->current = cur->current_read; } - diskio_stats[i].last = dev->bytes[DEVSTAT_READ] + + cur->last = dev->bytes[DEVSTAT_READ] + dev->bytes[DEVSTAT_WRITE]; - diskio_stats[i].last_read = dev->bytes[DEVSTAT_READ]; - diskio_stats[i].last_write = dev->bytes[DEVSTAT_WRITE]; + cur->last_read = dev->bytes[DEVSTAT_READ]; + cur->last_write = dev->bytes[DEVSTAT_WRITE]; } } } @@ -691,29 +720,16 @@ void update_diskio() free(dev_select); } - /* Since we return (diskio_total_current - diskio_total_old), - * the first frame will be way too high - * (it will be equal to diskio_total_current, i.e. all disk I/O since boot). - * That's why it is better to return 0 first time; */ - if (diskio_setup == 0) { - diskio_setup = 1; - info.diskio_value = 0; - } else { - info.diskio_value = (unsigned int) ((diskio_current - diskio_prev) / 1024); - } - diskio_prev = diskio_current; - free(statinfo_cur.dinfo); } void clear_diskio_stats() { - unsigned i; - for(i = 0; i < MAX_DISKIO_STATS; i++) { - if (diskio_stats[i].dev) { - free(diskio_stats[i].dev); - diskio_stats[i].dev = 0; - } + struct diskio_stat *cur; + while (stats.next) { + cur = stats.next; + stats.next = stats.next->next; + free(cur); } } @@ -721,36 +737,33 @@ struct diskio_stat *prepare_diskio_stat(const char *s) { struct diskio_stat *new = 0; struct stat sb; - unsigned i; - FILE *fp; int found = 0; char device[text_buffer_size], fbuf[text_buffer_size]; static int rep = 0; /* lookup existing or get new */ - for (i = 0; i < MAX_DISKIO_STATS; i++) { - if (diskio_stats[i].dev) { - if (strcmp(diskio_stats[i].dev, s) == 0) { - return &diskio_stats[i]; - } - } else { - new = &diskio_stats[i]; - break; - } + struct diskio_stat *cur = &stats; + + if (!s) + return cur; + + while (cur->next) { + cur = cur->next; + if (!strcmp(cur->dev, s)) + return cur; } + /* new dev */ - if (!new) { - ERR("too many diskio stats"); - return 0; - } - if (new->dev) { - free(new->dev); - new->dev = 0; + if (!(cur->next = calloc(1, sizeof(struct diskio_stat)))) { + ERR("out of memory allocating new disk stats struct"); + return NULL; } + cur = cur->next; + cur->last = cur->last_read = cur->last_write = UINT_MAX; if (strncmp(s, "/dev/", 5) == 0) { // supplied a /dev/device arg, so cut off the /dev part - new->dev = strndup(s + 5, text_buffer_size); + cur->dev = strndup(s + 5, text_buffer_size); } else { - new->dev = strndup(s, text_buffer_size); + cur->dev = strndup(s, text_buffer_size); } /* * check that device actually exists @@ -761,13 +774,7 @@ struct diskio_stat *prepare_diskio_stat(const char *s) ERR("diskio device '%s' does not exist", s); return 0; } - new->current = 0; - new->current_read = 0; - new ->current_write = 0; - new->last = UINT_MAX; - new->last_read = UINT_MAX; - new->last_write = UINT_MAX; - return new; + return cur; } /* While topless is obviously better, top is also not bad. */ @@ -1009,9 +1016,24 @@ char *get_apm_battery_time() #endif +void get_battery_short_status(char *buffer, unsigned int n, const char *bat) +{ + get_battery_stuff(buffer, n, bat, BATTERY_STATUS); + if (0 == strncmp("charging", buffer, 8)) { + buffer[0] = 'C'; + memmove(buffer + 1, buffer + 8, n - 8); + } else if (0 == strncmp("discharging", buffer, 11)) { + buffer[0] = 'D'; + memmove(buffer + 1, buffer + 11, n - 11); + } else if (0 == strncmp("absent/on AC", buffer, 12)) { + buffer[0] = 'A'; + memmove(buffer + 1, buffer + 12, n - 12); + } +} + void update_entropy(void) { - /* mirrorbox: can you do anything equivalent in freebsd? -drphibes. */ + /* Not applicable for FreeBSD as it uses the yarrow prng. */ } /* empty stub so conky links */ -- 1.7.9.5