1 #include "stdio_impl.h"
12 static off_t
mseek(FILE *f
, off_t off
, int whence
)
15 struct cookie
*c
= f
->cookie
;
21 base
= (size_t [3]){0, c
->pos
, c
->len
}[whence
];
22 if (off
< -base
|| off
> (ssize_t
)c
->size
-base
) goto fail
;
23 return c
->pos
= base
+off
;
26 static size_t mread(FILE *f
, unsigned char *buf
, size_t len
)
28 struct cookie
*c
= f
->cookie
;
29 size_t rem
= c
->len
- c
->pos
;
30 if (c
->pos
> c
->len
) rem
= 0;
35 memcpy(buf
, c
->buf
+c
->pos
, len
);
38 if (rem
> f
->buf_size
) rem
= f
->buf_size
;
40 f
->rend
= f
->buf
+ rem
;
41 memcpy(f
->rpos
, c
->buf
+c
->pos
, rem
);
46 static size_t mwrite(FILE *f
, const unsigned char *buf
, size_t len
)
48 struct cookie
*c
= f
->cookie
;
50 size_t len2
= f
->wpos
- f
->wbase
;
53 if (mwrite(f
, f
->wpos
, len2
) < len2
) return 0;
55 if (c
->mode
== 'a') c
->pos
= c
->len
;
56 rem
= c
->size
- c
->pos
;
57 if (len
> rem
) len
= rem
;
58 memcpy(c
->buf
+c
->pos
, buf
, len
);
60 if (c
->pos
> c
->len
) {
62 if (c
->len
< c
->size
) c
->buf
[c
->len
] = 0;
63 else if ((f
->flags
&F_NORD
) && c
->size
) c
->buf
[c
->size
-1] = 0;
68 static int mclose(FILE *m
)
73 FILE *fmemopen(void *restrict buf
, size_t size
, const char *restrict mode
)
77 int plus
= !!strchr(mode
, '+');
79 if (!size
|| !strchr("rwa", *mode
)) {
84 if (!buf
&& size
> SIZE_MAX
-sizeof(FILE)-BUFSIZ
-UNGET
) {
89 f
= calloc(sizeof *f
+ sizeof *c
+ UNGET
+ BUFSIZ
+ (buf
?0:size
), 1);
91 f
->cookie
= c
= (void *)(f
+1);
94 f
->buf
= (unsigned char *)(c
+1) + UNGET
;
96 if (!buf
) buf
= f
->buf
+ BUFSIZ
;
102 if (!plus
) f
->flags
= (*mode
== 'r') ? F_NOWR
: F_NORD
;
103 if (*mode
== 'r') c
->len
= size
;
104 else if (*mode
== 'a') c
->len
= c
->pos
= strnlen(buf
, size
);
111 if (!libc
.threaded
) f
->lock
= -1;