From ccd2b2a1dc0b1d207fb738593845e9be8b6e1d80 Mon Sep 17 00:00:00 2001 From: Phil Burk Date: Sun, 22 Apr 2018 11:16:20 -0700 Subject: [PATCH] pforth: use long for off_t Check for attempt to use position values that are too large. Remove use of fseeko() and ftello(). --- csrc/pf_inner.c | 38 ++++++++++++++++++++++++++------------ csrc/pf_io.c | 2 +- csrc/pf_io.h | 21 +++++++++++++-------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/csrc/pf_inner.c b/csrc/pf_inner.c index e435d49..606dc5c 100644 --- a/csrc/pf_inner.c +++ b/csrc/pf_inner.c @@ -1062,12 +1062,20 @@ DBUG(("XX ah,m,l = 0x%8x,%8x,%8x - qh,l = 0x%8x,%8x\n", ah,am,al, qh,ql )); case ID_FILE_REPOSITION: /* ( ud fid -- ior ) */ { file_offset_t offset; + cell_t offsetHigh; + cell_t offsetLow; FileID = (FileStream *) TOS; - offset = M_POP; - /* Avoid compiler warnings on Mac. */ - offset = (sizeof(file_offset_t) > sizeof(cell_t)) - ? (offset << 8*sizeof(cell_t)) : 0 ; - offset += M_POP; + offsetHigh = M_POP; + offsetLow = M_POP; + /* We do not support double precision file offsets in pForth. + * So check to make sure the high bits are not used. + */ + if (offsetHigh != 0) + { + TOS = -3; /* TODO err num? */ + break; + } + offset = offsetLow; TOS = sdSeekFile( FileID, offset, PF_SEEK_SET ); } endcase; @@ -1075,15 +1083,21 @@ DBUG(("XX ah,m,l = 0x%8x,%8x,%8x - qh,l = 0x%8x,%8x\n", ah,am,al, qh,ql )); case ID_FILE_POSITION: /* ( fid -- ud ior ) */ { file_offset_t position; - file_offset_t offsetHi; FileID = (FileStream *) TOS; position = sdTellFile( FileID ); - M_PUSH(position); - /* Just use a 0 if they are the same size. */ - offsetHi = (sizeof(file_offset_t) > sizeof(cell_t)) - ? (position >> (8*sizeof(cell_t))) : 0 ; - M_PUSH(offsetHi); - TOS = (position < 0) ? -4 : 0 ; /* !!! err num */ + if (position < 0) + { + M_PUSH(0); /* low */ + M_PUSH(0); /* high */ + TOS = -4; /* TODO proper error number */ + } + else + { + M_PUSH(position); /* low */ + /* We do not support double precision file offsets.*/ + M_PUSH(0); /* high */ + TOS = 0; + } } endcase; diff --git a/csrc/pf_io.c b/csrc/pf_io.c index 3b48d0a..ea6f4b5 100644 --- a/csrc/pf_io.c +++ b/csrc/pf_io.c @@ -194,7 +194,7 @@ cell_t sdWriteFile( void *ptr, cell_t Size, int32_t nItems, FileStream * Stream TOUCH(Stream); return 0; } -cell_t sdSeekFile( FileStream * Stream, cell_t Position, int32_t Mode ) +cell_t sdSeekFile( FileStream * Stream, file_offset_t Position, int32_t Mode ) { UNIMPLEMENTED("sdSeekFile"); TOUCH(Stream); diff --git a/csrc/pf_io.h b/csrc/pf_io.h index 5217390..db8fd92 100644 --- a/csrc/pf_io.h +++ b/csrc/pf_io.h @@ -122,14 +122,18 @@ void ioTerm( void ); #define sdFlushFile fflush #define sdReadFile fread #define sdWriteFile fwrite - #if defined(WIN32) || defined(__NT__) || defined(AMIGA) - /* TODO To support 64-bit file offset we probably need fseeki64(). */ - #define sdSeekFile fseek - #define sdTellFile ftell - #else - #define sdSeekFile fseeko - #define sdTellFile ftello - #endif + + /* + * Note that fseek() and ftell() only support a long file offset. + * So 64-bit offsets may not be supported on some platforms. + * At one point we supported fseeko() and ftello() but they require + * the off_t data type, which is not very portable. + * So we decided to sacrifice vary large file support in + * favor of portability. + */ + #define sdSeekFile fseek + #define sdTellFile ftell + #define sdCloseFile fclose #define sdRenameFile rename #define sdInputChar fgetc @@ -141,6 +145,7 @@ void ioTerm( void ); #define PF_SEEK_CUR (SEEK_CUR) #define PF_SEEK_END (SEEK_END) + /* TODO review the Size data type. */ ThrowCode sdResizeFile( FileStream *, uint64_t Size); /* -- 2.20.1