From ec674671176ea46e5d20eff2ae923a21442573c3 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Wed, 15 Oct 2008 16:27:46 +0000 Subject: [PATCH] Now that we have support for conditionally exporting symbols from the support library, use that for the [v]asprintf replacement functions when needed. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20871 dc483132-0cff-0310-8789-dd5450dbe970 --- src/configure.in | 10 +++- src/include/k5-platform.h | 79 ++------------------------- src/util/support/Makefile.in | 9 ++++ src/util/support/printf.c | 101 +++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 75 deletions(-) create mode 100644 src/util/support/printf.c diff --git a/src/configure.in b/src/configure.in index f1608d474..7a434cbf3 100644 --- a/src/configure.in +++ b/src/configure.in @@ -90,6 +90,15 @@ AC_SUBST(LIBUTIL) dnl for kdc AC_CHECK_HEADERS(syslog.h stdarg.h sys/select.h sys/sockio.h ifaddrs.h unistd.h) AC_CHECK_FUNCS(openlog syslog closelog strftime vsprintf vasprintf vsnprintf) +EXTRA_SUPPORT_SYMS= +AC_CHECK_FUNC(vasprintf, +[PRINTF_ST_OBJ= +PRINTF_OBJ=], +[PRINTF_ST_OBJ=printf.o +PRINTF_OBJ='$(OUTPRE)printf.$(OBJEXT)' +EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_asprintf krb5int_vasprintf"]) +AC_SUBST(PRINTF_OBJ) +AC_SUBST(PRINTF_ST_OBJ) KRB5_NEED_PROTO([#include #include ],vasprintf) @@ -170,7 +179,6 @@ AC_C_CONST AC_HEADER_DIRENT AC_CHECK_FUNCS(strdup setvbuf inet_ntoa inet_aton seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strftime strptime geteuid setenv unsetenv getenv gethostbyname2 getifaddrs gmtime_r localtime_r pthread_mutex_lock sched_yield bswap16 bswap64 mkstemp getusershell lstat access ftime getcwd srand48 srand srandom stat strchr strerror strerror_r strstr timezone umask waitpid sem_init sem_trywait daemon) dnl -EXTRA_SUPPORT_SYMS= AC_CHECK_FUNC(mkstemp, [MKSTEMP_ST_OBJ= MKSTEMP_OBJ=], diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h index 15d585b34..4a2b1aef7 100644 --- a/src/include/k5-platform.h +++ b/src/include/k5-platform.h @@ -892,87 +892,18 @@ snprintf(char *str, size_t size, const char *format, ...) #endif /* win32? */ #endif /* no vsnprintf */ -#ifndef HAVE_VASPRINTF - #if !defined(__cplusplus) && (__GNUC__ > 2) -static inline int k5_vasprintf(char **, const char *, va_list) +extern int krb5int_vasprintf(char **, const char *, va_list) __attribute__((__format__(__printf__, 2, 0))); -static inline int k5_asprintf(char **, const char *, ...) +extern int krb5int_asprintf(char **, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); #endif -#define vasprintf k5_vasprintf -/* On error: BSD: Set *ret to NULL. GNU: *ret is undefined. +#ifndef HAVE_VASPRINTF - Since we want to be able to use the GNU version directly, we need - provide only the weaker guarantee in this version. */ -static inline int -vasprintf(char **ret, const char *format, va_list ap) -{ - va_list ap2; - char *str = NULL, *nstr; - size_t len = 80; - int len2; - - while (1) { - if (len >= INT_MAX || len == 0) - goto fail; - nstr = realloc(str, len); - if (nstr == NULL) - goto fail; - str = nstr; - va_copy(ap2, ap); - len2 = vsnprintf(str, len, format, ap2); - va_end(ap2); - /* ISO C vsnprintf returns the needed length. Some old - vsnprintf implementations return -1 on truncation. */ - if (len2 < 0) { - /* Don't know how much space we need, just that we didn't - supply enough; get a bigger buffer and try again. */ - if (len <= SIZE_MAX/2) - len *= 2; - else if (len < SIZE_MAX) - len = SIZE_MAX; - else - goto fail; - } else if ((unsigned int) len2 >= SIZE_MAX) { - /* Need more space than we can request. */ - goto fail; - } else if ((size_t) len2 >= len) { - /* Need more space, but we know how much. */ - len = (size_t) len2 + 1; - } else { - /* Success! */ - break; - } - } - /* We might've allocated more than we need, if we're still using - the initial guess, or we got here by doubling. */ - if ((size_t) len2 < len - 1) { - nstr = realloc(str, (size_t) len2 + 1); - if (nstr) - str = nstr; - } - *ret = str; - return len2; - -fail: - free(str); - return -1; -} +#define vasprintf krb5int_vasprintf /* Assume HAVE_ASPRINTF iff HAVE_VASPRINTF. */ -#define asprintf k5_asprintf -static inline int -k5_asprintf(char **ret, const char *format, ...) -{ - va_list ap; - int n; - - va_start(ap, format); - n = vasprintf(ret, format, ap); - va_end(ap); - return n; -} +#define asprintf krb5int_asprintf #elif defined(NEED_VASPRINTF_PROTO) diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in index dfd642c2c..4fc6b1d69 100644 --- a/src/util/support/Makefile.in +++ b/src/util/support/Makefile.in @@ -30,6 +30,9 @@ MKSTEMP_OBJ= @MKSTEMP_OBJ@ ##DOS##MKSTEMP_ST_OBJ= mkstemp.o ##DOS##MKSTEMP_OBJ= $(OUTPRE)mkstemp.$(OBJEXT) +PRINTF_ST_OBJ= @PRINTF_ST_OBJ@ +PRINTF_OBJ= @PRINTF_OBJ@ + STLIBOBJS= \ threads.o \ init-addrinfo.o \ @@ -37,6 +40,7 @@ STLIBOBJS= \ errors.o \ gmt_mktime.o \ fake-addrinfo.o \ + $(PRINTF_ST_OBJ) \ $(MKSTEMP_ST_OBJ) LIBOBJS= \ @@ -46,6 +50,7 @@ LIBOBJS= \ $(OUTPRE)errors.$(OBJEXT) \ $(OUTPRE)gmt_mktime.$(OBJEXT) \ $(OUTPRE)fake-addrinfo.$(OBJEXT) \ + $(PRINTF_OBJ) \ $(MKSTEMP_OBJ) STOBJLISTS=OBJS.ST @@ -60,6 +65,7 @@ SRCS=\ $(srcdir)/errors.c \ $(srcdir)/gmt_mktime.c \ $(srcdir)/fake-addrinfo.c \ + $(srcdir)/printf.c \ $(srcdir)/mkstemp.c SHLIB_EXPDEPS = @@ -134,6 +140,9 @@ fake-addrinfo.so fake-addrinfo.po $(OUTPRE)fake-addrinfo.$(OBJEXT): \ $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ cache-addrinfo.h fake-addrinfo.c supp-int.h +printf.so printf.po $(OUTPRE)printf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ + printf.c mkstemp.so mkstemp.po $(OUTPRE)mkstemp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ mkstemp.c diff --git a/src/util/support/printf.c b/src/util/support/printf.c new file mode 100644 index 000000000..0df8c84ca --- /dev/null +++ b/src/util/support/printf.c @@ -0,0 +1,101 @@ +/* + * printf.c + * + * Copyright 2003, 2004, 2005, 2007, 2008 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * Provide {,v}asprintf for platforms that don't have them. + */ + +#include "k5-platform.h" + +/* On error: BSD: Set *ret to NULL. GNU: *ret is undefined. + + Since we want to be able to use the GNU version directly, we need + provide only the weaker guarantee in this version. */ +int +krb5int_vasprintf(char **ret, const char *format, va_list ap) +{ + va_list ap2; + char *str = NULL, *nstr; + size_t len = 80; + int len2; + + while (1) { + if (len >= INT_MAX || len == 0) + goto fail; + nstr = realloc(str, len); + if (nstr == NULL) + goto fail; + str = nstr; + va_copy(ap2, ap); + len2 = vsnprintf(str, len, format, ap2); + va_end(ap2); + /* ISO C vsnprintf returns the needed length. Some old + vsnprintf implementations return -1 on truncation. */ + if (len2 < 0) { + /* Don't know how much space we need, just that we didn't + supply enough; get a bigger buffer and try again. */ + if (len <= SIZE_MAX/2) + len *= 2; + else if (len < SIZE_MAX) + len = SIZE_MAX; + else + goto fail; + } else if ((unsigned int) len2 >= SIZE_MAX) { + /* Need more space than we can request. */ + goto fail; + } else if ((size_t) len2 >= len) { + /* Need more space, but we know how much. */ + len = (size_t) len2 + 1; + } else { + /* Success! */ + break; + } + } + /* We might've allocated more than we need, if we're still using + the initial guess, or we got here by doubling. */ + if ((size_t) len2 < len - 1) { + nstr = realloc(str, (size_t) len2 + 1); + if (nstr) + str = nstr; + } + *ret = str; + return len2; + +fail: + free(str); + return -1; +} + +int +krb5int_asprintf(char **ret, const char *format, ...) +{ + va_list ap; + int n; + + va_start(ap, format); + n = krb5int_vasprintf(ret, format, ap); + va_end(ap); + return n; +} -- 2.26.2