ref: 2d455f13954cd94ae98ed346bb7da23d579ad6d7
parent: 22f5e45998b00a0e48eb69282ab2c9a247defd13
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Dec 6 10:17:32 EST 2017
[lib/c] Add putc() and getc()
--- a/lib/c/include/errno.h
+++ b/lib/c/include/errno.h
@@ -4,7 +4,8 @@
#define EDOM 1
#define EILSEQ 2
#define ERANGE 3
-#define ENOMEN 4
+#define ENOMEM 4
+#define EBADF 5
extern int errno;
--- a/lib/c/src/Makefile
+++ b/lib/c/src/Makefile
@@ -7,6 +7,7 @@
printf.o fprintf.o vfprintf.o \
fgets.o gets.of fgetc.o fputc.o getchar.o putchar.o \
fputs.o puts.o fread.o fwrite.o \
+ getc.o putc.o __putc.o __getc.o \
realloc.o calloc.o malloc.o \
assert.o strcpy.o strcmp.o strlen.o strchr.o \
strrchr.o strcat.o strncmp.o strncpy.o strncat.o strcoll.o \
--- /dev/null
+++ b/lib/c/src/__getc.c
@@ -1,0 +1,36 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include "syscall.h"
+#undef getc
+
+int
+__getc(FILE *fp)
+{
+ int cnt;
+
+ if (fp->flags & (_IOEOF | _IOERR))
+ return EOF;
+
+ if ((fp->flags & (_IOREAD | _IORW)) == 0) {
+ fp->flags |= _IOERR;
+ errno = EBADF;
+ return EOF;
+ }
+
+ if (fp->flags & _IOSTRG) {
+ fp->flags |= _IOEOF;
+ return EOF;
+ }
+
+ if ((cnt = _read(fp->fd, fp->buf, fp->len)) <= 0) {
+ fp->flags |= (cnt == 0) ? _IOEOF : _IOERR;
+ return EOF;
+ }
+
+ fp->flags |= _IOREAD;
+ fp->rp = fp->buf;
+ fp->wp = fp->buf + cnt;
+
+ return *fp->rp++;
+}
--- /dev/null
+++ b/lib/c/src/__putc.c
@@ -1,0 +1,88 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "syscall.h"
+
+int
+_fflush(FILE *fp)
+{
+ int lnbuf = fp->flags & _IOLBF;
+ size_t cnt;
+
+ cnt = ((lnbuf) ? fp->lp : fp->wp) - fp->buf;
+
+ if (_write(fp->fd, fp->buf, cnt) != cnt) {
+ fp->flags |= _IOERR;
+ return EOF;
+ }
+ fp->rp = fp->wp = fp->buf;
+
+ return 0;
+}
+
+int
+fflush(FILE *fp)
+{
+ int err = 0;
+
+ if (fp)
+ return _flsbuf(fp);
+
+ for (fp = __iob; fp < &__iob[FOPEN_MAX]; ++fp) {
+ if ((fp->flags & _IOWRITE) == 0 && _flush(fp))
+ err = EOF;
+ }
+ return err;
+}
+
+static void
+cleanup(void)
+{
+ fflush(NULL);
+}
+
+int
+__putc(int ch, FILE *fp)
+{
+ static int first = 1;
+
+ if (fp->flags & _IOERR)
+ return EOF;
+
+ if (fp->flags & _IOREAD) {
+ fp->flags |= _IOERR;
+ errno = EBADF;
+ return EOF;
+ }
+
+ if (fp->flags & _IOSTRG) {
+ fp->flags |= _IOERR;
+ return EOF;
+ }
+
+ if (first) {
+ if (atexit(cleanup)) {
+ fp->flags |= _IOERR;
+ errno = ENOMEM;
+ return EOF;
+ }
+ first = 0;
+ }
+
+ if (fp->flags & _IOLBF) {
+ if (fp->lp == fp->rp && _flush(fp))
+ return EOF;
+ *fp->lp++ = ch;
+ if (ch == '\n' && flsbuf(fp))
+ return EOF;
+ } else {
+ if (fp->wp == fp->rp && _flsbuf(fp))
+ return EOF;
+ *fp->wp++ = ch;
+ }
+
+done:
+ fp->flags |= _IOWRITE;
+ return ch & 0xFF;
+}
--- /dev/null
+++ b/lib/c/src/getc.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef getc
+
+int
+getc(FILE *fp)
+{
+ return (fp->rp >= fp->wp) ? __getc(fp) : *fp->rp++;
+}
--- /dev/null
+++ b/lib/c/src/putc.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef putc
+
+int
+putc(int ch, FILE *fp)
+{
+ return (fp->wp >= fp->rp) ? __putc(c,fp) : *fp->wp++ = c;
+}