commit 66e334f5543b1b425aa0f34849357b970d6a746a
parent 1411e9231618c55fd39a970af79f3e99a593f7ba
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 9 Dec 2017 20:17:40 +0100
[lib/c] Add setbuf(), setbuffer(), setlinebuf() and setvbuf()
Again, it is only a work in progress.
Diffstat:
4 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/lib/c/include/stdio.h b/lib/c/include/stdio.h
@@ -116,11 +116,12 @@ extern int __putc(int, FILE *fp);
#define putc(c, fp) ((fp)->wp >= (fp)->rp ? __putc(c,fp) : (*(fp)->wp++ = c))
#endif
-#define ferror(fp) ((fp)->flags & _IOERR)
-#define feof(fp) ((fp)->flags & _IOEOF)
-#define clearerr(fp) (void) ((fp)->flags &= ~(_IOERR|_IOEOF))
-#define getchar() getc(stdin)
-#define putchar(c) putc((c), stdout)
+#define ferror(fp) ((fp)->flags & _IOERR)
+#define feof(fp) ((fp)->flags & _IOEOF)
+#define clearerr(fp) (void) ((fp)->flags &= ~(_IOERR|_IOEOF))
+#define getchar() getc(stdin)
+#define putchar(c) putc((c), stdout)
+#define setbuf(fp, b) (void) setvbuf(fp, b, b ? _IOFBF:_IONBF, BUFSIZ)
#endif
#endif
diff --git a/lib/c/src/Makefile b/lib/c/src/Makefile
@@ -10,6 +10,7 @@ OBJ = bsearch.o qsort.o \
fputs.o puts.o fread.o fwrite.o \
getc.o putc.o __putc.o __getc.o \
rewind.o fseek.o ferror.o feof.o clearerr.o \
+ setbuf.o setvbuf.o \
fclose.o fopen.c freopen.c _fpopen.o stdio.o \
realloc.o calloc.o malloc.o \
assert.o strcpy.o strcmp.o strlen.o strchr.o \
diff --git a/lib/c/src/setbuf.c b/lib/c/src/setbuf.c
@@ -0,0 +1,9 @@
+
+#include <stdio.h>
+#undef setbuf
+
+void
+setbuf(FILE * restrict fp, char * restrict buf)
+{
+ setvbuf(fp, buf, (buf) ? _IOFBF : _IONBF, BUFSIZ);
+}
diff --git a/lib/c/src/setvbuf.c b/lib/c/src/setvbuf.c
@@ -0,0 +1,44 @@
+
+#include <errno.h>
+#include <stdio.h>
+#undef setvbuf
+
+int
+setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size)
+{
+ int flags, r;
+
+ if (fflush(fp) == EOF)
+ return EOF;
+
+ switch (mode) {
+ case _IONBF:
+ size = sizeof(fp->unbuf);
+ buf = fp->unbuf;
+ break;
+ case _IOLBF:
+ case _IOFBF:
+ if (size == 0) {
+ if ((buf = malloc(BUFSIZ)) == NULL) {
+ errno = ENOMEM;
+ return EOF;
+ }
+ size = BUFSIZ;
+ }
+ break;
+ default:
+ errno = EIVAL;
+ return EOF;
+ }
+
+ flags = fp->flags;
+ if (flags & _IOALLOC)
+ free(fp->buf);
+ flag &= ~(_IONBF | _IOLBF | _IOFBF | _IOALLOC | _IOALLOC);
+ flags |= mode;
+ fp->flags = flags;
+ fp->buf = buf;
+ fp->size = size;
+
+ return 0;
+}