From 91e5f979a672ece12aa230c55b5658c65d1c9b14 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Tue, 14 Feb 2023 16:05:54 +0000 Subject: [PATCH] channel: Support attribute names that start with the channel's label Support attribute names that start with the channel's label to avoid breaking compatibility with old kernels, which did not offer a 'label' attribute, and caused Libiio to sometimes misdetect the channel's extended name as being part of the attribute name. Signed-off-by: Paul Cercueil --- channel.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/channel.c b/channel.c index 2f92459c1..891c1deab 100644 --- a/channel.c +++ b/channel.c @@ -344,21 +344,53 @@ const char * iio_channel_get_attr(const struct iio_channel *chn, return chn->attrs[index].name; } -const char * iio_channel_find_attr(const struct iio_channel *chn, - const char *name) +static const char * +iio_channel_do_find_attr(const struct iio_channel *chn, const char *name) { unsigned int i; + for (i = 0; i < chn->nb_attrs; i++) { const char *attr = chn->attrs[i].name; if (!strcmp(attr, name)) return attr; } + + return NULL; +} + +const char * iio_channel_find_attr(const struct iio_channel *chn, + const char *name) +{ + const char *attr; + size_t len; + + attr = iio_channel_do_find_attr(chn, name); + if (attr) + return attr; + + /* Support attribute names that start with the channel's label to avoid + * breaking compatibility with old kernels, which did not offer a + * 'label' attribute, and caused Libiio to sometimes misdetect the + * channel's extended name as being part of the attribute name. */ + if (chn->name) { + len = strlen(chn->name); + + if (!strncmp(chn->name, name, len) && name[len] == '_') { + name += len + 1; + return iio_channel_do_find_attr(chn, name); + } + } + return NULL; } ssize_t iio_channel_attr_read(const struct iio_channel *chn, const char *attr, char *dst, size_t len) { + attr = iio_channel_find_attr(chn, attr); + if (!attr) + return -ENOENT; + if (chn->dev->ctx->ops->read_channel_attr) return chn->dev->ctx->ops->read_channel_attr(chn, attr, dst, len); @@ -369,6 +401,10 @@ ssize_t iio_channel_attr_read(const struct iio_channel *chn, ssize_t iio_channel_attr_write_raw(const struct iio_channel *chn, const char *attr, const void *src, size_t len) { + attr = iio_channel_find_attr(chn, attr); + if (!attr) + return -ENOENT; + if (chn->dev->ctx->ops->write_channel_attr) return chn->dev->ctx->ops->write_channel_attr(chn, attr, src, len);