summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING2
-rw-r--r--configure.ac2
-rwxr-xr-xhw/xfree86/loader/sdksyms.sh1
-rw-r--r--include/Makefile.am1
-rw-r--r--include/Xprintf.h69
-rw-r--r--include/dix-config.h.in3
-rw-r--r--include/os.h12
-rw-r--r--os/xprintf.c170
8 files changed, 230 insertions, 30 deletions
diff --git a/COPYING b/COPYING
index bbf09ca76..cd9e80a48 100644
--- a/COPYING
+++ b/COPYING
@@ -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;
}