1 : /*
2 : * Copyright 2008 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * NaCl Generic I/O interface.
9 : */
10 : #include "native_client/src/include/portability.h"
11 :
12 : #include <stdlib.h>
13 :
14 : #include "native_client/src/shared/gio/gio.h"
15 :
16 : size_t gvprintf(struct Gio *gp,
17 : char const *fmt,
18 285275 : va_list ap) {
19 285275 : size_t bufsz = 1024;
20 285275 : char *buf = malloc(bufsz);
21 : int rv;
22 :
23 285275 : if (!buf) return -1;
24 :
25 570550 : while ((rv = vsnprintf(buf, bufsz, fmt, ap)) < 0 || (unsigned) rv >= bufsz) {
26 0 : free(buf);
27 0 : buf = 0;
28 :
29 : /**
30 : * Since the buffer size wasn't big enough, we want to double it.
31 : * Stop doubling when we reach SIZE_MAX / 2, though, otherwise we
32 : * risk wraparound.
33 : */
34 0 : if (bufsz < SIZE_MAX / 2) {
35 0 : bufsz *= 2;
36 0 : buf = malloc(bufsz);
37 : }
38 :
39 0 : if (!buf) {
40 0 : return (size_t) -1;
41 : }
42 : }
43 285275 : if (rv >= 0) {
44 285275 : rv = (int) (*gp->vtbl->Write)(gp, buf, rv);
45 : }
46 285275 : free(buf);
47 :
48 285275 : return rv;
49 : }
50 :
51 :
52 : size_t gprintf(struct Gio *gp,
53 275603 : char const *fmt, ...) {
54 : va_list ap;
55 : size_t rv;
56 :
57 275603 : va_start(ap, fmt);
58 275603 : rv = gvprintf(gp, fmt, ap);
59 275603 : va_end(ap);
60 :
61 275603 : return rv;
62 : }
|