summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-08-15 21:20:35 -0400
committerJakob Kaivo <jkk@ung.org>2020-08-15 21:20:35 -0400
commita8e42258fc1c84abc6536c5f80b7d2e72d72e54c (patch)
treee736dd77aa49481fe28ba6157eb3096518fd56e3
parentb72f8cea4376276a57281a31457b38fc24f6404f (diff)
make sensible
-rw-r--r--src/stdio/setvbuf.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/src/stdio/setvbuf.c b/src/stdio/setvbuf.c
index ecf038fd..c3aed354 100644
--- a/src/stdio/setvbuf.c
+++ b/src/stdio/setvbuf.c
@@ -1,36 +1,57 @@
#include <stdio.h>
-#include "stdlib.h"
+#include <errno.h>
+#include <stdlib.h>
#include "_stdio.h"
/** specify file stream buffering options **/
+
int setvbuf(FILE *stream, char *buf, int mode, size_t size)
{
- if (stream == NULL
- || !stream->isopen
- || stream->buftype != UNSET
- || (mode != _IOFBF && mode != _IOLBF && mode != _IONBF))
- {
- return 1;
+ flockfile(stream);
+
+ if (!f_is_open(stream)) {
+ #ifdef EBADF
+ errno = EBADF;
+ #endif
+
+ return -1;
}
- stream->buffering = mode;
- stream->bsize = size;
+ if (mode != _IOFBF && mode != _IOLBF && mode != _IONBF) {
+ #ifdef EINVAL
+ errno = EINVAL;
+ #endif
+
+ funlockfile(stream);
+ return -1;
+ }
if (mode == _IONBF) {
- /* maybe free buffer */
+ stream->bmode = mode;
+ funlockfile(stream);
return 0;
}
if (buf != NULL) {
stream->buf = buf;
- stream->buftype = SUPPLIED;
- } else if (size <= BUFSIZ) {
- stream->buf = stream->ibuf;
- stream->buftype = INTERNAL;
- } else {
- stream->buf = malloc(size);
- stream->buftype = ALLOCED;
+ } else if (size > stream->bsize) {
+ char *tmp = stream->buf;
+ if (tmp == stream->ibuf) {
+ tmp = NULL;
+ }
+
+ stream->buf = realloc(tmp, size);
+ if (stream->buf == NULL) {
+ stream->buf = tmp ? tmp : stream->ibuf;
+ funlockfile(stream);
+ return -1;
+ }
+
+ stream->ibuf[0] = 'a';
}
+
+ stream->bmode = mode;
+ stream->bsize = size;
return 0;
}