diff options
| author | Russ Allbery <rra@stanford.edu> | 2010-02-09 15:32:54 -0800 | 
|---|---|---|
| committer | Russ Allbery <rra@stanford.edu> | 2010-02-09 15:32:54 -0800 | 
| commit | ccf1cd7efa90bdcbe834e0d4ca144289cca97fd7 (patch) | |
| tree | a3f791ef91920da7a1857e2e95bab3ecdf9aa4a7 | |
| parent | ce6c27ef04783e21baf44549ff9e361e0c0f148e (diff) | |
Update portability code to rra-c-util 3.0
Add replacements for mkstemp and setenv, since we now use them when
obtaining credentials in the client.  Fix the bool type with Sun Studio
12 on Solaris 10.
| -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 | 
