Skip to content

Commit

Permalink
Use portable definitions of asprintf, snprintf, vsnprintf and strndup
Browse files Browse the repository at this point in the history
  • Loading branch information
jhrozek committed Apr 5, 2016
1 parent dc0266a commit 8bcd688
Show file tree
Hide file tree
Showing 10 changed files with 1,236 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ pam_hbac_la_LDFLAGS = \
-lpam \
-module \
-avoid-version

if NEEDS_PORTABLE
pam_hbac_la_SOURCES += \
src/portable/asprintf.c \
src/portable/snprintf.c \
src/portable/strndup.c \
$(NULL)
endif

if HAVE_GNU_LD
pam_hbac_la_LDFLAGS += \
-Wl,--version-script,$(srcdir)/src/pam_hbac.exports
Expand All @@ -64,6 +73,9 @@ dist_noinst_HEADERS = \
src/libhbac/ipa_hbac.h \
src/libhbac/sss_utf8.h \
src/libhbac/sss_compat.h \
src/portable/portable_macros.h \
src/portable/portable_stdbool.h \
src/portable/portable_system.h \
src/tests/common_mock.h \
src/tests/ph_tests.h \
$(NULL)
Expand Down
12 changes: 12 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ AC_INIT([pam_hbac],
AC_CONFIG_AUX_DIR([build])

AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
[AC_USE_SYSTEM_EXTENSIONS],
[AC_GNU_SOURCE])

m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AM_PROG_CC_C_O
AC_DISABLE_STATIC
Expand All @@ -28,6 +32,14 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
AM_CONDITIONAL([HAVE_GCC], [test "$ac_cv_prog_gcc" = yes])
AM_CONDITIONAL([HAVE_GNU_LD], [test "$lt_cv_prog_gnu_ld" = yes])

