summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/compat.c')
-rw-r--r--libglusterfs/src/compat.c133
1 files changed, 101 insertions, 32 deletions
diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c
index dc21aecf47e..76ced628629 100644
--- a/libglusterfs/src/compat.c
+++ b/libglusterfs/src/compat.c
@@ -369,38 +369,6 @@ solaris_getxattr(const char *path,
}
-int
-asprintf(char **string_ptr, const char *format, ...)
-{
- va_list arg;
- char *str;
- int size;
- int rv;
-
- if (!string_ptr || !format)
- return -1;
-
- va_start(arg, format);
- size = vsnprintf(NULL, 0, format, arg);
- size++;
- va_start(arg, format);
- str = MALLOC(size);
- if (str == NULL) {
- va_end(arg);
- /*
- * Strictly speaking, GNU asprintf doesn't do this,
- * but the caller isn't checking the return value.
- */
- gf_log ("libglusterfs", GF_LOG_CRITICAL, "failed to allocate memory");
- return -1;
- }
- rv = vsnprintf(str, size, format, arg);
- va_end(arg);
-
- *string_ptr = str;
- return (rv);
-}
-
char* strsep(char** str, const char* delims)
{
char* token;
@@ -424,6 +392,107 @@ char* strsep(char** str, const char* delims)
return token;
}
+/* Code comes from libiberty */
+
+int
+vasprintf (char **result, const char *format, va_list args)
+{
+ const char *p = format;
+ /* Add one to make sure that it is never zero, which might cause malloc
+ to return NULL. */
+ int total_width = strlen (format) + 1;
+ va_list ap;
+
+ /* this is not really portable but works under Windows */
+ memcpy ( &ap, &args, sizeof (va_list));
+
+ while (*p != '\0')
+ {
+ if (*p++ == '%')
+ {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ {
+ char *endp;
+ total_width += strtoul (p, &endp, 10);
+ p = endp;
+ }
+ if (*p == '.')
+ {
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ {
+ char *endp;
+ total_width += strtoul (p, &endp, 10);
+ p = endp;
+ }
+ }
+ while (strchr ("hlL", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s
+ and floats. */
+ total_width += 30;
+ switch (*p)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ (void) va_arg (ap, int);
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ (void) va_arg (ap, double);
+ /* Since an ieee double can have an exponent of 307, we'll
+ make the buffer wide enough to cover the gross case. */
+ total_width += 307;
+
+ case 's':
+ total_width += strlen (va_arg (ap, char *));
+ break;
+ case 'p':
+ case 'n':
+ (void) va_arg (ap, char *);
+ break;
+ }
+ }
+ }
+ *result = malloc (total_width);
+ if (*result != NULL)
+ return vsprintf (*result, format, args);
+ else
+ return 0;
+}
+
+int
+asprintf (char **buf, const char *fmt, ...)
+{
+ int status;
+ va_list ap;
+
+ va_start (ap, fmt);
+ status = vasprintf (buf, fmt, ap);
+ va_end (ap);
+ return status;
+}
+
#endif /* GF_SOLARIS_HOST_OS */
#ifndef HAVE_STRNLEN