aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/cat.c3
-rw-r--r--c/gbos.h1
-rw-r--r--c/head.c4
-rw-r--r--c/save.c2
-rw-r--r--c/wc.c4
-rw-r--r--src/fs.asm10
6 files changed, 18 insertions, 6 deletions
diff --git a/c/cat.c b/c/cat.c
index dde58cd..790cb88 100644
--- a/c/cat.c
+++ b/c/cat.c
@@ -6,7 +6,8 @@ void main(void) {
if (argc > 0) {
unsigned char fd = open(argv[0], O_READ);
int ch;
- if (fd == NOFD) { puts("cat: no such file"); nl(); return; }
+ if (fd == EISDIR) { puts("cat: is a directory"); nl(); return; }
+ if (fd == NOFD) { puts("cat: no such file"); nl(); return; }
while ((ch = fgetc(fd)) >= 0) putc((char)ch);
close(fd);
} else {
diff --git a/c/gbos.h b/c/gbos.h
index c93414f..2a99c0e 100644
--- a/c/gbos.h
+++ b/c/gbos.h
@@ -34,6 +34,7 @@ void poweroff(void); /* clean emulator shutdown (saves) */
#define O_READ 0
#define O_WRITE 1
#define NOFD 0xFF
+#define EISDIR 0xFE /* open() failed: path is a directory */
/* process control (c/libc.s) */
unsigned char fork(void);
diff --git a/c/head.c b/c/head.c
index e8bf846..3298e54 100644
--- a/c/head.c
+++ b/c/head.c
@@ -16,10 +16,10 @@ void main(void) {
}
if (fname) {
fd = open(fname, O_READ);
- if (fd == NOFD) { puts("head: no such file"); nl(); return; }
+ if (fd > 3) { puts("head: no such file"); nl(); return; }
}
for (;;) {
- if (fd == NOFD) { char c = readc(); if (c == EOF) break; ch = c; }
+ if (fd > 3) { char c = readc(); if (c == EOF) break; ch = c; }
else { ch = fgetc(fd); if (ch < 0) break; }
if (lines < n) putc((char)ch);
if (ch == '\n') lines++;
diff --git a/c/save.c b/c/save.c
index dd2b8cd..1755fea 100644
--- a/c/save.c
+++ b/c/save.c
@@ -7,7 +7,7 @@ void main(void) {
char c;
if (argc < 1) { puts("usage: save <name>"); nl(); return; }
fd = open(argv[0], O_WRITE);
- if (fd == NOFD) { puts("save: cannot create"); nl(); return; }
+ if (fd > 3) { puts("save: cannot create"); nl(); return; }
for (;;) {
c = readc();
if (c == EOF) break;
diff --git a/c/wc.c b/c/wc.c
index 424876d..4fa48ee 100644
--- a/c/wc.c
+++ b/c/wc.c
@@ -14,10 +14,10 @@ void main(void) {
for (i = 0; i < argc; i++) if (argv[i][0] != '-') { fname = argv[i]; break; }
if (fname) {
fd = open(fname, O_READ);
- if (fd == NOFD) { puts("wc: no such file"); nl(); return; }
+ if (fd > 3) { puts("wc: no such file"); nl(); return; }
}
for (;;) {
- if (fd == NOFD) { char c = readc(); if (c == EOF) break; ch = c; }
+ if (fd > 3) { char c = readc(); if (c == EOF) break; ch = c; }
else { ch = fgetc(fd); if (ch < 0) break; }
chars++;
if (ch == '\n') lines++;
diff --git a/src/fs.asm b/src/fs.asm
index d543b0f..a4ad77e 100644
--- a/src/fs.asm
+++ b/src/fs.asm
@@ -678,6 +678,13 @@ sys_open::
ld [wFsDir], a
call dir_find ; A = target inode or 0
ld [wFsInode], a
+ or a
+ jr z, .notdir ; doesn't exist yet: no type to check
+ call inode_ptr
+ ld a, [hl] ; I_TYPE
+ cp IT_DIR
+ jr z, .isdir ; can't open a directory as a file
+.notdir
ld a, [wFsMode]
or a
jr nz, .write
@@ -730,6 +737,9 @@ sys_open::
ld a, c
cp OF_MAX
jr c, .ofl
+.isdir
+ ld a, $FE ; EISDIR: is a directory
+ ret
.fail
ld a, $FF
ret