krb5 commit [krb5-1.15]: Fix option parsing on Windows

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/8b8cad8b9ff92e2a2d344fc7c4d77277c9c09829
commit 8b8cad8b9ff92e2a2d344fc7c4d77277c9c09829
Author: Greg Hudson <[email protected]>
Date:   Tue May 15 21:52:08 2018 -0700

    Fix option parsing on Windows
    
    Commit 8f9ade8ec50cde1176411085294f85ecfb2820a4 (ticket 8391) moved
    the built-in getopt() and getopt_long() implementations from a static
    library in util/windows to util/support, where (on Windows) it is
    built into k5sprt32.dll or k5sprt64.dll.  The getopt() interface uses
    global variables opterr, optind, optopt, and optarg, each renamed via
    macro to have a k5_ prefix when we use the built-in implementation.
    Data objects exported from DLLs need special handling in Windows; they
    must be marked as DATA in the DLL .def file, and they must be declared
    with "__declspec(dllimport)" in calling code.  Without this handling,
    optind begins with a garbage value and getopt_long() returns -1
    immediately, so client programs always behave as if they have no
    arguments.
    
    Stop unnecessarily declaring optind and optarg in client programs.
    Declare the getopt() global variables with __declspec(dllimport) on
    Windows, except when compiling getopt.c itself.  When creating
    libkrb5support.exports on Windows (this file is later used by
    lib/Makefile.in to create k5sprt32.def), add a DATA tag to the data
    objects.
    
    (cherry picked from commit 63246cf3513a0e8bdfc734db985af14c8c5170c5)
    
    ticket: 8684
    version_fixed: 1.15.4

 src/clients/kdestroy/kdestroy.c |    3 ---
 src/clients/klist/klist.c       |    2 --
 src/clients/kswitch/kswitch.c   |    3 ---
 src/clients/kvno/kvno.c         |    3 ---
 src/include/k5-platform.h       |   14 ++++++++++----
 src/util/support/Makefile.in    |    4 +++-
 src/util/support/getopt.c       |    2 ++
 7 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/src/clients/kdestroy/kdestroy.c b/src/clients/kdestroy/kdestroy.c
index f955549..8c12771 100644
--- a/src/clients/kdestroy/kdestroy.c
+++ b/src/clients/kdestroy/kdestroy.c
@@ -37,9 +37,6 @@
 #define BELL_CHAR '\007'
 #endif
 
-extern int optind;
-extern char *optarg;
-
 #ifndef _WIN32
 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
 #else
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index ba19788..a5438df 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -48,8 +48,6 @@
 #include <netdb.h>
 #endif
 
-extern int optind;
-
 int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
 int show_etype = 0, show_addresses = 0, no_resolve = 0, print_version = 0;
 int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0;
diff --git a/src/clients/kswitch/kswitch.c b/src/clients/kswitch/kswitch.c
index f26ecea..9cba7cb 100644
--- a/src/clients/kswitch/kswitch.c
+++ b/src/clients/kswitch/kswitch.c
@@ -27,9 +27,6 @@
 #include "k5-int.h"
 #include <locale.h>
 
-extern int optind;
-extern char *optarg;
-
 #ifndef _WIN32
 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
 #else
diff --git a/src/clients/kvno/kvno.c b/src/clients/kvno/kvno.c
index 80bee59..9b402f3 100644
--- a/src/clients/kvno/kvno.c
+++ b/src/clients/kvno/kvno.c
@@ -32,9 +32,6 @@
 #endif
 #include <string.h>
 
-extern int optind;
-extern char *optarg;
-
 static char *prog;
 
 static void xusage()
diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h
index 994f463..1210cc3 100644
--- a/src/include/k5-platform.h
+++ b/src/include/k5-platform.h
@@ -1065,10 +1065,16 @@ int k5_path_isabs(const char *path);
 #define N_(s) s
 
 #if !defined(HAVE_GETOPT) || !defined(HAVE_UNISTD_H)
-extern int k5_opterr;
-extern int k5_optind;
-extern int k5_optopt;
-extern char *k5_optarg;
+/* Data objects imported from DLLs must be declared as such on Windows. */
+#if defined(_WIN32) && !defined(K5_GETOPT_C)
+#define K5_GETOPT_DECL __declspec(dllimport)
+#else
+#define K5_GETOPT_DECL
+#endif
+K5_GETOPT_DECL extern int k5_opterr;
+K5_GETOPT_DECL extern int k5_optind;
+K5_GETOPT_DECL extern int k5_optopt;
+K5_GETOPT_DECL extern char *k5_optarg;
 #define opterr k5_opterr
 #define optind k5_optind
 #define optopt k5_optopt
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index 6239e41..30fe154 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -172,8 +172,9 @@ SHLIB_EXPORT_FILE=libkrb5support.exports
 
 EXTRA_SUPPORT_SYMS= @EXTRA_SUPPORT_SYMS@
 ##DOS##EXTRA_SUPPORT_SYMS= krb5int_mkstemp krb5int_strlcpy krb5int_strlcat \
-##DOS##		k5_optind k5_optarg k5_opterr k5_optopt k5_getopt k5_getopt_long \
+##DOS##		k5_getopt k5_getopt_long \
 ##DOS##		krb5int_vasprintf krb5int_asprintf krb5int_gettimeofday $(IPC_SYMS)
+##DOS##DATA_SUPPORT_SYMS= k5_opterr k5_optind k5_optopt k5_optarg
 
 ##DOS##!if 0
 libkrb5support.exports: $(srcdir)/libkrb5support-fixed.exports Makefile
@@ -186,6 +187,7 @@ libkrb5support.exports: $(srcdir)/libkrb5support-fixed.exports Makefile
 ##DOS##libkrb5support.exports: libkrb5support-fixed.exports Makefile
 ##DOS##	$(CP) libkrb5support-fixed.exports new-exports
 ##DOS##	for %%x in ($(EXTRA_SUPPORT_SYMS) .) do if not %%x==. echo %%x >> new-exports
+##DOS##	for %%x in ($(DATA_SUPPORT_SYMS) .) do if not %x==. echo %%x DATA >> new-exports
 ##DOS##	$(RM) libkrb5support.exports
 ##DOS##	$(MV) new-exports libkrb5support.exports
 
diff --git a/src/util/support/getopt.c b/src/util/support/getopt.c
index 44cda68..ae8cb10 100644
--- a/src/util/support/getopt.c
+++ b/src/util/support/getopt.c
@@ -39,6 +39,8 @@
 static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
 #endif
 
+#define K5_GETOPT_C
+
 #include <assert.h>
 #include <errno.h>
 #include <stdio.h>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.