| OLD | NEW |
| 1 #include "stdio_impl.h" | 1 #include "stdio_impl.h" |
| 2 #include <errno.h> | 2 #include <errno.h> |
| 3 #include <string.h> | 3 #include <string.h> |
| 4 #include <inttypes.h> | 4 #include <inttypes.h> |
| 5 | 5 |
| 6 struct cookie { | 6 struct cookie { |
| 7 » size_t pos, len, size; | 7 size_t pos, len, size; |
| 8 » unsigned char *buf; | 8 unsigned char* buf; |
| 9 » int mode; | 9 int mode; |
| 10 }; | 10 }; |
| 11 | 11 |
| 12 static off_t mseek(FILE *f, off_t off, int whence) | 12 static off_t mseek(FILE* f, off_t off, int whence) { |
| 13 { | 13 ssize_t base; |
| 14 » ssize_t base; | 14 struct cookie* c = f->cookie; |
| 15 » struct cookie *c = f->cookie; | 15 if (whence > 2U) { |
| 16 » if (whence>2U) { | 16 fail: |
| 17 fail: | 17 errno = EINVAL; |
| 18 » » errno = EINVAL; | 18 return -1; |
| 19 » » return -1; | 19 } |
| 20 » } | 20 base = (size_t[3]){0, c->pos, c->len}[whence]; |
| 21 » base = (size_t [3]){0, c->pos, c->len}[whence]; | 21 if (off < -base || off > (ssize_t)c->size - base) |
| 22 » if (off < -base || off > (ssize_t)c->size-base) goto fail; | 22 goto fail; |
| 23 » return c->pos = base+off; | 23 return c->pos = base + off; |
| 24 } | 24 } |
| 25 | 25 |
| 26 static size_t mread(FILE *f, unsigned char *buf, size_t len) | 26 static size_t mread(FILE* f, unsigned char* buf, size_t len) { |
| 27 { | 27 struct cookie* c = f->cookie; |
| 28 » struct cookie *c = f->cookie; | 28 size_t rem = c->len - c->pos; |
| 29 » size_t rem = c->len - c->pos; | 29 if (c->pos > c->len) |
| 30 » if (c->pos > c->len) rem = 0; | 30 rem = 0; |
| 31 » if (len > rem) { | 31 if (len > rem) { |
| 32 » » len = rem; | 32 len = rem; |
| 33 » » f->flags |= F_EOF; | 33 f->flags |= F_EOF; |
| 34 » } | 34 } |
| 35 » memcpy(buf, c->buf+c->pos, len); | 35 memcpy(buf, c->buf + c->pos, len); |
| 36 » c->pos += len; | 36 c->pos += len; |
| 37 » rem -= len; | 37 rem -= len; |
| 38 » if (rem > f->buf_size) rem = f->buf_size; | 38 if (rem > f->buf_size) |
| 39 » f->rpos = f->buf; | 39 rem = f->buf_size; |
| 40 » f->rend = f->buf + rem; | 40 f->rpos = f->buf; |
| 41 » memcpy(f->rpos, c->buf+c->pos, rem); | 41 f->rend = f->buf + rem; |
| 42 » c->pos += rem; | 42 memcpy(f->rpos, c->buf + c->pos, rem); |
| 43 » return len; | 43 c->pos += rem; |
| 44 return len; |
| 44 } | 45 } |
| 45 | 46 |
| 46 static size_t mwrite(FILE *f, const unsigned char *buf, size_t len) | 47 static size_t mwrite(FILE* f, const unsigned char* buf, size_t len) { |
| 47 { | 48 struct cookie* c = f->cookie; |
| 48 » struct cookie *c = f->cookie; | 49 size_t rem; |
| 49 » size_t rem; | 50 size_t len2 = f->wpos - f->wbase; |
| 50 » size_t len2 = f->wpos - f->wbase; | 51 if (len2) { |
| 51 » if (len2) { | 52 f->wpos = f->wbase; |
| 52 » » f->wpos = f->wbase; | 53 if (mwrite(f, f->wpos, len2) < len2) |
| 53 » » if (mwrite(f, f->wpos, len2) < len2) return 0; | 54 return 0; |
| 54 » } | 55 } |
| 55 » if (c->mode == 'a') c->pos = c->len; | 56 if (c->mode == 'a') |
| 56 » rem = c->size - c->pos; | 57 c->pos = c->len; |
| 57 » if (len > rem) len = rem; | 58 rem = c->size - c->pos; |
| 58 » memcpy(c->buf+c->pos, buf, len); | 59 if (len > rem) |
| 59 » c->pos += len; | 60 len = rem; |
| 60 » if (c->pos > c->len) { | 61 memcpy(c->buf + c->pos, buf, len); |
| 61 » » c->len = c->pos; | 62 c->pos += len; |
| 62 » » if (c->len < c->size) c->buf[c->len] = 0; | 63 if (c->pos > c->len) { |
| 63 » » else if ((f->flags&F_NORD) && c->size) c->buf[c->size-1] = 0; | 64 c->len = c->pos; |
| 64 » } | 65 if (c->len < c->size) |
| 65 » return len; | 66 c->buf[c->len] = 0; |
| 67 else if ((f->flags & F_NORD) && c->size) |
| 68 c->buf[c->size - 1] = 0; |
| 69 } |
| 70 return len; |
| 66 } | 71 } |
| 67 | 72 |
| 68 static int mclose(FILE *m) | 73 static int mclose(FILE* m) { |
| 69 { | 74 return 0; |
| 70 » return 0; | |
| 71 } | 75 } |
| 72 | 76 |
| 73 FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode) | 77 FILE* fmemopen(void* restrict buf, size_t size, const char* restrict mode) { |
| 74 { | 78 FILE* f; |
| 75 » FILE *f; | 79 struct cookie* c; |
| 76 » struct cookie *c; | 80 int plus = !!strchr(mode, '+'); |
| 77 » int plus = !!strchr(mode, '+'); | |
| 78 » | |
| 79 » if (!size || !strchr("rwa", *mode)) { | |
| 80 » » errno = EINVAL; | |
| 81 » » return 0; | |
| 82 » } | |
| 83 | 81 |
| 84 » if (!buf && size > SIZE_MAX-sizeof(FILE)-BUFSIZ-UNGET) { | 82 if (!size || !strchr("rwa", *mode)) { |
| 85 » » errno = ENOMEM; | 83 errno = EINVAL; |
| 86 » » return 0; | 84 return 0; |
| 87 » } | 85 } |
| 88 | 86 |
| 89 » f = calloc(sizeof *f + sizeof *c + UNGET + BUFSIZ + (buf?0:size), 1); | 87 if (!buf && size > SIZE_MAX - sizeof(FILE) - BUFSIZ - UNGET) { |
| 90 » if (!f) return 0; | 88 errno = ENOMEM; |
| 91 » f->cookie = c = (void *)(f+1); | 89 return 0; |
| 92 » f->fd = -1; | 90 } |
| 93 » f->lbf = EOF; | |
| 94 » f->buf = (unsigned char *)(c+1) + UNGET; | |
| 95 » f->buf_size = BUFSIZ; | |
| 96 » if (!buf) buf = f->buf + BUFSIZ; | |
| 97 | 91 |
| 98 » c->buf = buf; | 92 f = calloc(sizeof *f + sizeof *c + UNGET + BUFSIZ + (buf ? 0 : size), 1); |
| 99 » c->size = size; | 93 if (!f) |
| 100 » c->mode = *mode; | 94 return 0; |
| 101 » | 95 f->cookie = c = (void*)(f + 1); |
| 102 » if (!plus) f->flags = (*mode == 'r') ? F_NOWR : F_NORD; | 96 f->fd = -1; |
| 103 » if (*mode == 'r') c->len = size; | 97 f->lbf = EOF; |
| 104 » else if (*mode == 'a') c->len = c->pos = strnlen(buf, size); | 98 f->buf = (unsigned char*)(c + 1) + UNGET; |
| 99 f->buf_size = BUFSIZ; |
| 100 if (!buf) |
| 101 buf = f->buf + BUFSIZ; |
| 105 | 102 |
| 106 » f->read = mread; | 103 c->buf = buf; |
| 107 » f->write = mwrite; | 104 c->size = size; |
| 108 » f->seek = mseek; | 105 c->mode = *mode; |
| 109 » f->close = mclose; | |
| 110 | 106 |
| 111 » if (!libc.threaded) f->lock = -1; | 107 if (!plus) |
| 108 f->flags = (*mode == 'r') ? F_NOWR : F_NORD; |
| 109 if (*mode == 'r') |
| 110 c->len = size; |
| 111 else if (*mode == 'a') |
| 112 c->len = c->pos = strnlen(buf, size); |
| 112 | 113 |
| 113 » return __ofl_add(f); | 114 f->read = mread; |
| 115 f->write = mwrite; |
| 116 f->seek = mseek; |
| 117 f->close = mclose; |
| 118 |
| 119 if (!libc.threaded) |
| 120 f->lock = -1; |
| 121 |
| 122 return __ofl_add(f); |
| 114 } | 123 } |
| OLD | NEW |