aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2018-05-15 21:52:08 -0700
committerGreg Hudson <ghudson@mit.edu>2018-10-29 12:42:36 -0400
commit8b8cad8b9ff92e2a2d344fc7c4d77277c9c09829 (patch)
treec0ba69ba602b66540bf85e61c3124253930ce6a0
parent387d5d333e82b3b0858c48d5f7c541ef122e36b6 (diff)
downloadkrb5-8b8cad8b9ff92e2a2d344fc7c4d77277c9c09829.zip
krb5-8b8cad8b9ff92e2a2d344fc7c4d77277c9c09829.tar.gz
krb5-8b8cad8b9ff92e2a2d344fc7c4d77277c9c09829.tar.bz2
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
-rw-r--r--src/clients/kdestroy/kdestroy.c3
-rw-r--r--src/clients/klist/klist.c2
-rw-r--r--src/clients/kswitch/kswitch.c3
-rw-r--r--src/clients/kvno/kvno.c3
-rw-r--r--src/include/k5-platform.h14
-rw-r--r--src/util/support/Makefile.in4
-rw-r--r--src/util/support/getopt.c2
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>