From 334447308fed2eb0a44e67adb95009bb15aa7efe Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sun, 14 Dec 2008 17:53:31 +0100 Subject: [PATCH] enable DEV_NAME to handle symlinks Using a macro is not possible anymore, so have a function dev_name() do the job. Functionality is the same as the old DEV_NAME, unless the specified path is a symlink in which case it's being dereferenced first. To save callers from having to free the returned string, a static local buffer is used (effectively rendering the function non-reentrant). --- src/conky.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/conky.c b/src/conky.c index e6591970..dbd58160 100644 --- a/src/conky.c +++ b/src/conky.c @@ -1951,9 +1951,25 @@ void scan_mixer_bar(const char *arg, int *a, int *w, int *h) } } -/* strip a leading /dev/ if any */ -#define DEV_NAME(x) x != NULL && strlen(x) > 5 && strncmp(x, "/dev/", 5) == 0 \ - ? x + 5 : x +/* strip a leading /dev/ if any, following symlinks first + * + * BEWARE: this function returns a pointer to static content + * which gets overwritten in consecutive calls. I.e.: + * this function is NOT reentrant. + */ +const char *dev_name(const char *path) +{ + static char buf[255]; /* should be enough for pathnames */ + ssize_t buflen; + +#define DEV_NAME(x) \ + x != NULL && strlen(x) > 5 && strncmp(x, "/dev/", 5) == 0 ? x + 5 : x + if ((buflen = readlink(path, buf, 254)) == -1) + return DEV_NAME(path); + buf[buflen] = '\0'; + return DEV_NAME(buf); +#undef DEV_NAME +} /* construct_text_object() creates a new text_object */ static struct text_object *construct_text_object(const char *s, @@ -2128,7 +2144,7 @@ static struct text_object *construct_text_object(const char *s, #if defined(__linux__) END OBJ(disk_protect, 0) if (arg) - obj->data.s = strndup(DEV_NAME(arg), text_buffer_size); + obj->data.s = strndup(dev_name(arg), text_buffer_size); else CRIT_ERR("disk_protect needs an argument"); END OBJ(i8k_version, INFO_I8K) @@ -2178,7 +2194,7 @@ static struct text_object *construct_text_object(const char *s, CRIT_ERR("get_ioscheduler needs an argument (e.g. hda)"); obj->data.s = 0; } else - obj->data.s = strndup(DEV_NAME(arg), text_buffer_size); + obj->data.s = strndup(dev_name(arg), text_buffer_size); END OBJ(laptop_mode, 0) END OBJ(pb_battery, 0) if (arg && strcmp(arg, "status") == EQUAL) { @@ -2285,24 +2301,24 @@ static struct text_object *construct_text_object(const char *s, #if defined(__linux__) END OBJ(diskio, INFO_DISKIO) if (arg) { - obj->data.diskio = prepare_diskio_stat(DEV_NAME(arg)); + obj->data.diskio = prepare_diskio_stat(dev_name(arg)); } else { obj->data.diskio = NULL; } END OBJ(diskio_read, INFO_DISKIO) if (arg) { - obj->data.diskio = prepare_diskio_stat(DEV_NAME(arg)); + obj->data.diskio = prepare_diskio_stat(dev_name(arg)); } else { obj->data.diskio = NULL; } END OBJ(diskio_write, INFO_DISKIO) if (arg) { - obj->data.diskio = prepare_diskio_stat(DEV_NAME(arg)); + obj->data.diskio = prepare_diskio_stat(dev_name(arg)); } else { obj->data.diskio = NULL; } END OBJ(diskiograph, INFO_DISKIO) - char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d, + char *buf = scan_graph(dev_name(arg), &obj->a, &obj->b, &obj->c, &obj->d, &obj->e, &obj->showaslog); if (buf) { @@ -2312,7 +2328,7 @@ static struct text_object *construct_text_object(const char *s, obj->data.diskio = NULL; } END OBJ(diskiograph_read, INFO_DISKIO) - char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d, + char *buf = scan_graph(dev_name(arg), &obj->a, &obj->b, &obj->c, &obj->d, &obj->e, &obj->showaslog); if (buf) { @@ -2322,7 +2338,7 @@ static struct text_object *construct_text_object(const char *s, obj->data.diskio = NULL; } END OBJ(diskiograph_write, INFO_DISKIO) - char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d, + char *buf = scan_graph(dev_name(arg), &obj->a, &obj->b, &obj->c, &obj->d, &obj->e, &obj->showaslog); if (buf) {