From e275b0524247912573a738ab41e0aa5e6e3260f5 Mon Sep 17 00:00:00 2001 From: Nikos Ntarmos Date: Sun, 15 Mar 2009 19:11:49 -0600 Subject: [PATCH] Disk i/o support on FreeBSD patch. Patch sf.net id #2657227 (thanks Nikos). --- ChangeLog | 1 + src/conky.c | 2 -- src/freebsd.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cf5c45e..a55aa72c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 2009-03-15 * Added extra newline patch, sf.net id #2638601 (thanks Ali) + * Disk i/o support on FreeBSD patch, sf.net id #2657227 (thanks Nikos) 2009-03-07 * Added alias patch ( sf.net id #2663691 ) changed it to prevent it from diff --git a/src/conky.c b/src/conky.c index 963c1985..eb0a1d00 100644 --- a/src/conky.c +++ b/src/conky.c @@ -1321,7 +1321,6 @@ static struct text_object *construct_text_object(const char *s, obj->data.loadavg[0] = (r >= 1) ? (unsigned char) a : 0; free(buf); } -#if defined(__linux__) END OBJ(diskio, INFO_DISKIO) obj->data.diskio = prepare_diskio_stat(dev_name(arg)); END OBJ(diskio_read, INFO_DISKIO) @@ -1349,7 +1348,6 @@ static struct text_object *construct_text_object(const char *s, obj->data.diskio = prepare_diskio_stat(dev_name(buf)); if (buf) free(buf); -#endif END OBJ(color, 0) #ifdef X11 if (output_methods & TO_X) { diff --git a/src/freebsd.c b/src/freebsd.c index bf3a59a2..d5859d73 100644 --- a/src/freebsd.c +++ b/src/freebsd.c @@ -64,6 +64,8 @@ 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 int getsysctl(char *name, void *ptr, size_t len) { @@ -717,6 +719,66 @@ void update_diskio() 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 *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; + } + } + /* new dev */ + if (!new) { + ERR("too many diskio stats"); + return 0; + } + if (new->dev) { + free(new->dev); + new->dev = 0; + } + 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); + } else { + new->dev = strndup(s, text_buffer_size); + } + /* + * check that device actually exists + */ + snprintf(device, text_buffer_size, "/dev/%s", new->dev); + + if (stat(device, &sb)) { + 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; } /* While topless is obviously better, top is also not bad. */