Skip to content

Commit

Permalink
Workaround for non-compliant vsnprintf()
Browse files Browse the repository at this point in the history
  • Loading branch information
cpq committed Aug 2, 2013
1 parent f815c31 commit 2de96bd
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -1629,6 +1629,24 @@ int mg_write(struct mg_connection *conn, const void *buf, size_t len) {
return (int) total;
}

// Alternative alloc_vprintf() for non-compliant C runtimes
static int alloc_vprintf2(char **buf, const char *fmt, va_list ap) {
va_list ap_copy;
int size = MG_BUF_LEN;
int len = -1;

*buf = NULL;
while (len == -1) {
if (*buf) free(*buf);
*buf = malloc(size *= 4);
if (!*buf) break;
va_copy(ap_copy, ap);
len = vsnprintf(*buf, size, fmt, ap_copy);
}

return len;
}

// Print message to buffer. If buffer is large enough to hold the message,
// return buffer. If buffer is to small, allocate large enough buffer on heap,
// and return allocated buffer.
Expand All @@ -1644,7 +1662,12 @@ static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap) {
va_copy(ap_copy, ap);
len = vsnprintf(NULL, 0, fmt, ap_copy);

if (len > (int) size &&
if (len < 0) {
// C runtime is not standard compliant, vsnprintf() returned -1.
// Switch to alternative code path that uses incremental allocations.
va_copy(ap_copy, ap);
len = alloc_vprintf2(buf, fmt, ap);
} else if (len > (int) size &&
(size = len + 1) > 0 &&
(*buf = (char *) malloc(size)) == NULL) {
len = -1; // Allocation failed, mark failure
Expand Down

0 comments on commit 2de96bd

Please sign in to comment.