From bfd18a52e1baa4da7040b8df04a3f29e83b0d6b6 Mon Sep 17 00:00:00 2001 From: zlg Date: Sun, 9 Jan 2022 20:18:52 -0800 Subject: Solve Exercise 8-4: fseek() implementation --- ch8/syscalls.h | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'ch8/syscalls.h') diff --git a/ch8/syscalls.h b/ch8/syscalls.h index ff58db5..cda913f 100644 --- a/ch8/syscalls.h +++ b/ch8/syscalls.h @@ -66,7 +66,7 @@ int fempty(struct _flags flags) { FILE * fopen(char *name, char *mode) { int fd; FILE *fp; - if (*mode != 'r' && *mode != 'w' && *mode != 'a') { + if (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != '+') { return NULL; } for (fp = _iob; fp < _iob + FOPEN_MAX; fp++) { @@ -77,24 +77,34 @@ FILE * fopen(char *name, char *mode) { if (fp >= _iob + FOPEN_MAX) { return NULL; } - if (*mode == 'w') { - fd = creat(name, PERMS); - } else if (*mode == 'a') { - if ((fd = open(name, O_WRONLY, 0)) == -1) { + switch (*mode) { + case '+': + if ((fd = open(name, O_RDWR, 0)) == -1) { + fd = creat(name, PERMS); + } + break; + case 'w': fd = creat(name, PERMS); - } - lseek(fd, 0L, 2); - } else { - fd = open(name, O_RDONLY, 0); + break; + case 'a': + if ((fd = open(name, O_WRONLY, 0)) == -1) { + fd = creat(name, PERMS); + } + lseek(fd, 0L, 2); + break; + default: + fd = open(name, O_RDONLY, 0); } if (fd == -1) { return NULL; } fp->fd = fd; fp->cnt = 0; - if (*mode == 'r') { + fp->flags._EOF = 0; + if (*mode == 'r' || *mode == '+') { fp->flags._READ = 1; - } else { + } + if (*mode == 'w' || *mode == '+' || *mode == 'a') { fp->flags._WRITE = 1; } return fp; @@ -220,3 +230,16 @@ int puts(char *s) { putchar('\n'); return i; } + +/* Set the 'cursor' position within a file for read or write operations + * Returns 0 on success, EOF on error, with errno set. + */ +int fseek(FILE *fp, long offset, int origin) { + long pos; + if ((pos = lseek(fp->fd, offset, origin)) == EOF) { + return EOF; + } + _fillbuf(fp); + lseek(fp->fd, offset, origin); + return 0; +} -- cgit v1.2.3-54-g00ecf