diff options
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | portable/asprintf.c | 3 | ||||
-rw-r--r-- | portable/mkstemp.c | 87 | ||||
-rw-r--r-- | portable/setenv.c | 61 | ||||
-rw-r--r-- | portable/stdbool.h | 4 | ||||
-rw-r--r-- | portable/system.h | 38 |
8 files changed, 186 insertions, 16 deletions
diff --git a/Makefile.am b/Makefile.am index 439b4c1..57fb6eb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,8 @@ -# Makefile.am -- Automake makefile for wallet. +# Automake makefile for wallet. # # Written by Russ Allbery <rra@stanford.edu> -# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2006, 2007, 2008, 2010 +# Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -62,6 +62,8 @@ wallet 0.10 (unreleased) * Prefer KRB5_CONFIG over a path constructed from --with-*. * Update GSS-API probes for Solaris 10's native implementation. * Change AC_TRY_* to AC_*_IFELSE as recommended by Autoconf. + * Use AC_TYPE_LONG_LONG_INT instead of AC_CHECK_TYPES([long long]). + * Provide a proper bool type with Sun Studio 12 on Solaris 10. wallet 0.9 (2008-04-24) diff --git a/configure.ac b/configure.ac index 78fecea..1b91ff0 100644 --- a/configure.ac +++ b/configure.ac @@ -37,7 +37,7 @@ RRA_C_GNU_VAMACROS AC_TYPE_LONG_LONG_INT RRA_FUNC_SNPRINTF AC_CHECK_FUNCS([setrlimit]) -AC_REPLACE_FUNCS([asprintf strlcat strlcpy]) +AC_REPLACE_FUNCS([asprintf mkstemp setenv strlcat strlcpy]) AC_ARG_WITH([wallet-server], [AC_HELP_STRING([--with-wallet-server=HOST], [Default wallet server])], diff --git a/portable/asprintf.c b/portable/asprintf.c index 9451795..4219a19 100644 --- a/portable/asprintf.c +++ b/portable/asprintf.c @@ -18,7 +18,8 @@ #if TESTING # define asprintf test_asprintf # define vasprintf test_vasprintf -int test_asprintf(char **, const char *, ...); +int test_asprintf(char **, const char *, ...) + __attribute__((__format__(printf, 2, 3))); int test_vasprintf(char **, const char *, va_list); #endif diff --git a/portable/mkstemp.c b/portable/mkstemp.c new file mode 100644 index 0000000..dd2a485 --- /dev/null +++ b/portable/mkstemp.c @@ -0,0 +1,87 @@ +/* + * Replacement for a missing mkstemp. + * + * Provides the same functionality as the library function mkstemp for those + * systems that don't have it. + * + * Written by Russ Allbery <rra@stanford.edu> + * This work is hereby placed in the public domain by its author. + */ + +#include <config.h> +#include <portable/system.h> + +#include <errno.h> +#include <fcntl.h> +#include <sys/time.h> + +/* + * If we're running the test suite, rename mkstemp to avoid conflicts with the + * system version. #undef it first because some systems may define it to + * another name. + */ +#if TESTING +# undef mkstemp +# define mkstemp test_mkstemp +int test_mkstemp(char *); +#endif + +/* Pick the longest available integer type. */ +#if HAVE_LONG_LONG +typedef unsigned long long long_int_type; +#else +typedef unsigned long long_int_type; +#endif + +int +mkstemp(char *template) +{ + static const char letters[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + size_t length; + char *XXXXXX; + struct timeval tv; + long_int_type randnum, working; + int i, tries, fd; + + /* + * Make sure we have a valid template and initialize p to point at the + * beginning of the template portion of the string. + */ + length = strlen(template); + if (length < 6) { + errno = EINVAL; + return -1; + } + XXXXXX = template + length - 6; + if (strcmp(XXXXXX, "XXXXXX") != 0) { + errno = EINVAL; + return -1; + } + + /* Get some more-or-less random information. */ + gettimeofday(&tv, NULL); + randnum = ((long_int_type) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid(); + + /* + * Now, try to find a working file name. We try no more than TMP_MAX file + * names. + */ + for (tries = 0; tries < TMP_MAX; tries++) { + for (working = randnum, i = 0; i < 6; i++) { + XXXXXX[i] = letters[working % 62]; + working /= 62; + } + fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600); + if (fd >= 0 || (errno != EEXIST && errno != EISDIR)) + return fd; + + /* + * This is a relatively random increment. Cut off the tail end of + * tv_usec since it's often predictable. + */ + randnum += (tv.tv_usec >> 10) & 0xfff; + } + errno = EEXIST; + return -1; +} diff --git a/portable/setenv.c b/portable/setenv.c new file mode 100644 index 0000000..d66ddcd --- /dev/null +++ b/portable/setenv.c @@ -0,0 +1,61 @@ +/* + * Replacement for a missing setenv. + * + * Provides the same functionality as the standard library routine setenv for + * those platforms that don't have it. + * + * Written by Russ Allbery <rra@stanford.edu> + * This work is hereby placed in the public domain by its author. + */ + +#include <config.h> +#include <portable/system.h> + +/* + * If we're running the test suite, rename setenv to avoid conflicts with + * the system version. + */ +#if TESTING +# define setenv test_setenv +int test_setenv(const char *, const char *, int); +#endif + +int +setenv(const char *name, const char *value, int overwrite) +{ + char *envstring; + size_t size; + + if (!overwrite && getenv(name) != NULL) + return 0; + + /* + * Allocate memory for the environment string. We intentionally don't use + * concat here, or the xmalloc family of allocation routines, since the + * intention is to provide a replacement for the standard library function + * which sets errno and returns in the event of a memory allocation + * failure. + */ + size = strlen(name) + 1 + strlen(value) + 1; + envstring = malloc(size); + if (envstring == NULL) + return -1; + + /* + * Build the environment string and add it to the environment using + * putenv. Systems without putenv lose, but XPG4 requires it. + */ + strlcpy(envstring, name, size); + strlcat(envstring, "=", size); + strlcat(envstring, value, size); + return putenv(envstring); + + /* + * Note that the memory allocated is not freed. This is intentional; many + * implementations of putenv assume that the string passed to putenv will + * never be freed and don't make a copy of it. Repeated use of this + * function will therefore leak memory, since most implementations of + * putenv also don't free strings removed from the environment (due to + * being overwritten). + */ +} diff --git a/portable/stdbool.h b/portable/stdbool.h index 01a2ff2..bfbf4c4 100644 --- a/portable/stdbool.h +++ b/portable/stdbool.h @@ -15,7 +15,9 @@ #if HAVE_STDBOOL_H # include <stdbool.h> #else -# if !HAVE__BOOL +# if HAVE__BOOL +# define bool _Bool +# else # ifdef __cplusplus typedef bool _Bool; # elif _WIN32 diff --git a/portable/system.h b/portable/system.h index b899d08..461601b 100644 --- a/portable/system.h +++ b/portable/system.h @@ -1,6 +1,9 @@ /* + * Standard system includes and portability adjustments. + * * Declarations of routines and variables in the C library. Including this - * file is the equivalent of including all of the following headers, portably: + * file is the equivalent of including all of the following headers, + * portably: * * #include <sys/types.h> * #include <stdarg.h> @@ -12,8 +15,8 @@ * #include <string.h> * #include <unistd.h> * - * Missing functions are provided via #define or prototyped if available. - * Also provides some standard #defines. + * Missing functions are provided via #define or prototyped if available from + * the portable helper library. Also provides some standard #defines. * * Written by Russ Allbery <rra@stanford.edu> * This work is hereby placed in the public domain by its author. @@ -55,13 +58,17 @@ BEGIN_DECLS +/* Default to a hidden visibility for all portability functions. */ +#pragma GCC visibility push(hidden) + /* * Provide prototypes for functions not declared in system headers. Use the - * HAVE_DECL macros for those functions that may be prototyped but - * implemented incorrectly or implemented without a prototype. + * HAVE_DECL macros for those functions that may be prototyped but implemented + * incorrectly or implemented without a prototype. */ #if !HAVE_ASPRINTF -extern int asprintf(char **, const char *, ...); +extern int asprintf(char **, const char *, ...) + __attribute__((__format__(printf, 2, 3))); extern int vasprintf(char **, const char *, va_list); #endif #if !HAVE_DECL_SNPRINTF @@ -71,6 +78,12 @@ extern int snprintf(char *, size_t, const char *, ...) #if !HAVE_DECL_VSNPRINTF extern int vsnprintf(char *, size_t, const char *, va_list); #endif +#if !HAVE_MKSTEMP +extern int mkstemp(char *); +#endif +#if !HAVE_SETENV +extern int setenv(const char *, const char *, int); +#endif #if !HAVE_STRLCAT extern size_t strlcat(char *, const char *, size_t); #endif @@ -78,6 +91,9 @@ extern size_t strlcat(char *, const char *, size_t); extern size_t strlcpy(char *, const char *, size_t); #endif +/* Undo default visibility change. */ +#pragma GCC visibility pop + END_DECLS /* Windows provides snprintf under a different name. */ @@ -90,9 +106,9 @@ END_DECLS * been defined, all the rest almost certainly have. */ #ifndef STDIN_FILENO -# define STDIN_FILENO 0 -# define STDOUT_FILENO 1 -# define STDERR_FILENO 2 +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 #endif /* @@ -101,9 +117,9 @@ END_DECLS */ #ifndef va_copy # ifdef __va_copy -# define va_copy(d, s) __va_copy((d), (s)) +# define va_copy(d, s) __va_copy((d), (s)) # else -# define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list)) +# define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list)) # endif #endif |