# Portability checks
AC_HEADER_STDBOOL
AC_CHECK_TYPES([ssize_t], [], [],
[#include <sys/types.h>])
AC_TYPE_LONG_LONG_INT
AC_CHECK_FUNCS([asprintf vasprintf snprintf vsnprintf strndup], [], [needs_portable=1])
AM_CONDITIONAL([NEEDS_PORTABLE], [test "x$needs_portable" != "x"])

# Check if the compiler supports optional attributes
CC_ATTRIBUTE_PRINTF

Expand Down
21 changes: 21 additions & 0 deletions src/pam_hbac_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <security/pam_appl.h>

#include "config.h"
#include "portable/portable_system.h"

#ifdef HAVE_SECURITY__PAM_MACROS_H
# include <security/_pam_macros.h>
Expand Down Expand Up @@ -85,4 +86,24 @@ do { \
#define FALLBACK_GETPW_R_SIZE_MAX 128
#define FALLBACK_NGROUPS_MAX 128

#ifndef HAVE_ASPRINTF
#define asprintf portable_asprintf
#endif

#ifndef HAVE_VASPRINTF
#define vasprintf portable_vasprintf
#endif

#ifndef HAVE_VSNPRINTF
#define vsnprintf portable_vsnprintf
#endif

#ifndef HAVE_SNPRINTF
#define snprintf portable_snprintf
#endif

#ifndef HAVE_STRNDUP
#define strndp portable_strndup
#endif

#endif /* __PAM_HBAC_COMPAT_H__ */
1 change: 1 addition & 0 deletions src/pam_hbac_dnparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <ldap.h>

#include "pam_hbac_dnparse.h"
#include "pam_hbac_compat.h"

/* if val is NULL, only key is checked */
static bool
Expand Down
65 changes: 65 additions & 0 deletions src/portable/asprintf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Replacement for a missing asprintf and vasprintf.
*
* Provides the same functionality as the standard GNU library routines
* asprintf and vasprintf for those platforms that don't have them.
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* international treaty, and hereby commit to the public, at large, that they
* shall not, at any time in the future, seek to enforce any copyright in this
* work against any person or entity, or prevent any person or entity from
* copying, publishing, distributing or creating derivative works of this
* work.
*/

#include "config.h"
#include "portable_system.h"

#include <errno.h>

int
portable_asprintf(char **strp, const char *fmt, ...)
{
va_list args;
int status;

va_start(args, fmt);
status = portable_vasprintf(strp, fmt, args);
va_end(args);
return status;
}


int
portable_vasprintf(char **strp, const char *fmt, va_list args)
{
va_list args_copy;
int status, needed, oerrno;

va_copy(args_copy, args);
needed = portable_vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
if (needed < 0) {
*strp = NULL;
return needed;
}
*strp = malloc(needed + 1);
if (*strp == NULL)
return -1;
status = portable_vsnprintf(*strp, needed + 1, fmt, args);
if (status >= 0)
return status;
else {
oerrno = errno;
free(*strp);
*strp = NULL;
errno = oerrno;
return status;
}
}
70 changes: 70 additions & 0 deletions src/portable/portable_macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Portability macros used in include files.
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* international treaty, and hereby commit to the public, at large, that they
* shall not, at any time in the future, seek to enforce any copyright in this
* work against any person or entity, or prevent any person or entity from
* copying, publishing, distributing or creating derivative works of this
* work.
*/

#ifndef PORTABLE_MACROS_H
#define PORTABLE_MACROS_H 1

/*
* __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7
* could you use the __format__ form of the attributes, which is what we use
* (to avoid confusion with other macros).
*/
#ifndef __attribute__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __attribute__(spec) /* empty */
# endif
#endif

/*
* We use __alloc_size__, but it was only available in fairly recent versions
* of GCC. Suppress warnings about the unknown attribute if GCC is too old.
* We know that we're GCC at this point, so we can use the GCC variadic macro
* extension, which will still work with versions of GCC too old to have C99
* variadic macro support.
*/
#if !defined(__attribute__) && !defined(__alloc_size__)
# if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)) \
&& !defined(__clang__)
# define __alloc_size__(spec, args...) /* empty */
# endif
#endif

/*
* LLVM and Clang pretend to be GCC but don't support all of the __attribute__
* settings that GCC does. For them, suppress warnings about unknown
* attributes on declarations. This unfortunately will affect the entire
* compilation context, but there's no push and pop available.
*/
#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__))
# pragma GCC diagnostic ignored "-Wattributes"
#endif

/*
* BEGIN_DECLS is used at the beginning of declarations so that C++
* compilers don't mangle their names. END_DECLS is used at the end.
*/
#undef BEGIN_DECLS
#undef END_DECLS
#ifdef __cplusplus
# define BEGIN_DECLS extern "C" {
# define END_DECLS }
#else
# define BEGIN_DECLS /* empty */
# define END_DECLS /* empty */
#endif

#endif /* !PORTABLE_MACROS_H */
49 changes: 49 additions & 0 deletions src/portable/portable_stdbool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Portability wrapper around <stdbool.h>.
*
* Provides the bool and _Bool types and the true and false constants,
* following the C99 specification, on hosts that don't have stdbool.h. This
* logic is based heavily on the example in the Autoconf manual.
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* international treaty, and hereby commit to the public, at large, that they
* shall not, at any time in the future, seek to enforce any copyright in this
* work against any person or entity, or prevent any person or entity from
* copying, publishing, distributing or creating derivative works of this
* work.
*/

#ifndef PORTABLE_STDBOOL_H
#define PORTABLE_STDBOOL_H 1

/*
* Allow inclusion of config.h to be skipped, since sometimes we have to use a
* stripped-down version of config.h with a different name.
*/
#include "config.h"

#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if HAVE__BOOL
# define bool _Bool
# else
# ifdef __cplusplus
typedef bool _Bool;
# else
typedef unsigned char _Bool;
# define bool _Bool
# endif
# endif
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
#endif

#endif /* !PORTABLE_STDBOOL_H */
100 changes: 100 additions & 0 deletions src/portable/portable_system.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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:
*
* #include <inttypes.h>
* #include <limits.h>
* #include <stdarg.h>
* #include <stdbool.h>
* #include <stddef.h>
* #include <stdio.h>
* #include <stdlib.h>
* #include <stdint.h>
* #include <string.h>
* #include <strings.h>
* #include <sys/types.h>
* #include <unistd.h>
*
* Missing functions are provided via #define or prototyped if available from
* the portable helper library. Also provides some standard #defines.
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* international treaty, and hereby commit to the public, at large, that they
* shall not, at any time in the future, seek to enforce any copyright in this
* work against any person or entity, or prevent any person or entity from
* copying, publishing, distributing or creating derivative works of this
* work.
*/

#ifndef PORTABLE_SYSTEM_H
#define PORTABLE_SYSTEM_H 1

/* Make sure we have our configuration information. */
#include "config.h"

/* BEGIN_DECL and __attribute__. */
#include "portable_macros.h"

/* A set of standard ANSI C headers. We don't care about pre-ANSI systems. */
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

/* Get the bool type. */
#include "portable_stdbool.h"

/* Windows does not define ssize_t. */
#ifndef HAVE_SSIZE_T
typedef ptrdiff_t ssize_t;
#endif

/*
* C99 requires va_copy. Older versions of GCC provide __va_copy. Per the
* Autoconf manual, memcpy is a generally portable fallback.
*/
#ifndef va_copy
# ifdef __va_copy
# define va_copy(d, s) __va_copy((d), (s))
# else
# define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
# endif
#endif

BEGIN_DECLS

int portable_asprintf(char **strp, const char *fmt, ...);
int portable_vasprintf(char **strp, const char *fmt, va_list args);

int portable_snprintf (char *str,size_t count,const char *fmt,...);
int portable_vsnprintf (char *str, size_t count, const char *fmt, va_list args);

char *portable_strndup(const char *s, size_t n);

END_DECLS

#endif /* !PORTABLE_SYSTEM_H */

0 comments on commit 8bcd688

Please sign in to comment.