• R
    qemu-io: Add generic function for reinitializing optind. · d339d766
    Richard W.M. Jones 提交于
    On FreeBSD 11.2:
    
      $ nbdkit memory size=1M --run './qemu-io -f raw -c "aio_write 0 512" $nbd'
      Parsing error: non-numeric argument, or extraneous/unrecognized suffix -- aio_write
    
    After main option parsing, we reinitialize optind so we can parse each
    command.  However reinitializing optind to 0 does not work on FreeBSD.
    What happens when you do this is optind remains 0 after the option
    parsing loop, and the result is we try to parse argv[optind] ==
    argv[0] == "aio_write" as if it was the first parameter.
    
    The FreeBSD manual page says:
    
      In order to use getopt() to evaluate multiple sets of arguments, or to
      evaluate a single set of arguments multiple times, the variable optreset
      must be set to 1 before the second and each additional set of calls to
      getopt(), and the variable optind must be reinitialized.
    
    (From the rest of the man page it is clear that optind must be
    reinitialized to 1).
    
    The glibc man page says:
    
      A program that scans multiple argument vectors,  or  rescans  the  same
      vector  more than once, and wants to make use of GNU extensions such as
      '+' and '-' at  the  start  of  optstring,  or  changes  the  value  of
      POSIXLY_CORRECT  between scans, must reinitialize getopt() by resetting
      optind to 0, rather than the traditional value of 1.  (Resetting  to  0
      forces  the  invocation  of  an  internal  initialization  routine that
      rechecks POSIXLY_CORRECT and checks for GNU extensions in optstring.)
    
    This commit introduces an OS-portability function called
    qemu_reset_optind which provides a way of resetting optind that works
    on FreeBSD and platforms that use optreset, while keeping it the same
    as now on other platforms.
    
    Note that the qemu codebase sets optind in many other places, but in
    those other places it's setting a local variable and not using getopt.
    This change is only needed in places where we are using getopt and the
    associated global variable optind.
    Signed-off-by: NRichard W.M. Jones <rjones@redhat.com>
    Message-id: 20190118101114.11759-2-rjones@redhat.com
    Reviewed-by: NDaniel P. Berrangé <berrange@redhat.com>
    Reviewed-by: NEric Blake <eblake@redhat.com>
    Signed-off-by: NMax Reitz <mreitz@redhat.com>
    d339d766
configure 199.2 KB