forked from lda/telodendria
Fix broken IoVprintf().
You can't call vsnprintf() on the same va_list more than once! I learned this the hard way with StreamVprintf().
This commit is contained in:
parent
5289c16e2b
commit
6c9e939b9f
2 changed files with 14 additions and 33 deletions
4
TODO.txt
4
TODO.txt
|
@ -12,8 +12,8 @@ Milestone: v0.3.0
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
[~] Stream API
|
[~] Stream API
|
||||||
[~] Implementation
|
[x] Implementation
|
||||||
[ ] Convert all code that deals with I/O
|
[x] Convert all code that deals with I/O
|
||||||
[!] Multi-output (proof of concept)
|
[!] Multi-output (proof of concept)
|
||||||
[!] Memory streams (proof of concept)
|
[!] Memory streams (proof of concept)
|
||||||
[ ] TLS
|
[ ] TLS
|
||||||
|
|
43
src/Io.c
43
src/Io.c
|
@ -25,8 +25,9 @@
|
||||||
|
|
||||||
#include <Memory.h>
|
#include <Memory.h>
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
struct Io
|
struct Io
|
||||||
|
@ -133,8 +134,9 @@ IoClose(Io * io)
|
||||||
int
|
int
|
||||||
IoVprintf(Io * io, const char *fmt, va_list ap)
|
IoVprintf(Io * io, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf = NULL;
|
||||||
int write;
|
size_t bufSize = 0;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -143,42 +145,21 @@ IoVprintf(Io * io, const char *fmt, va_list ap)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = Malloc(IO_BUFFER);
|
fp = open_memstream(&buf, &bufSize);
|
||||||
if (!buf)
|
if (!fp)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
write = vsnprintf(buf, IO_BUFFER, fmt, ap);
|
ret = vfprintf(fp, fmt, ap);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
if (write < 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
Free(buf);
|
ret = IoWrite(io, buf, bufSize);
|
||||||
return write;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of bytes to write exceeded buffer size; this should be
|
free(buf); /* Allocated by stdlib, not Memory API */
|
||||||
* rare, but may occasionally happen. If it does, realloc to the
|
|
||||||
* correct size and try again. */
|
|
||||||
if (write >= IO_BUFFER)
|
|
||||||
{
|
|
||||||
char *new = Realloc(buf, write + 1);
|
|
||||||
|
|
||||||
if (!new)
|
|
||||||
{
|
|
||||||
Free(buf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = new;
|
|
||||||
|
|
||||||
/* This time we don't care about the return value */
|
|
||||||
vsnprintf(buf, write, fmt, ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = IoWrite(io, buf, write);
|
|
||||||
|
|
||||||
Free(buf);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue