New function _dirskip that allows to skip an amount of bytes from the
directory with error check. git-svn-id: svn://svn.cc65.org/cc65/trunk@5668 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -65,6 +65,7 @@ S_OBJS = c_acptr.o \
|
|||||||
closedir.o \
|
closedir.o \
|
||||||
ctype.o \
|
ctype.o \
|
||||||
cvline.o \
|
cvline.o \
|
||||||
|
dir.o \
|
||||||
diskcmd.o \
|
diskcmd.o \
|
||||||
exehdr.o \
|
exehdr.o \
|
||||||
filedes.o \
|
filedes.o \
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Internal include file, do not use directly.
|
* Internal include file, do not use directly.
|
||||||
* Written by Ullrich von Bassewitz. Based on code by Groepaz.
|
* Written by Ullrich von Bassewitz. Based on code by Groepaz.
|
||||||
*/
|
*/
|
||||||
@@ -24,6 +24,22 @@ struct DIR {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char __fastcall__ _dirskip (unsigned char count, struct DIR* dir);
|
||||||
|
/* Skip bytes from the directory and make sure, errno is set if this isn't
|
||||||
|
* possible. Return true if anything is ok and false otherwise. For
|
||||||
|
* simplicity we assume that read will never return less than count if there
|
||||||
|
* is no error and end-of-file is not reached.
|
||||||
|
* Note: count must not be more than 254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of dir.h */
|
/* End of dir.h */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -23,5 +23,5 @@
|
|||||||
.global _readdir
|
.global _readdir
|
||||||
.global _telldir
|
.global _telldir
|
||||||
.global _rewinddir
|
.global _rewinddir
|
||||||
|
.global __dirskip
|
||||||
|
|
||||||
|
|||||||
92
libsrc/cbm/dir.s
Normal file
92
libsrc/cbm/dir.s
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 2012-06-01
|
||||||
|
;
|
||||||
|
; unsigned char __fastcall__ _dirskip (unsigned char count, struct DIR* dir);
|
||||||
|
; /* Skip bytes from the directory and make sure, errno is set if this isn't
|
||||||
|
; * possible. Return true if anything is ok and false otherwise. For
|
||||||
|
; * simplicity we assume that read will never return less than count if there
|
||||||
|
; * is no error and end-of-file is not reached.
|
||||||
|
; * Note: count must not be more than 254.
|
||||||
|
; */
|
||||||
|
;
|
||||||
|
|
||||||
|
.include "dir.inc"
|
||||||
|
.include "errno.inc"
|
||||||
|
.include "zeropage.inc"
|
||||||
|
|
||||||
|
.import _read
|
||||||
|
.import pushax, pushptr1idx
|
||||||
|
.import subysp, addysp1
|
||||||
|
|
||||||
|
|
||||||
|
.proc __dirskip
|
||||||
|
|
||||||
|
sta ptr1
|
||||||
|
stx ptr1+1 ; Save dir
|
||||||
|
|
||||||
|
; Get count and allocate space on the stack
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
lda (sp),y
|
||||||
|
pha
|
||||||
|
tay
|
||||||
|
jsr subysp
|
||||||
|
|
||||||
|
; Save current value of sp
|
||||||
|
|
||||||
|
lda sp
|
||||||
|
pha
|
||||||
|
lda sp+1
|
||||||
|
pha
|
||||||
|
|
||||||
|
; Push dir->fd
|
||||||
|
|
||||||
|
ldy #DIR::fd+1
|
||||||
|
jsr pushptr1idx
|
||||||
|
|
||||||
|
; Push pointer to buffer
|
||||||
|
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
pla
|
||||||
|
jsr pushax
|
||||||
|
|
||||||
|
; Load count and call read
|
||||||
|
|
||||||
|
pla
|
||||||
|
pha
|
||||||
|
ldx #0
|
||||||
|
jsr _read
|
||||||
|
|
||||||
|
; Check for errors. In case of errors, errno is already set.
|
||||||
|
|
||||||
|
cpx #$FF
|
||||||
|
bne L2
|
||||||
|
|
||||||
|
; read() returned an error
|
||||||
|
|
||||||
|
pla ; Count
|
||||||
|
tay
|
||||||
|
lda #0
|
||||||
|
tax
|
||||||
|
L1: jmp addysp1 ; Drop buffer plus count
|
||||||
|
|
||||||
|
; read() was successful, check number of bytes read. We assume that read will
|
||||||
|
; not return more than count, so X is zero if we come here.
|
||||||
|
|
||||||
|
L2: sta tmp1
|
||||||
|
pla ; count
|
||||||
|
tay
|
||||||
|
cmp tmp1
|
||||||
|
beq L1 ; Drop variables, return count
|
||||||
|
|
||||||
|
; Didn't read enough bytes. This is an error for us, but errno is not set
|
||||||
|
|
||||||
|
lda #<EIO
|
||||||
|
sta __errno
|
||||||
|
stx __errno+1
|
||||||
|
txa ; A=X=0
|
||||||
|
beq L1 ; Branch always
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Ullrich von Bassewitz, 2012-05-30. Based on code by Groepaz.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@@ -10,10 +14,8 @@
|
|||||||
|
|
||||||
DIR* __fastcall__ opendir (const char*)
|
DIR* __fastcall__ opendir (const char*)
|
||||||
{
|
{
|
||||||
unsigned char buffer[8+16+1+7];
|
|
||||||
int count;
|
|
||||||
DIR d;
|
|
||||||
DIR* dir = 0;
|
DIR* dir = 0;
|
||||||
|
DIR d;
|
||||||
|
|
||||||
/* Setup file name and offset */
|
/* Setup file name and offset */
|
||||||
d.name[0] = '$';
|
d.name[0] = '$';
|
||||||
@@ -25,8 +27,7 @@ DIR* __fastcall__ opendir (const char*)
|
|||||||
if (d.fd >= 0) {
|
if (d.fd >= 0) {
|
||||||
|
|
||||||
/* Skip the disk header */
|
/* Skip the disk header */
|
||||||
count = read (d.fd, buffer, sizeof (buffer));
|
if (_dirskip (32, &d)) {
|
||||||
if (count == sizeof (buffer)) {
|
|
||||||
|
|
||||||
/* Allocate memory for the DIR structure returned */
|
/* Allocate memory for the DIR structure returned */
|
||||||
dir = malloc (sizeof (*dir));
|
dir = malloc (sizeof (*dir));
|
||||||
@@ -38,9 +39,6 @@ DIR* __fastcall__ opendir (const char*)
|
|||||||
/* Set an appropriate error code */
|
/* Set an appropriate error code */
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
}
|
}
|
||||||
} else if (count >= 0) {
|
|
||||||
/* Short read - need to set an error code */
|
|
||||||
errno = EIO;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user