* [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind.
@ 2019-01-09 13:23 Richard W.M. Jones
2019-01-09 13:23 ` Richard W.M. Jones
2019-01-09 13:44 ` Daniel P. Berrangé
0 siblings, 2 replies; 6+ messages in thread
From: Richard W.M. Jones @ 2019-01-09 13:23 UTC (permalink / raw)
To: eblake; +Cc: kwolf, mreitz, qemu-block, qemu-devel
How about this one? Add a generic osdep function for reinitializing
optind, which does optreset on FreeBSD (but is identical on all other
OSes). Use it from qemu-io and qemu-img.
I have tested this on Linux, FreeBSD and OpenBSD.
checkpatch complains:
WARNING: Block comments use a leading /* on a separate line
#69: FILE: include/qemu/osdep.h:591:
+/**
WARNING: architecture specific defines should be avoided
#78: FILE: include/qemu/osdep.h:600:
+#ifdef __FreeBSD__
total: 0 errors, 2 warnings, 44 lines checked
but as far as I'm aware I've followed the correct formatting and
guidelines.
Rich.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind.
2019-01-09 13:23 [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind Richard W.M. Jones
@ 2019-01-09 13:23 ` Richard W.M. Jones
2019-01-09 13:44 ` Daniel P. Berrangé
1 sibling, 0 replies; 6+ messages in thread
From: Richard W.M. Jones @ 2019-01-09 13:23 UTC (permalink / raw)
To: eblake; +Cc: kwolf, mreitz, qemu-block, qemu-devel
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, while keeping it the same on other OSes.
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: Richard W.M. Jones <rjones@redhat.com>
---
include/qemu/osdep.h | 18 ++++++++++++++++++
qemu-img.c | 2 +-
qemu-io-cmds.c | 2 +-
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 3bf48bcdec..ea4ce4db9e 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -92,6 +92,7 @@ extern int daemon(int, int);
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <assert.h>
@@ -587,4 +588,21 @@ extern int qemu_icache_linesize_log;
extern int qemu_dcache_linesize;
extern int qemu_dcache_linesize_log;
+/**
+ * qemu_reset_optind:
+ *
+ * After using getopt or getopt_long, if you need to parse another set
+ * of options, then you must reset optind. Unfortunately the way to
+ * do this varies between implementations of getopt.
+ */
+static inline void qemu_reset_optind(void)
+{
+#ifdef __FreeBSD__
+ optind = 1;
+ optreset = 1;
+#else
+ optind = 0;
+#endif
+}
+
#endif
diff --git a/qemu-img.c b/qemu-img.c
index ad04f59565..25288c4d18 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4962,7 +4962,7 @@ int main(int argc, char **argv)
return 0;
}
argv += optind;
- optind = 0;
+ qemu_reset_optind();
if (!trace_init_backends()) {
exit(1);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 2c39124036..ee8f56e46a 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -114,7 +114,7 @@ static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
}
}
- optind = 0;
+ qemu_reset_optind();
return ct->cfunc(blk, argc, argv);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind.
2019-01-09 13:23 [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind Richard W.M. Jones
2019-01-09 13:23 ` Richard W.M. Jones
@ 2019-01-09 13:44 ` Daniel P. Berrangé
2019-01-09 14:14 ` Richard W.M. Jones
2019-01-09 14:53 ` Eric Blake
1 sibling, 2 replies; 6+ messages in thread
From: Daniel P. Berrangé @ 2019-01-09 13:44 UTC (permalink / raw)
To: Richard W.M. Jones; +Cc: eblake, kwolf, qemu-devel, qemu-block, mreitz
On Wed, Jan 09, 2019 at 01:23:01PM +0000, Richard W.M. Jones wrote:
> How about this one? Add a generic osdep function for reinitializing
> optind, which does optreset on FreeBSD (but is identical on all other
> OSes). Use it from qemu-io and qemu-img.
>
> I have tested this on Linux, FreeBSD and OpenBSD.
>
> checkpatch complains:
>
> WARNING: Block comments use a leading /* on a separate line
> #69: FILE: include/qemu/osdep.h:591:
> +/**
I think it just doesn't like your '/**' and wants '/*' instead.
> WARNING: architecture specific defines should be avoided
> #78: FILE: include/qemu/osdep.h:600:
> +#ifdef __FreeBSD__
Normally we'd suggest doing a configure test to for the platform
feature and then using a feature based ifdef test. In this case
though that would be difficult and/or overly complex.
This does make me wonder about the other *BSDs, OS-X and Mingw
though ? Should they all be using the #else codepath, or should
the other BSDs / OS-X use the __FreeBSD__ codepath.
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind.
2019-01-09 13:44 ` Daniel P. Berrangé
@ 2019-01-09 14:14 ` Richard W.M. Jones
2019-01-09 14:19 ` Daniel P. Berrangé
2019-01-09 14:53 ` Eric Blake
1 sibling, 1 reply; 6+ messages in thread
From: Richard W.M. Jones @ 2019-01-09 14:14 UTC (permalink / raw)
To: Daniel P. Berrangé; +Cc: eblake, kwolf, qemu-devel, qemu-block, mreitz
On Wed, Jan 09, 2019 at 01:44:48PM +0000, Daniel P. Berrangé wrote:
> On Wed, Jan 09, 2019 at 01:23:01PM +0000, Richard W.M. Jones wrote:
> > How about this one? Add a generic osdep function for reinitializing
> > optind, which does optreset on FreeBSD (but is identical on all other
> > OSes). Use it from qemu-io and qemu-img.
> >
> > I have tested this on Linux, FreeBSD and OpenBSD.
> >
> > checkpatch complains:
> >
> > WARNING: Block comments use a leading /* on a separate line
> > #69: FILE: include/qemu/osdep.h:591:
> > +/**
>
> I think it just doesn't like your '/**' and wants '/*' instead.
The existing comments in the same file are a mix of three styles.
I chose the style used closest to the new comment I was adding :-)
> > WARNING: architecture specific defines should be avoided
> > #78: FILE: include/qemu/osdep.h:600:
> > +#ifdef __FreeBSD__
>
> Normally we'd suggest doing a configure test to for the platform
> feature and then using a feature based ifdef test. In this case
> though that would be difficult and/or overly complex.
>
> This does make me wonder about the other *BSDs, OS-X and Mingw
OpenBSD is known fine with optind = 0. I can't test OS-X. I can test
mingw (on Linux) later.
Rich.
> though ? Should they all be using the #else codepath, or should
> the other BSDs / OS-X use the __FreeBSD__ codepath.
>
>
> Regards,
> Daniel
> --
> |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o- https://fstop138.berrange.com :|
> |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind.
2019-01-09 14:14 ` Richard W.M. Jones
@ 2019-01-09 14:19 ` Daniel P. Berrangé
0 siblings, 0 replies; 6+ messages in thread
From: Daniel P. Berrangé @ 2019-01-09 14:19 UTC (permalink / raw)
To: Richard W.M. Jones; +Cc: eblake, kwolf, qemu-devel, qemu-block, mreitz
On Wed, Jan 09, 2019 at 02:14:46PM +0000, Richard W.M. Jones wrote:
> On Wed, Jan 09, 2019 at 01:44:48PM +0000, Daniel P. Berrangé wrote:
> > On Wed, Jan 09, 2019 at 01:23:01PM +0000, Richard W.M. Jones wrote:
> > > How about this one? Add a generic osdep function for reinitializing
> > > optind, which does optreset on FreeBSD (but is identical on all other
> > > OSes). Use it from qemu-io and qemu-img.
> > >
> > > I have tested this on Linux, FreeBSD and OpenBSD.
> > >
> > > checkpatch complains:
> > >
> > > WARNING: Block comments use a leading /* on a separate line
> > > #69: FILE: include/qemu/osdep.h:591:
> > > +/**
> >
> > I think it just doesn't like your '/**' and wants '/*' instead.
>
> The existing comments in the same file are a mix of three styles.
> I chose the style used closest to the new comment I was adding :-)
Yeah, pre-existing code is a mess often not passing current style
rules. I wish we'd clean up existing code, but failing that, it can
be valid to ignore style warnings to be more consistent with existing
code.
>
> > > WARNING: architecture specific defines should be avoided
> > > #78: FILE: include/qemu/osdep.h:600:
> > > +#ifdef __FreeBSD__
> >
> > Normally we'd suggest doing a configure test to for the platform
> > feature and then using a feature based ifdef test. In this case
> > though that would be difficult and/or overly complex.
> >
> > This does make me wonder about the other *BSDs, OS-X and Mingw
>
> OpenBSD is known fine with optind = 0. I can't test OS-X. I can test
> mingw (on Linux) later.
>
>
> > though ? Should they all be using the #else codepath, or should
> > the other BSDs / OS-X use the __FreeBSD__ codepath.
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind.
2019-01-09 13:44 ` Daniel P. Berrangé
2019-01-09 14:14 ` Richard W.M. Jones
@ 2019-01-09 14:53 ` Eric Blake
1 sibling, 0 replies; 6+ messages in thread
From: Eric Blake @ 2019-01-09 14:53 UTC (permalink / raw)
To: Daniel P. Berrangé, Richard W.M. Jones
Cc: kwolf, qemu-devel, qemu-block, mreitz
[-- Attachment #1: Type: text/plain, Size: 1758 bytes --]
On 1/9/19 7:44 AM, Daniel P. Berrangé wrote:
> On Wed, Jan 09, 2019 at 01:23:01PM +0000, Richard W.M. Jones wrote:
>> How about this one? Add a generic osdep function for reinitializing
>> optind, which does optreset on FreeBSD (but is identical on all other
>> OSes). Use it from qemu-io and qemu-img.
>>
>> I have tested this on Linux, FreeBSD and OpenBSD.
>>
>
>> WARNING: architecture specific defines should be avoided
>> #78: FILE: include/qemu/osdep.h:600:
>> +#ifdef __FreeBSD__
>
> Normally we'd suggest doing a configure test to for the platform
> feature and then using a feature based ifdef test. In this case
> though that would be difficult and/or overly complex.
>
> This does make me wonder about the other *BSDs, OS-X and Mingw
> though ? Should they all be using the #else codepath, or should
> the other BSDs / OS-X use the __FreeBSD__ codepath.
Indeed, and I already suggested a configure-time probe on the v2
review. My preference, if we want to go with this helper function for a
hard reset, would be:
#if HAVE_OPTRESET
optind = 1;
optreset = 1;
#else
optind = 0;
#endif
where HAVE_OPTRESET is based on a configure-time probe.
Basically, any platform that HAS optreset will probably honor it; any
platform that lacks optreset is hopefully okay with the
POSIX-unspecified behavior of optind = 0.
But I do like the idea presented in this version of trying to isolate
the reset into a common helper function, so that if we have to make
later changes, we only have to touch the one function rather than all
callsites that reset getopt parsing.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-01-09 14:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-09 13:23 [Qemu-devel] [PATCH v3] qemu-io: Add generic function for reinitializing optind Richard W.M. Jones
2019-01-09 13:23 ` Richard W.M. Jones
2019-01-09 13:44 ` Daniel P. Berrangé
2019-01-09 14:14 ` Richard W.M. Jones
2019-01-09 14:19 ` Daniel P. Berrangé
2019-01-09 14:53 ` Eric Blake
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).