dovecot-2.2: doveadm: Fixed reseting getopt() with glibc when pr...

dovecot at dovecot.org dovecot at dovecot.org
Mon Dec 7 09:30:07 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/ed41702f14c2
changeset: 19480:ed41702f14c2
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Dec 07 11:29:29 2015 +0200
description:
doveadm: Fixed reseting getopt() with glibc when processing multiple commands in a single process.
This means commands run with doveadm batch or multiple commands in a single
doveadm-server connection.

glibc's getopt() man page says that optind=1 should reset it for scanning a
new argument vector, but this doesn't actually seem to work. Setting
optind=0 does work though, so use it everywhere.

diffstat:

 src/doveadm/client-connection.c  |   4 ++--
 src/doveadm/doveadm-dsync.c      |   2 +-
 src/doveadm/doveadm-mail-batch.c |   2 +-
 src/doveadm/doveadm.c            |   7 +------
 src/lib/lib.c                    |  11 +++++++++++
 src/lib/lib.h                    |   2 ++
 6 files changed, 18 insertions(+), 10 deletions(-)

diffs (93 lines):

diff -r 1f1fc5eb4a8e -r ed41702f14c2 src/doveadm/client-connection.c
--- a/src/doveadm/client-connection.c	Mon Dec 07 11:21:59 2015 +0200
+++ b/src/doveadm/client-connection.c	Mon Dec 07 11:29:29 2015 +0200
@@ -46,7 +46,7 @@
 	const char *str = NULL;
 	unsigned int i;
 
-	optind = 1;
+	i_getopt_reset();
 	doveadm_exit_code = 0;
 	cmd->cmd(argc, argv);
 
@@ -93,7 +93,7 @@
 	if (doveadm_debug)
 		ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
 
-	optind = 1;
+	i_getopt_reset();
 	getopt_args = t_strconcat("AF:S:u:", ctx->getopt_args, NULL);
 	while ((c = getopt(argc, argv, getopt_args)) > 0) {
 		switch (c) {
diff -r 1f1fc5eb4a8e -r ed41702f14c2 src/doveadm/doveadm-dsync.c
--- a/src/doveadm/doveadm-dsync.c	Mon Dec 07 11:21:59 2015 +0200
+++ b/src/doveadm/doveadm-dsync.c	Mon Dec 07 11:29:29 2015 +0200
@@ -1335,5 +1335,5 @@
 	legacy_dsync = TRUE;
 	*_argc = dest;
 	*_argv = new_argv;
-	optind = 1;
+	i_getopt_reset();
 }
diff -r 1f1fc5eb4a8e -r ed41702f14c2 src/doveadm/doveadm-mail-batch.c
--- a/src/doveadm/doveadm-mail-batch.c	Mon Dec 07 11:21:59 2015 +0200
+++ b/src/doveadm/doveadm-mail-batch.c	Mon Dec 07 11:29:29 2015 +0200
@@ -68,7 +68,7 @@
 	subctx->full_args = argv + 1;
 	subctx->service_flags |= batchctx->ctx.service_flags;
 
-	optind = 1;
+	i_getopt_reset();
 	getopt_args = subctx->getopt_args != NULL ? subctx->getopt_args : "";
 	while ((c = getopt(argc, (void *)argv, getopt_args)) > 0) {
 		if (subctx->v.parse_arg == NULL ||
diff -r 1f1fc5eb4a8e -r ed41702f14c2 src/doveadm/doveadm.c
--- a/src/doveadm/doveadm.c	Mon Dec 07 11:21:59 2015 +0200
+++ b/src/doveadm/doveadm.c	Mon Dec 07 11:29:29 2015 +0200
@@ -328,12 +328,7 @@
 
 	argc -= optind;
 	argv += optind;
-#ifdef __GLIBC__
-	/* for subcommands allow -options anywhere in command line */
-	optind = 0;
-#else
-	optind = 1;
-#endif
+	i_getopt_reset();
 
 	master_service_init_finish(master_service);
 	if (!doveadm_debug) {
diff -r 1f1fc5eb4a8e -r ed41702f14c2 src/lib/lib.c
--- a/src/lib/lib.c	Mon Dec 07 11:21:59 2015 +0200
+++ b/src/lib/lib.c	Mon Dec 07 11:29:29 2015 +0200
@@ -56,6 +56,17 @@
 	}
 }
 
+void i_getopt_reset(void)
+{
+#ifdef __GLIBC__
+	/* a) for subcommands allow -options anywhere in command line
+	   b) this is actually required for the reset to work (glibc bug?) */
+	optind = 0;
+#else
+	optind = 1;
+#endif
+}
+
 void lib_atexit(lib_atexit_callback_t *callback)
 {
 	lib_atexit_priority(callback, 0);
diff -r 1f1fc5eb4a8e -r ed41702f14c2 src/lib/lib.h
--- a/src/lib/lib.h	Mon Dec 07 11:21:59 2015 +0200
+++ b/src/lib/lib.h	Mon Dec 07 11:29:29 2015 +0200
@@ -60,6 +60,8 @@
 int i_unlink_if_exists(const char *path, const char *source_fname,
 		       unsigned int source_linenum);
 #define i_unlink_if_exists(path) i_unlink_if_exists(path, __FILE__, __LINE__)
+/* Reset getopt() so it can be used for the next args. */
+void i_getopt_reset(void);
 
 /* Call the given callback at the beginning of lib_deinit(). The main
    difference to atexit() is that liblib's memory allocation and logging


More information about the dovecot-cvs mailing list