From b5bc289c5029181ccd09aff990c9c526e2cc2847 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 28 Jul 2020 14:56:02 -0400 Subject: [PATCH] iio_attr: accept negative numbers as data to write to getopt doesn't understand the difference between the '-' before an option and the '-' before a negative number. It can not - they are both the same, and in some applications option zero (-0) might be valid. in iio_attr this causes problems when we try to write negative numbers root@analog:~# iio_attr -o -c adrv9002-phy voltage0 hardwaregain -10 iio_attr: invalid option -- '1' Since the only time we do this in in iio_attr, handle the last option differently (if the last option is a negative number). This does mean we still don't pass -foo to an attribute to be written, since iio_attr thinks that is an unknown "-f" option. ./tests/iio_attr -v -a usb -o -c ad9361-phy voltage0 hardwaregain -foo Using auto-detected IIO context at URI "usb:3.39.5" ./tests/iio_attr: invalid option -- 'f' but this does fix the reported bug #573 ./tests/iio_attr -v -a usb -o -c ad9361-phy voltage0 hardwaregain -1 Using auto-detected IIO context at URI "usb:3.39.5" dev 'ad9361-phy', channel 'voltage0' (output), attr 'hardwaregain', value '-10.000000 dB' wrote 3 bytes to hardwaregain dev 'ad9361-phy', channel 'voltage0' (output), attr 'hardwaregain', value '-1.000000 dB' Signed-off-by: Robin Getz --- tests/iio_attr.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/iio_attr.c b/tests/iio_attr.c index bf0396010..bc3b1de69 100644 --- a/tests/iio_attr.c +++ b/tests/iio_attr.c @@ -353,7 +353,7 @@ int main(int argc, char **argv) { char **argw; struct iio_context *ctx; - int c; + int c, argd = argc; int device_index = 0, channel_index = 0, attr_index = 0; const char *gen_file = NULL; bool search_device = false, ignore_case = false, @@ -371,13 +371,24 @@ int main(int argc, char **argv) argw = dup_argv(MY_NAME, argc, argv); - ctx = handle_common_opts(MY_NAME, argc, argw, MY_OPTS, options, options_descriptions); + /* + * getopt_long() thinks negative numbers are options, -1 is option '1' + * The only time we should see a negative number is the last argument during a write, + * so if there is one, we skip that argument during getopt processing + * look for "-" followed by a number. + */ + if (strnlen(argv[argc - 1], 2) >= 2 && argv[argc - 1][0] == '-' && + (argv[argc - 1][1] >= '0' && argv[argc - 1][1] <= '9')) { + argd--; + } + + ctx = handle_common_opts(MY_NAME, argd, argw, MY_OPTS, options, options_descriptions); opts = add_common_options(options); if (!opts) { fprintf(stderr, "Failed to add common options\n"); return EXIT_FAILURE; } - while ((c = getopt_long(argc, argw, "+" COMMON_OPTIONS MY_OPTS, /* Flawfinder: ignore */ + while ((c = getopt_long(argd, argw, "+" COMMON_OPTIONS MY_OPTS, /* Flawfinder: ignore */ opts, NULL)) != -1) { switch (c) { /* All these are handled in the common */