From: Greg Hudson Date: Wed, 16 May 2018 04:52:08 +0000 (-0700) Subject: Fix option parsing on Windows X-Git-Tag: krb5-1.17-beta1~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F778%2Fhead;p=thirdparty%2Fkrb5.git 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. ticket: 8684 (new) tags: pullup target_version: 1.16-next target_version: 1.15-next --- diff --git a/src/clients/kdestroy/kdestroy.c b/src/clients/kdestroy/kdestroy.c index 0bf83586c1..4e16bec252 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 e9e76d8f3b..70adb54e80 100644 --- a/src/clients/klist/klist.c +++ b/src/clients/klist/klist.c @@ -49,8 +49,6 @@ #include #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 f26ecea032..9cba7cb225 100644 --- a/src/clients/kswitch/kswitch.c +++ b/src/clients/kswitch/kswitch.c @@ -27,9 +27,6 @@ #include "k5-int.h" #include -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 77a128d5db..57f7a78321 100644 --- a/src/clients/kvno/kvno.c +++ b/src/clients/kvno/kvno.c @@ -32,9 +32,6 @@ #endif #include -extern int optind; -extern char *optarg; - static char *prog; static int quiet = 0; diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h index 763408a098..e080b4a6e7 100644 --- a/src/include/k5-platform.h +++ b/src/include/k5-platform.h @@ -1116,10 +1116,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 2799af1be0..890218bc62 100644 --- a/src/util/support/Makefile.in +++ b/src/util/support/Makefile.in @@ -180,8 +180,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 @@ -194,6 +195,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 44cda68de5..ae8cb10dd2 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 #include #include