diff --git a/COPYING b/COPYING
index bbf09ca7631e9c6b2837a3bc0e9bfa47f99e6eb7..cd9e80a48a74ffe01deff993361f0ed3d30a37dc 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 b56d3e8a206fc3acb1787d34331d90c8c53f70dc..d2318dafd56b3fa1ba81dbd3d6ecacd8619c01a2 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 4ac3c818c98b8d12c5de7c50dbab35245f88b6b7..356d490fa6f5afceb37e354d6688d821500cb995 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 966d215257dd91165d2a318d5ca6d9523b409040..42f00826995d0dae676d86e4a2135e6c0d1271f0 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 0000000000000000000000000000000000000000..5177122c90787675c7fc29e0f24fa330a5bcb841
--- /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 6a332642b1de6b05645c8a15cf8b443a0a8d1e4c..5622766b8d4dc0ccaf1cc88579869b13f062d29a 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 566514d4ae7e04652ea68075baea11f6674dc190..88f23aeedda969e5c1cdf21728794f787e31d16c 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 71a4424f793166619b89769fa1de5e99e1cc25e5..0a8bd068735bd48e1a4dad1323b19d354869babc 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;
 }