From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, stefanha@redhat.com, qemu-devel@nongnu.org
Subject: [PULL 49/57] qemu-img: resize: do not always eat last argument
Date: Tue, 15 Jul 2025 21:03:22 +0200 [thread overview]
Message-ID: <20250715190330.378764-50-kwolf@redhat.com> (raw)
In-Reply-To: <20250715190330.378764-1-kwolf@redhat.com>
From: Michael Tokarev <mjt@tls.msk.ru>
'qemu-img resize --help' does not work, since it wants more
arguments. Also -size is only recognized as a very last
argument, but it is common for tools to handle other options
after positional arguments too.
Tell getopt_long() to return non-options together with options,
and process filename and size in the loop, and check if there's
an argument right after filename which looks like -N (number),
and treat it as size (decrement). This way we can handle --help,
and we can also have options after filename and size, and `--'
will be handled fine too.
The only case which is not handled right is when there's an option
between filename and size, and size is given as decrement, - in
this case -size will be treated as option, not as size.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-ID: <20250531171609.197078-20-mjt@tls.msk.ru>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qemu-img.c | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index a02d271af1..36ef998a34 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4302,7 +4302,7 @@ static int img_resize(const img_cmd_t *ccmd, int argc, char **argv)
{
Error *err = NULL;
int c, ret, relative;
- const char *filename, *fmt, *size;
+ const char *filename = NULL, *fmt = NULL, *size = NULL;
int64_t n, total_size, current_size;
bool quiet = false;
BlockBackend *blk = NULL;
@@ -4325,17 +4325,7 @@ static int img_resize(const img_cmd_t *ccmd, int argc, char **argv)
bool image_opts = false;
bool shrink = false;
- /* Remove size from argv manually so that negative numbers are not treated
- * as options by getopt. */
- if (argc < 3) {
- error_exit(argv[0], "Not enough arguments");
- return 1;
- }
-
- size = argv[--argc];
-
/* Parse getopt arguments */
- fmt = NULL;
for(;;) {
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
@@ -4345,7 +4335,7 @@ static int img_resize(const img_cmd_t *ccmd, int argc, char **argv)
{"shrink", no_argument, 0, OPTION_SHRINK},
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, ":f:hq",
+ c = getopt_long(argc, argv, "-:f:hq",
long_options, NULL);
if (c == -1) {
break;
@@ -4383,12 +4373,35 @@ static int img_resize(const img_cmd_t *ccmd, int argc, char **argv)
case OPTION_SHRINK:
shrink = true;
break;
+ case 1: /* a non-optional argument */
+ if (!filename) {
+ filename = optarg;
+ /* see if we have -size (number) next to filename */
+ if (optind < argc) {
+ size = argv[optind];
+ if (size[0] == '-' && size[1] >= '0' && size[1] <= '9') {
+ ++optind;
+ } else {
+ size = NULL;
+ }
+ }
+ } else if (!size) {
+ size = optarg;
+ } else {
+ error_exit(argv[0], "Extra argument(s) in command line");
+ }
+ break;
}
}
- if (optind != argc - 1) {
+ if (!filename && optind < argc) {
+ filename = argv[optind++];
+ }
+ if (!size && optind < argc) {
+ size = argv[optind++];
+ }
+ if (!filename || !size || optind < argc) {
error_exit(argv[0], "Expecting image file name and size");
}
- filename = argv[optind++];
/* Choose grow, shrink, or absolute resize mode */
switch (size[0]) {
--
2.50.1
next prev parent reply other threads:[~2025-07-15 19:49 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-15 19:02 [PULL 00/57] Block layer patches Kevin Wolf
2025-07-15 19:02 ` [PULL 01/57] block: never use atomics to access bs->quiesce_counter Kevin Wolf
2025-07-15 19:02 ` [PULL 02/57] block: add bdrv_graph_wrlock_drained() convenience wrapper Kevin Wolf
2025-07-15 19:02 ` [PULL 03/57] block/mirror: switch to bdrv_set_backing_hd_drained() variant Kevin Wolf
2025-07-15 19:02 ` [PULL 04/57] block/commit: " Kevin Wolf
2025-07-15 19:02 ` [PULL 05/57] block: call bdrv_set_backing_hd() while unlocked in bdrv_open_backing_file() Kevin Wolf
2025-07-15 19:02 ` [PULL 06/57] block: mark bdrv_set_backing_hd() as GRAPH_UNLOCKED Kevin Wolf
2025-07-15 19:02 ` [PULL 07/57] blockdev: avoid locking and draining multiple times in external_snapshot_abort() Kevin Wolf
2025-07-15 19:02 ` [PULL 08/57] block: drop wrapper for bdrv_set_backing_hd_drained() Kevin Wolf
2025-07-15 19:02 ` [PULL 09/57] block-backend: mark blk_drain_all() as GRAPH_UNLOCKED Kevin Wolf
2025-07-15 19:02 ` [PULL 10/57] block/snapshot: mark bdrv_all_delete_snapshot() " Kevin Wolf
2025-07-15 19:02 ` [PULL 11/57] block/stream: mark stream_prepare() " Kevin Wolf
2025-07-15 19:02 ` [PULL 12/57] block: mark bdrv_reopen_queue() and bdrv_reopen_multiple() " Kevin Wolf
2025-07-15 19:02 ` [PULL 13/57] block: mark bdrv_inactivate() as GRAPH_RDLOCK and move drain to callers Kevin Wolf
2025-07-15 19:02 ` [PULL 14/57] block: mark bdrv_inactivate_all() as GRAPH_UNLOCKED Kevin Wolf
2025-07-15 19:02 ` [PULL 15/57] block: mark blk_remove_bs() " Kevin Wolf
2025-07-15 19:02 ` [PULL 16/57] block: mark blk_drain() " Kevin Wolf
2025-07-15 19:02 ` [PULL 17/57] block-backend: mark blk_io_limits_disable() " Kevin Wolf
2025-07-15 19:02 ` [PULL 18/57] block/commit: mark commit_abort() " Kevin Wolf
2025-07-15 19:02 ` [PULL 19/57] block: Allow bdrv_new() with and without graph lock Kevin Wolf
2025-07-15 19:02 ` [PULL 20/57] block: mark bdrv_replace_child_bs() as GRAPH_UNLOCKED Kevin Wolf
2025-07-15 19:02 ` [PULL 21/57] block: mark bdrv_insert_node() " Kevin Wolf
2025-07-15 19:02 ` [PULL 22/57] block: mark bdrv_drop_intermediate() " Kevin Wolf
2025-07-15 19:02 ` [PULL 23/57] block: mark bdrv_close_all() " Kevin Wolf
2025-07-15 19:02 ` [PULL 24/57] block: mark bdrv_close() " Kevin Wolf
2025-07-15 19:02 ` [PULL 25/57] block: mark bdrv_open_child_common() and its callers GRAPH_UNLOCKED Kevin Wolf
2025-07-15 19:02 ` [PULL 26/57] blockjob: mark block_job_remove_all_bdrv() as GRAPH_UNLOCKED Kevin Wolf
2025-07-15 19:03 ` [PULL 27/57] block/qapi: include child references in block device info Kevin Wolf
2025-07-15 19:03 ` [PULL 28/57] block/qapi: make @node-name in @BlockDeviceInfo non-optional Kevin Wolf
2025-07-15 19:03 ` [PULL 29/57] file-posix: Fix aio=threads performance regression after enablign FUA Kevin Wolf
2025-07-15 19:03 ` [PULL 30/57] iotests: add test for changing the 'drive' property via 'qom-set' Kevin Wolf
2025-07-15 19:03 ` [PULL 31/57] qemu-img: measure: convert img_size to signed, simplify handling Kevin Wolf
2025-07-15 19:03 ` [PULL 32/57] qemu-img: create: " Kevin Wolf
2025-07-15 19:03 ` [PULL 33/57] qemu-img: global option processing and error printing Kevin Wolf
2025-07-15 19:03 ` [PULL 34/57] qemu-img: pass current cmd info into command handlers Kevin Wolf
2025-07-15 19:03 ` [PULL 35/57] qemu-img: create: refresh options/--help (short option change) Kevin Wolf
2025-07-15 19:03 ` [PULL 36/57] qemu-img: factor out parse_output_format() and use it in the code Kevin Wolf
2025-07-15 19:03 ` [PULL 37/57] qemu-img: check: refresh options/--help Kevin Wolf
2025-07-15 19:03 ` [PULL 38/57] qemu-img: simplify --repair error message Kevin Wolf
2025-07-15 19:03 ` [PULL 39/57] qemu-img: commit: refresh options/--help Kevin Wolf
2025-07-15 19:03 ` [PULL 40/57] qemu-img: compare: use helper function for --object Kevin Wolf
2025-07-15 19:03 ` [PULL 41/57] qemu-img: compare: refresh options/--help Kevin Wolf
2025-07-15 19:03 ` [PULL 42/57] qemu-img: convert: refresh options/--help (short option change) Kevin Wolf
2025-07-15 19:03 ` [PULL 43/57] qemu-img: info: refresh options/--help Kevin Wolf
2025-07-15 19:03 ` [PULL 44/57] qemu-img: map: " Kevin Wolf
2025-07-15 19:03 ` [PULL 45/57] qemu-img: snapshot: allow specifying -f fmt Kevin Wolf
2025-07-15 19:03 ` [PULL 46/57] qemu-img: snapshot: make -l (list) the default, simplify option handling Kevin Wolf
2025-07-15 19:03 ` [PULL 47/57] qemu-img: snapshot: refresh options/--help Kevin Wolf
2025-07-15 19:03 ` [PULL 48/57] qemu-img: rebase: refresh options/--help (short option change) Kevin Wolf
2025-07-15 19:03 ` Kevin Wolf [this message]
2025-07-15 19:03 ` [PULL 50/57] qemu-img: resize: refresh options/--help Kevin Wolf
2025-07-15 19:03 ` [PULL 51/57] qemu-img: amend: " Kevin Wolf
2025-07-15 19:03 ` [PULL 52/57] qemu-img: bench: " Kevin Wolf
2025-07-15 19:03 ` [PULL 53/57] qemu-img: bitmap: " Kevin Wolf
2025-07-15 19:03 ` [PULL 54/57] qemu-img: dd: " Kevin Wolf
2025-07-15 19:03 ` [PULL 55/57] qemu-img: measure: " Kevin Wolf
2025-07-15 19:03 ` [PULL 56/57] qemu-img: implement short --help, remove global help() function Kevin Wolf
2025-07-15 19:03 ` [PULL 57/57] qemu-img: extend cvtnum() and use it in more places Kevin Wolf
2025-07-16 12:41 ` [PULL 00/57] Block layer patches Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250715190330.378764-50-kwolf@redhat.com \
--to=kwolf@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).