diff options
Diffstat (limited to 'libglusterfs/src/compat.c')
-rw-r--r-- | libglusterfs/src/compat.c | 133 |
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 |