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