Skip to content

Commit

Permalink
iio_info: Fix getopt() handling
Browse files Browse the repository at this point in the history
iio_info currently assumes that the argument for an option that is parsed
by getopt_long() is in the argv[] following the option and then the
combination of option and argument always consumes two argv[] entries.

This is not necessarily true though. getopt_long() accepts option and
argument in the same argv[] entry. For short options the argument can
directly follow the option character and for long options the argument can
follow in the same argv[] entry separated by a '=' character.

E.g. both -u ip:192.168.1.1 and -uip:192.168.1.1 as well as --uri
192.168.1.1 and --uri=192.168.1.1 are equivalent and all valid.

As a result of this iio_info will show undefined behavior when option and
argument are passed in the same argv[] entry (E.g. crash with a
segmentation fault).

To address this properly use the optarg and optind variables that are
provided by the getopt() interface. optarg points to the start of the
argument for the current option and optind will point to the first non
option argv[] entry after all options have been scanned.

Signed-off-by: Lars-Peter Clausen <[email protected]>
  • Loading branch information
larsclausen authored and commodo committed Feb 28, 2018
1 parent 19d642c commit 52a5f07
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions tests/iio_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,10 @@ static int dev_is_buffer_capable(const struct iio_device *dev)
int main(int argc, char **argv)
{
struct iio_context *ctx;
int c, option_index = 0, arg_index = 0, xml_index = 0, ip_index = 0,
uri_index = 0;
int c, option_index = 0;
const char *arg_uri = NULL;
const char *arg_ip = NULL;
const char *arg_xml = NULL;
enum backend backend = LOCAL;
bool do_scan = false, detect_context = false;
unsigned int i, major, minor;
Expand All @@ -192,20 +194,17 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
backend = NETWORK;
arg_index += 2;
ip_index = arg_index;
arg_ip = optarg;
break;
case 'x':
if (backend != LOCAL) {
fprintf(stderr, "-x, -n and -u are mutually exclusive\n");
return EXIT_FAILURE;
}
backend = XML;
arg_index += 2;
xml_index = arg_index;
arg_xml = optarg;
break;
case 's':
arg_index += 1;
do_scan = true;
break;
case 'u':
Expand All @@ -214,19 +213,17 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
backend = AUTO;
arg_index += 2;
uri_index = arg_index;
arg_uri = optarg;
break;
case 'a':
arg_index += 1;
detect_context = true;
break;
case '?':
return EXIT_FAILURE;
}
}

if (arg_index >= argc) {
if (optind != argc) {
fprintf(stderr, "Incorrect number of arguments.\n\n");
usage();
return EXIT_FAILURE;
Expand All @@ -248,11 +245,11 @@ int main(int argc, char **argv)
if (detect_context)
ctx = autodetect_context();
else if (backend == XML)
ctx = iio_create_xml_context(argv[xml_index]);
ctx = iio_create_xml_context(arg_xml);
else if (backend == NETWORK)
ctx = iio_create_network_context(argv[ip_index]);
ctx = iio_create_network_context(arg_ip);
else if (backend == AUTO)
ctx = iio_create_context_from_uri(argv[uri_index]);
ctx = iio_create_context_from_uri(arg_uri);
else
ctx = iio_create_default_context();

Expand Down

0 comments on commit 52a5f07

Please sign in to comment.