EXPORT_C int vasprintf(char **str, const char *fmt, va_list ap) { int ret; FILE f; struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); if (f._bf._base == NULL) { *str = NULL; errno = ENOMEM; return (-1); } f._bf._size = f._w = 127; /* Leave room for the NUL */ f._extra = &ext; INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); if (ret < 0) { free(f._bf._base); *str = NULL; errno = ENOMEM; return (-1); } *f._p = '\0'; *str = (char *)f._bf._base; return (ret); }
/* * Helper function for `fprintf to unbuffered unix file': creates a * temporary buffer. We only work on write-only files; this avoids * worries about ungetc buffers and so forth. */ static int __sbprintf(FILE *fp, locale_t loc, const char *fmt, va_list ap) { int ret; FILE fake; unsigned char buf[BUFSIZ]; struct __sFILEX ext; fake._extra = &ext; INITEXTRA(&fake); /* XXX This is probably not needed. */ if (prepwrite(fp) != 0) return (EOF); /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; fake._orientation = fp->_orientation; fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; fake._bf._size = fake._w = sizeof(buf); fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ ret = __vfprintf(&fake, loc, fmt, ap); if (ret >= 0 && __fflush(&fake)) ret = EOF; if (fake._flags & __SERR) fp->_flags |= __SERR; return (ret); }