diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/LIB.status | 7 | ||||
-rw-r--r-- | libc/include/stdio.h | 44 | ||||
-rw-r--r-- | libc/include/unistd.h | 1 |
3 files changed, 43 insertions, 9 deletions
diff --git a/libc/LIB.status b/libc/LIB.status index bd8fcf0..43cc8de 100644 --- a/libc/LIB.status +++ b/libc/LIB.status @@ -92,14 +92,15 @@ getline - missing, gnu replacement to gets ungetc - missing, won't implement, as we don't bufferize at all. fread - ok, inlined fwrite - ok, inlined -fseek - missing -ftell - missing +fseek - ok, inlined +ftell - ok, inlined rewind - missing fgetpos - missing fsetpos - missing clearerr - missing -feof - missing +feof - ok, inlined ferror - missing +fileno - ok, inlined perror - missing fileno - missing diff --git a/libc/include/stdio.h b/libc/include/stdio.h index a99fd42..a2655ea 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -11,6 +11,7 @@ static const int EOF = -1; struct _FILE { int fd; + int got_eof; }; typedef struct _FILE FILE; @@ -103,6 +104,7 @@ static inline FILE * fopen(const char * fname, const char * mode) { if (fd >= 0) { r = (FILE *) malloc(sizeof(FILE)); r->fd = fd; + r->got_eof = 0; } return r; @@ -126,21 +128,32 @@ static inline int fclose(FILE * stream) { static inline size_t fread(void * _ptr, size_t size, size_t nmemb, FILE * stream) { int i; uint8_t * ptr = (uint8_t *) _ptr; + size_t r; if (!stream) { _impure_ptr->_errno = EINVAL; return -1; } - if (size == 1) - return read(stream->fd, ptr, nmemb); + if (size == 1) { + r = read(stream->fd, ptr, nmemb); + if (r == 0) + stream->got_eof = 1; + return r; + } - if (nmemb == 1) - return read(stream->fd, ptr, size) == size ? 1 : 0; + if (nmemb == 1) { + r = read(stream->fd, ptr, size) == size ? 1 : 0; + if (r == 0) + stream->got_eof = 1; + return r; + } for (i = 0; i < nmemb; i++) { - if (read(stream->fd, ptr + size * i, size) != size) + if (read(stream->fd, ptr + size * i, size) != size) { + stream->got_eof = 1; return i; + } } return nmemb; @@ -177,11 +190,30 @@ static inline int fgetc(FILE * stream) { return -1; } - if (read(stream->fd, &v, 1) != 1) + if (read(stream->fd, &v, 1) != 1) { + stream->got_eof = 1; return EOF; + } return v; } +static inline int fseek(FILE * stream, off_t offset, int wheel) { + int r; + if (!stream) { + _impure_ptr->_errno = EINVAL; + return -1; + } + + r = lseek(stream->fd, offset, wheel) != -1 ? 0 : -1; + if (!r) + stream->got_eof = 0; + return r; +} + static inline int getc() { return fgetc(stdin); } +static inline off_t ftell(FILE * stream) { return lseek(stream->fd, 0, SEEK_CUR); } +static inline int feof(FILE * stream) { return stream->got_eof; } +static inline int fileno(FILE * stream) { return stream->fd; } +static inline void rewind(FILE * stream) { fseek(stream, 0, SEEK_SET); } #endif diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 8efd838..0b009f8 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -27,5 +27,6 @@ int open(const char *pathname, int flags); int close(int fd); ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); +off_t lseek(int fd, off_t seek, int wheel); #endif |