aboutsummaryrefslogtreecommitdiff
path: root/ch8/syscalls.h
diff options
context:
space:
mode:
authorzlg <zlg@zlg.space>2022-01-09 20:18:52 -0800
committerzlg <zlg@zlg.space>2022-01-09 20:18:52 -0800
commitbfd18a52e1baa4da7040b8df04a3f29e83b0d6b6 (patch)
tree37cd17530ef47fff106c0a30fb26fe70cca429d8 /ch8/syscalls.h
parentSolve exercise 8-3: fflush and fclose (diff)
downloadknr-bfd18a52e1baa4da7040b8df04a3f29e83b0d6b6.tar.gz
knr-bfd18a52e1baa4da7040b8df04a3f29e83b0d6b6.tar.bz2
knr-bfd18a52e1baa4da7040b8df04a3f29e83b0d6b6.tar.xz
knr-bfd18a52e1baa4da7040b8df04a3f29e83b0d6b6.zip
Solve Exercise 8-4: fseek() implementation
Diffstat (limited to '')
-rw-r--r--ch8/syscalls.h45
1 files changed, 34 insertions, 11 deletions
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;
+}