OLD | NEW |
1 #include "stdio_impl.h" | 1 #include "stdio_impl.h" |
2 #include <errno.h> | 2 #include <errno.h> |
3 #include <limits.h> | 3 #include <limits.h> |
4 #include <string.h> | 4 #include <string.h> |
5 | 5 |
6 struct cookie { | 6 struct cookie { |
7 » char **bufp; | 7 char** bufp; |
8 » size_t *sizep; | 8 size_t* sizep; |
9 » size_t pos; | 9 size_t pos; |
10 » char *buf; | 10 char* buf; |
11 » size_t len; | 11 size_t len; |
12 » size_t space; | 12 size_t space; |
13 }; | 13 }; |
14 | 14 |
15 static off_t ms_seek(FILE *f, off_t off, int whence) | 15 static off_t ms_seek(FILE* f, off_t off, int whence) { |
16 { | 16 ssize_t base; |
17 » ssize_t base; | 17 struct cookie* c = f->cookie; |
18 » struct cookie *c = f->cookie; | 18 if (whence > 2U) { |
19 » if (whence>2U) { | 19 fail: |
20 fail: | 20 errno = EINVAL; |
21 » » errno = EINVAL; | 21 return -1; |
22 » » return -1; | 22 } |
23 » } | 23 base = (size_t[3]){0, c->pos, c->len}[whence]; |
24 » base = (size_t [3]){0, c->pos, c->len}[whence]; | 24 if (off < -base || off > SSIZE_MAX - base) |
25 » if (off < -base || off > SSIZE_MAX-base) goto fail; | 25 goto fail; |
26 » return c->pos = base+off; | 26 return c->pos = base + off; |
27 } | 27 } |
28 | 28 |
29 static size_t ms_write(FILE *f, const unsigned char *buf, size_t len) | 29 static size_t ms_write(FILE* f, const unsigned char* buf, size_t len) { |
30 { | 30 struct cookie* c = f->cookie; |
31 » struct cookie *c = f->cookie; | 31 size_t len2 = f->wpos - f->wbase; |
32 » size_t len2 = f->wpos - f->wbase; | 32 char* newbuf; |
33 » char *newbuf; | 33 if (len2) { |
34 » if (len2) { | 34 f->wpos = f->wbase; |
35 » » f->wpos = f->wbase; | 35 if (ms_write(f, f->wbase, len2) < len2) |
36 » » if (ms_write(f, f->wbase, len2) < len2) return 0; | 36 return 0; |
37 » } | 37 } |
38 » if (len + c->pos >= c->space) { | 38 if (len + c->pos >= c->space) { |
39 » » len2 = 2*c->space+1 | c->pos+len+1; | 39 len2 = 2 * c->space + 1 | c->pos + len + 1; |
40 » » newbuf = realloc(c->buf, len2); | 40 newbuf = realloc(c->buf, len2); |
41 » » if (!newbuf) return 0; | 41 if (!newbuf) |
42 » » *c->bufp = c->buf = newbuf; | 42 return 0; |
43 » » memset(c->buf + c->space, 0, len2 - c->space); | 43 *c->bufp = c->buf = newbuf; |
44 » » c->space = len2; | 44 memset(c->buf + c->space, 0, len2 - c->space); |
45 » } | 45 c->space = len2; |
46 » memcpy(c->buf+c->pos, buf, len); | 46 } |
47 » c->pos += len; | 47 memcpy(c->buf + c->pos, buf, len); |
48 » if (c->pos >= c->len) c->len = c->pos; | 48 c->pos += len; |
49 » *c->sizep = c->pos; | 49 if (c->pos >= c->len) |
50 » return len; | 50 c->len = c->pos; |
| 51 *c->sizep = c->pos; |
| 52 return len; |
51 } | 53 } |
52 | 54 |
53 static int ms_close(FILE *f) | 55 static int ms_close(FILE* f) { |
54 { | 56 return 0; |
55 » return 0; | |
56 } | 57 } |
57 | 58 |
58 FILE *open_memstream(char **bufp, size_t *sizep) | 59 FILE* open_memstream(char** bufp, size_t* sizep) { |
59 { | 60 FILE* f; |
60 » FILE *f; | 61 struct cookie* c; |
61 » struct cookie *c; | 62 char* buf; |
62 » char *buf; | |
63 | 63 |
64 » if (!(f=malloc(sizeof *f + sizeof *c + BUFSIZ))) return 0; | 64 if (!(f = malloc(sizeof *f + sizeof *c + BUFSIZ))) |
65 » if (!(buf=malloc(sizeof *buf))) { | 65 return 0; |
66 » » free(f); | 66 if (!(buf = malloc(sizeof *buf))) { |
67 » » return 0; | 67 free(f); |
68 » } | 68 return 0; |
69 » memset(f, 0, sizeof *f + sizeof *c); | 69 } |
70 » f->cookie = c = (void *)(f+1); | 70 memset(f, 0, sizeof *f + sizeof *c); |
| 71 f->cookie = c = (void*)(f + 1); |
71 | 72 |
72 » c->bufp = bufp; | 73 c->bufp = bufp; |
73 » c->sizep = sizep; | 74 c->sizep = sizep; |
74 » c->pos = c->len = c->space = *sizep = 0; | 75 c->pos = c->len = c->space = *sizep = 0; |
75 » c->buf = *bufp = buf; | 76 c->buf = *bufp = buf; |
76 » *buf = 0; | 77 *buf = 0; |
77 | 78 |
78 » f->flags = F_NORD; | 79 f->flags = F_NORD; |
79 » f->fd = -1; | 80 f->fd = -1; |
80 » f->buf = (void *)(c+1); | 81 f->buf = (void*)(c + 1); |
81 » f->buf_size = BUFSIZ; | 82 f->buf_size = BUFSIZ; |
82 » f->lbf = EOF; | 83 f->lbf = EOF; |
83 » f->write = ms_write; | 84 f->write = ms_write; |
84 » f->seek = ms_seek; | 85 f->seek = ms_seek; |
85 » f->close = ms_close; | 86 f->close = ms_close; |
86 | 87 |
87 » if (!libc.threaded) f->lock = -1; | 88 if (!libc.threaded) |
| 89 f->lock = -1; |
88 | 90 |
89 » return __ofl_add(f); | 91 return __ofl_add(f); |
90 } | 92 } |
OLD | NEW |