From ccd4e2aa30cb950af8c92ba86e2721fac99b9337 Mon Sep 17 00:00:00 2001 From: oetiker Date: Mon, 11 May 2009 21:25:57 +0000 Subject: [PATCH] fix rrd_getops use of external variables (optarg and friends) ... most prominently is kills a segfault when using rrdtool perl bindings on solaris ... thanks to Ihsan Dogan for helping with tracking this down and providing access to sparc solaris boxes. git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@1799 a5681a0c-68f1-0310-ab6d-d61299d08faa --- program/configure.ac | 13 +++++++++++++ program/src/rrd_getopt.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/program/configure.ac b/program/configure.ac index 843e5b24..ac5023e3 100644 --- a/program/configure.ac +++ b/program/configure.ac @@ -372,6 +372,19 @@ CHECK_FOR_WORKING_MS_ASYNC dnl Do we need getopt_long +dnl even when including our own getopt implementation +dnl we may want to make sure we use the external +dnl defined by libc to not run into linker resolve trouble + +AC_CACHE_CHECK([for opterr], rd_cv_var_int_opterr, +[AC_TRY_LINK([#include ], + [extern int opterr; opterr = 1;], + [rd_cv_var_int_opterr=yes], + [rd_cv_var_int_opterr=no])]) +if test x"$rd_cv_var_int_opterr" = x"yes"; then + AC_DEFINE(HAVE_INT_OPTERR, 1, [Define to 1 if you have the global variable 'int opterr'.]) +fi + build_getopt=no RRD_GETOPT_LONG="LIBC_HAS_GETOPT_LONG" AC_CHECK_FUNC(getopt_long,[],[ diff --git a/program/src/rrd_getopt.c b/program/src/rrd_getopt.c index dbb3f3f7..f973471c 100644 --- a/program/src/rrd_getopt.c +++ b/program/src/rrd_getopt.c @@ -112,6 +112,14 @@ Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ +/* + * On some versions of Solaris, opterr and friends are defined in core libc + * rather than in a separate getopt module. Define these variables only + * if configure found they aren't there by default. (We assume that testing + * opterr is sufficient for all of these except optreset.) + */ +#ifndef HAVE_INT_OPTERR + char *optarg = NULL; /* Index in ARGV of the next element to be scanned. @@ -126,9 +134,28 @@ char *optarg = NULL; Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + /* 1003.2 says this must be 1 before any call. */ int optind = 1; +#else + extern int opterr; + extern int optind; + extern int optopt; + extern char *optarg; +#endif + + /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ @@ -144,16 +171,6 @@ int __getopt_initialized = 0; static char *nextchar; -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. -- 2.30.2