X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Fff-printf.c;h=f2ef8f3244b33ae5888af7f78e128b15b9043d82;hb=3f82df43970c14a075f6590417f6b72ba5d3fe93;hp=903508cfa10c8d43e7de569d16adbc4dfacf01be;hpb=f1149d882df3b1bfd12a33cef49430f559c3e0ee;p=libucw.git diff --git a/ucw/ff-printf.c b/ucw/ff-printf.c index 903508cf..f2ef8f32 100644 --- a/ucw/ff-printf.c +++ b/ucw/ff-printf.c @@ -9,9 +9,9 @@ #include #include +#include #include -#include #include int @@ -26,27 +26,38 @@ vbprintf(struct fastbuf *b, const char *msg, va_list args) len = vsnprintf(buf, remains, msg, args2); va_end(args2); - if (len <= remains) + if (len < remains) { bdirect_write_commit(b, buf + len); return len; } + /* + * We need a temporary buffer. If it is small, let's use stack. + * Otherwise, we malloc it, but we have to be careful, since we + * might be running inside a transaction and bwrite() could + * throw an exception. + * + * FIXME: This deserves a more systematic solution, the same + * problem is likely to happen at other places, too. + */ int bufsize = len + 1; - bool need_free = 0; + struct resource *res = NULL; + byte *extra_buffer = NULL; if (bufsize <= 256) buf = alloca(bufsize); + else if (rp_current()) + buf = res_malloc(bufsize, &res); else - { - buf = xmalloc(bufsize); - need_free = 1; - } + buf = extra_buffer = xmalloc(bufsize); vsnprintf(buf, bufsize, msg, args); bwrite(b, buf, len); - if (need_free) - xfree(buf); + if (res) + res_free(res); + else if (extra_buffer) + xfree(extra_buffer); return len; }