diff options
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rwxr-xr-x | hw/xfree86/loader/sdksyms.sh | 1 | ||||
-rw-r--r-- | include/Makefile.am | 1 | ||||
-rw-r--r-- | include/Xprintf.h | 69 | ||||
-rw-r--r-- | include/dix-config.h.in | 3 | ||||
-rw-r--r-- | include/os.h | 12 | ||||
-rw-r--r-- | os/xprintf.c | 170 |
8 files changed, 230 insertions, 30 deletions
@@ -15,7 +15,7 @@ Copyright © 2006 Nokia Corporation Copyright © 2006-2008 Peter Hutterer Copyright © 2006 Adam Jackson Copyright © 2009-2010 NVIDIA Corporation -Copyright © 1987, 2003-2006, 2008-2009 Oracle and/or its affiliates. +Copyright © 1987, 2003-2006, 2008-2010 Oracle and/or its affiliates. Copyright © 1999 Keith Packard Copyright © 2007-2009 Red Hat, Inc. Copyright © 2005-2008 Daniel Stone diff --git a/configure.ac b/configure.ac index b56d3e8a2..d2318dafd 100644 --- a/configure.ac +++ b/configure.ac @@ -203,7 +203,7 @@ dnl Checks for library functions. AC_FUNC_VPRINTF AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \ strtol getopt getopt_long vsnprintf walkcontext backtrace \ - getisax getzoneid shmctl64 strcasestr ffs]) + getisax getzoneid shmctl64 strcasestr ffs vasprintf]) AC_FUNC_ALLOCA dnl Old HAS_* names used in os/*.c. AC_CHECK_FUNC([getdtablesize], diff --git a/hw/xfree86/loader/sdksyms.sh b/hw/xfree86/loader/sdksyms.sh index 4ac3c818c..356d490fa 100755 --- a/hw/xfree86/loader/sdksyms.sh +++ b/hw/xfree86/loader/sdksyms.sh @@ -253,6 +253,7 @@ cat > sdksyms.c << EOF /* include/Makefile.am */ #include "XIstubs.h" +#include "Xprintf.h" #include "closestr.h" #include "closure.h" #include "colormap.h" diff --git a/include/Makefile.am b/include/Makefile.am index 966d21525..42f008269 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,6 +1,7 @@ if XORG sdk_HEADERS = \ XIstubs.h \ + Xprintf.h \ callback.h \ closestr.h \ closure.h \ diff --git a/include/Xprintf.h b/include/Xprintf.h new file mode 100644 index 000000000..5177122c9 --- /dev/null +++ b/include/Xprintf.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef XPRINTF_H +#define XPRINTF_H + +#include <stdio.h> +#include <stdarg.h> +#include <X11/Xfuncproto.h> + +#ifndef _X_RESTRICT_KYWD +# if defined(restrict) /* assume autoconf set it correctly */ || \ + (defined(__STDC__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ +# define _X_RESTRICT_KYWD restrict +# elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ +# define _X_RESTRICT_KYWD __restrict__ +# else +# define _X_RESTRICT_KYWD +# endif +#endif + +/* + * These functions provide a portable implementation of the common (but not + * yet universal) asprintf & vasprintf routines to allocate a buffer big + * enough to sprintf the arguments to. The XNF variants terminate the server + * if the allocation fails. + * The buffer allocated is returned in the pointer provided in the first + * argument. The return value is the size of the allocated buffer, or -1 + * on failure. + */ +extern _X_EXPORT int Xasprintf (char **ret, + const char * _X_RESTRICT_KYWD fmt, + ...) _X_ATTRIBUTE_PRINTF(2,3); +extern _X_EXPORT int Xvasprintf (char **ret, + const char * _X_RESTRICT_KYWD fmt, + va_list va) _X_ATTRIBUTE_PRINTF(2,0); +extern _X_EXPORT int XNFasprintf (char **ret, + const char * _X_RESTRICT_KYWD fmt, + ...) _X_ATTRIBUTE_PRINTF(2,3); +extern _X_EXPORT int XNFvasprintf (char **ret, + const char * _X_RESTRICT_KYWD fmt, + va_list va) _X_ATTRIBUTE_PRINTF(2,0); + +#if !defined(HAVE_ASPRINTF) && !defined(HAVE_VASPRINTF) +# define asprintf Xasprintf +# define vasprintf Xvasprintf +#endif + +#endif /* XPRINTF_H */ diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 6a332642b..5622766b8 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -243,6 +243,9 @@ /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF +/* Define to 1 if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + /* Support IPv6 for TCP connections */ #undef IPv6 diff --git a/include/os.h b/include/os.h index 566514d4a..88f23aeed 100644 --- a/include/os.h +++ b/include/os.h @@ -263,10 +263,14 @@ extern _X_EXPORT char *Xstrdup(const char *s); */ extern _X_EXPORT char *XNFstrdup(const char *s); -extern _X_EXPORT char *Xprintf(const char *fmt, ...) _X_ATTRIBUTE_PRINTF(1,2); -extern _X_EXPORT char *Xvprintf(const char *fmt, va_list va); -extern _X_EXPORT char *XNFprintf(const char *fmt, ...) _X_ATTRIBUTE_PRINTF(1,2); -extern _X_EXPORT char *XNFvprintf(const char *fmt, va_list va); +/* Include new X*asprintf API */ +#include "Xprintf.h" + +/* Older api deprecated in favor of the asprintf versions */ +extern _X_EXPORT char *Xprintf(const char *fmt, ...) _X_ATTRIBUTE_PRINTF(1,2) _X_DEPRECATED; +extern _X_EXPORT char *Xvprintf(const char *fmt, va_list va)_X_ATTRIBUTE_PRINTF(1,0) _X_DEPRECATED; +extern _X_EXPORT char *XNFprintf(const char *fmt, ...) _X_ATTRIBUTE_PRINTF(1,2) _X_DEPRECATED; +extern _X_EXPORT char *XNFvprintf(const char *fmt, va_list va)_X_ATTRIBUTE_PRINTF(1,0) _X_DEPRECATED; typedef void (*OsSigHandlerPtr)(int /* sig */); typedef int (*OsSigWrapperPtr)(int /* sig */); diff --git a/os/xprintf.c b/os/xprintf.c index 71a4424f7..0a8bd0687 100644 --- a/os/xprintf.c +++ b/os/xprintf.c @@ -1,6 +1,13 @@ -/* - * printf routines which xalloc their buffer - */ +/** + * @file + * + * @section DESCRIPTION + * + * These functions provide a portable implementation of the common (but not + * yet universal) asprintf & vasprintf routines to allocate a buffer big + * enough to sprintf the arguments to. The XNF variants terminate the server + * if the allocation fails. + */ /* * Copyright (c) 2004 Alexander Gottwald * @@ -26,6 +33,29 @@ * holders shall not be used in advertising or otherwise to promote the sale, * use or other dealings in this Software without prior written authorization. */ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif @@ -35,6 +65,13 @@ #include <stdarg.h> #include <stdio.h> +#ifdef asprintf +# undef asprintf +#endif +#ifdef vasprintf +# undef vasprintf +#endif + #ifndef va_copy # ifdef __va_copy # define va_copy __va_copy @@ -42,11 +79,23 @@ # error "no working va_copy was found" # endif #endif - -char * -Xvprintf(const char *format, va_list va) + +/** + * Varargs sprintf that allocates a string buffer the right size for + * the pattern & data provided and prints the requested data to it. + * + * @param ret Pointer to which the newly allocated buffer is written + * (contents undefined on error) + * @param format printf style format string + * @param va variable argument list + * @return size of allocated buffer, or -1 on error. + */ +int +Xvasprintf(char **ret, const char * _X_RESTRICT_KYWD format, va_list va) { - char *ret; +#ifdef HAVE_VASPRINTF + return vasprintf(ret, format, va); +#else int size; va_list va2; @@ -54,12 +103,94 @@ Xvprintf(const char *format, va_list va) size = vsnprintf(NULL, 0, format, va2); va_end(va2); - ret = (char *)malloc(size + 1); - if (ret == NULL) - return NULL; + *ret = malloc(size + 1); + if (*ret == NULL) + return -1; - vsnprintf(ret, size + 1, format, va); + vsnprintf(*ret, size + 1, format, va); ret[size] = 0; + return size; +#endif +} + +#ifndef HAVE_VASPRINTF +# define vasprintf Xvasprintf +#endif + +/** + * sprintf that allocates a string buffer the right size for + * the pattern & data provided and prints the requested data to it. + * + * @param ret Pointer to which the newly allocated buffer is written + * (contents undefined on error) + * @param format printf style format string + * @param ... arguments for specified format + * @return size of allocated buffer, or -1 on error. + */ +int +Xasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...) +{ + int size; + va_list va; + va_start(va, format); + size = vasprintf(ret, format, va); + va_end(va); + return size; +} + +/** + * Varargs sprintf that allocates a string buffer the right size for + * the pattern & data provided and prints the requested data to it. + * On failure, issues a FatalError message and aborts the server. + * + * @param ret Pointer to which the newly allocated buffer is written + * (contents undefined on error) + * @param format printf style format string + * @param va variable argument list + * @return size of allocated buffer + */ +int +XNFvasprintf(char **ret, const char * _X_RESTRICT_KYWD format, va_list va) +{ + int size = vasprintf(ret, format, va); + if ((size == -1) || (*ret == NULL)) { + Error("XNFvasprintf"); + FatalError("XNFvasprintf failed"); + } + return size; +} + +/** + * sprintf that allocates a string buffer the right size for + * the pattern & data provided and prints the requested data to it. + * On failure, issues a FatalError message and aborts the server. + * + * @param ret Pointer to which the newly allocated buffer is written + * (contents undefined on error) + * @param format printf style format string + * @param ... arguments for specified format + * @return size of allocated buffer + */ +int +XNFasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...) +{ + int size; + va_list va; + va_start(va, format); + size = XNFvasprintf(ret, format, va); + va_end(va); + return size; +} + +/* Old api, now deprecated, may be removed in the future */ +char * +Xvprintf(const char *format, va_list va) +{ + char *ret; + + if (vasprintf(&ret, format, va) == -1) + ret = NULL; + return ret; } @@ -68,7 +199,8 @@ char *Xprintf(const char *format, ...) char *ret; va_list va; va_start(va, format); - ret = Xvprintf(format, va); + if (vasprintf(&ret, format, va) == -1) + ret = NULL; va_end(va); return ret; } @@ -77,19 +209,9 @@ char * XNFvprintf(const char *format, va_list va) { char *ret; - int size; - va_list va2; - - va_copy(va2, va); - size = vsnprintf(NULL, 0, format, va2); - va_end(va2); - ret = (char *)xnfalloc(size + 1); - if (ret == NULL) - return NULL; + XNFvasprintf(&ret, format, va); - vsnprintf(ret, size + 1, format, va); - ret[size] = 0; return ret; } @@ -98,7 +220,7 @@ char *XNFprintf(const char *format, ...) char *ret; va_list va; va_start(va, format); - ret = XNFvprintf(format, va); + XNFvasprintf(&ret, format, va); va_end(va); return ret; } |