--- a/FileStream.st Thu Apr 03 14:59:44 2014 +0200
+++ b/FileStream.st Thu Apr 03 15:03:29 2014 +0200
@@ -9,6 +9,7 @@
other person. No title to or ownership of the software is
hereby transferred.
"
+
"{ Package: 'stx:libbasic' }"
ExternalStream subclass:#FileStream
@@ -20,7 +21,6 @@
!FileStream primitiveDefinitions!
%{
-
#undef String
#undef Character
@@ -180,7 +180,7 @@
# define HFILE FILE *
#endif /* ! WIN32 */
-#define xxDO_WRAP_CALL_FSEEK
+//#define DO_WRAP_CALL_FSEEK
#include "stxOSDefs.h"
@@ -193,7 +193,6 @@
#ifndef SEEK_END
# define SEEK_END 2
#endif
-
%}
! !
@@ -914,8 +913,8 @@
position
"return the read/write position in the file"
+ |error|
%{
-
HFILE f;
off_t currentPosition;
@@ -929,6 +928,7 @@
currentPosition = STX_C_CALL1( "ftell", ftell, f);
# else
currentPosition = ftell(f);
+ __threadErrno = errno;
# endif
} else {
OBJ rA = __INST(readAhead);
@@ -942,6 +942,7 @@
currentPosition = STX_C_CALL3( "lseek", lseek, fileno(f), offs, SEEK_CUR);
# else
currentPosition = lseek(fileno(f), offs, SEEK_CUR);
+ __threadErrno = errno;
# endif
}
#else /* !WIN32 */
@@ -967,10 +968,13 @@
}
RETURN ( rslt );
}
- __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
+ error = __mkSmallInteger(__threadErrno);
}
%}.
- lastErrorNumber notNil ifTrue:[^ self ioError].
+ error notNil ifTrue:[
+ lastErrorNumber := error.
+ ^ self ioError:error.
+ ].
handle isNil ifTrue:[^ self errorNotOpen].
^ self primitiveFailed
!
@@ -978,9 +982,8 @@
position:newPos
"set the read/write position in the file"
- |rslt|
+ |rslt error|
%{
-
HFILE f;
long ret;
OBJ fp;
@@ -1049,7 +1052,7 @@
__INST(hitEOF) = false;
RETURN ( self );
}
- __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
+ error = __mkSmallInteger(__threadErrno);
}
}
getOutOfHere: ;
@@ -1060,13 +1063,14 @@
"/ that point.
^ self slowPosition:newPos
].
- lastErrorNumber notNil ifTrue:[
- (OperatingSystem errorSymbolForNumber:lastErrorNumber) == #EINVAL ifTrue:[
+ error notNil ifTrue:[
+ lastErrorNumber := error.
+ (OperatingSystem errorSymbolForNumber:error) == #EINVAL ifTrue:[
"/ invalid position
- ^ self positionError
+ ^ self positionError.
].
"/ assume I/O error
- ^ self ioError
+ ^ self ioError:error.
].
handle isNil ifTrue:[^ self errorNotOpen].
@@ -1100,41 +1104,46 @@
setToEnd
"set the read/write position in the file to be at the end of the file"
+ |error|
%{
HFILE f;
off_t ret;
if (__INST(handle) != nil) {
- f = __FILEVal(__INST(handle));
- __INST(position) = nil; /* i.e. unknown */
- do {
+ f = __FILEVal(__INST(handle));
+ __INST(position) = nil; /* i.e. unknown */
+ do {
#ifdef WIN32
- __threadErrno = 0;
- if (__INST(buffered) == true) {
- ret = STX_C_CALL3( "fseek", fseek, f, 0L, SEEK_END);
- } else {
- __INST(readAhead) = nil;
- ret = STX_C_CALL3( "lseek", lseek, fileno(f), 0L, SEEK_END);
- }
+ __threadErrno = 0;
+ if (__INST(buffered) == true) {
+ ret = STX_C_CALL3( "fseek", fseek, f, 0L, SEEK_END);
+ } else {
+ __INST(readAhead) = nil;
+ ret = STX_C_CALL3( "lseek", lseek, fileno(f), 0L, SEEK_END);
+ }
#else
- if (__INST(buffered) == true) {
+ if (__INST(buffered) == true) {
#ifdef _LFS_LARGE_FILE
- ret = fseeko(f, (off_t)0, SEEK_END);
+ ret = fseeko(f, (off_t)0, SEEK_END);
#else
- ret = fseek(f, 0L, SEEK_END);
+ ret = fseek(f, 0L, SEEK_END);
#endif
- } else {
- ret = lseek(fileno(f), (off_t)0, SEEK_END);
- }
+ } else {
+ ret = lseek(fileno(f), (off_t)0, SEEK_END);
+ }
#endif
- } while ((ret < 0) && (__threadErrno == EINTR));
- if (ret >= 0) {
- RETURN ( self );
- }
- __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
+ } while ((ret < 0) && (__threadErrno == EINTR));
+ if (ret >= 0) {
+ RETURN ( self );
+ }
+ error = __mkSmallInteger(__threadErrno);
}
%}.
- lastErrorNumber notNil ifTrue:[^ self ioError].
+ error notNil ifTrue:[
+ lastErrorNumber := error.
+ self ioError:error.
+ ^ self.
+ ].
handle isNil ifTrue:[^ self errorNotOpen].
^ self primitiveFailed
!
@@ -1249,7 +1258,7 @@
This is a private entry, but maybe useful to open/create a file in a special mode,
which is proprietrary to the operatingSystem."
- |wasBlocked encodedPathName|
+ |wasBlocked encodedPathName error|
encodedPathName := OperatingSystem encodePath:pathName.
@@ -1258,369 +1267,369 @@
int pass = 0;
if (!__isNonNilObject(encodedPathName)
- || !(__isStringLike(openmode) || __isArrayLike(openmode)))
- goto badArgument;
+ || !(__isStringLike(openmode) || __isArrayLike(openmode)))
+ goto badArgument;
retry:
#ifdef __VMS__
if (__isStringLike(encodedPathName)) {
- do {
- /*
- * allow passing additional RMS arguments.
- * stupid: DEC does not seem to offer an interface for passing a char **.
- */
- __threadErrno = 0;
+ do {
+ /*
+ * allow passing additional RMS arguments.
+ * stupid: DEC does not seem to offer an interface for passing a char **.
+ */
+ __threadErrno = 0;
- {
- if (__isArray(attributeSpec)) {
- OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element;
- int numAttrib = 0;
- int i;
+ {
+ if (__isArray(attributeSpec)) {
+ OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element;
+ int numAttrib = 0;
+ int i;
- numAttrib = __arraySize(attributeSpec);
- for (i=0; i<numAttrib;i++) {
- if (! __isStringLike(ap[i])) {
- __threadErrno = EINVAL; /* invalid argument */
- goto getOutOfHere;
- }
- }
- switch (numAttrib) {
- case 0:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode));
- __END_INTERRUPTABLE__
- break;
- case 1:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]));
- __END_INTERRUPTABLE__
- break;
- case 2:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]));
- __END_INTERRUPTABLE__
- break;
- case 3:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]));
- __END_INTERRUPTABLE__
- break;
- case 4:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
- __stringVal(ap[3]));
- __END_INTERRUPTABLE__
- break;
- case 5:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
- __stringVal(ap[3]), __stringVal(ap[4]));
- __END_INTERRUPTABLE__
- break;
- case 6:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
- __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]));
- __END_INTERRUPTABLE__
- break;
- case 7:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
- __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
- __stringVal(ap[6]));
- __END_INTERRUPTABLE__
- break;
- case 8:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
- __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
- __stringVal(ap[6]), __stringVal(ap[7]));
- __END_INTERRUPTABLE__
- break;
- case 9:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
- __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
- __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]));
- __END_INTERRUPTABLE__
- break;
- case 10:
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
- __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
- __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
- __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]),
- __stringVal(ap[9]));
- __END_INTERRUPTABLE__
- break;
- default:
- __threadErrno = E2BIG; /* too many args */
- goto getOutOfHere;
- }
- } else if (attributeSpec != nil) {
- __threadErrno = EINVAL; /* invalid argument */
- goto getOutOfHere;
- } else {
- /*
- * create file as sequential streamLF by default.
- */
- __BEGIN_INTERRUPTABLE__
- f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf");
- __END_INTERRUPTABLE__
- }
- }
- } while ((f == NULL) && (__threadErrno == EINTR));
+ numAttrib = __arraySize(attributeSpec);
+ for (i=0; i<numAttrib;i++) {
+ if (! __isStringLike(ap[i])) {
+ __threadErrno = EINVAL; /* invalid argument */
+ goto getOutOfHere;
+ }
+ }
+ switch (numAttrib) {
+ case 0:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode));
+ __END_INTERRUPTABLE__
+ break;
+ case 1:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]));
+ __END_INTERRUPTABLE__
+ break;
+ case 2:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]));
+ __END_INTERRUPTABLE__
+ break;
+ case 3:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]));
+ __END_INTERRUPTABLE__
+ break;
+ case 4:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
+ __stringVal(ap[3]));
+ __END_INTERRUPTABLE__
+ break;
+ case 5:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
+ __stringVal(ap[3]), __stringVal(ap[4]));
+ __END_INTERRUPTABLE__
+ break;
+ case 6:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
+ __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]));
+ __END_INTERRUPTABLE__
+ break;
+ case 7:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
+ __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
+ __stringVal(ap[6]));
+ __END_INTERRUPTABLE__
+ break;
+ case 8:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
+ __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
+ __stringVal(ap[6]), __stringVal(ap[7]));
+ __END_INTERRUPTABLE__
+ break;
+ case 9:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
+ __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
+ __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]));
+ __END_INTERRUPTABLE__
+ break;
+ case 10:
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
+ __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
+ __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
+ __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]),
+ __stringVal(ap[9]));
+ __END_INTERRUPTABLE__
+ break;
+ default:
+ __threadErrno = E2BIG; /* too many args */
+ goto getOutOfHere;
+ }
+ } else if (attributeSpec != nil) {
+ __threadErrno = EINVAL; /* invalid argument */
+ goto getOutOfHere;
+ } else {
+ /*
+ * create file as sequential streamLF by default.
+ */
+ __BEGIN_INTERRUPTABLE__
+ f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf");
+ __END_INTERRUPTABLE__
+ }
+ }
+ } while ((f == NULL) && (__threadErrno == EINTR));
}
#else /* not VMS */
# ifdef WIN32
{
- DWORD share = 0, access = 0, create = 0, attr = 0;
- char * __openmode;
- HANDLE handle;
- SECURITY_ATTRIBUTES sa;
+ DWORD share = 0, access = 0, create = 0, attr = 0;
+ char * __openmode;
+ HANDLE handle;
+ SECURITY_ATTRIBUTES sa;
- if (__isStringLike(openmode)) {
- share = FILE_SHARE_READ|FILE_SHARE_WRITE;
- __openmode = __stringVal(openmode);
- if (strcmp(__openmode, "rb") == 0) {
- access = GENERIC_READ;
- create = OPEN_EXISTING;
- } else if (strcmp(__openmode, "rb+") == 0) {
- access = GENERIC_READ | GENERIC_WRITE;
- create = OPEN_EXISTING;
- } else if (strcmp(__openmode, "wb") == 0) {
- access = GENERIC_WRITE;
- create = CREATE_ALWAYS;
- } else if (strcmp(__openmode, "wb+") == 0) {
- access = GENERIC_READ | GENERIC_WRITE;
- create = CREATE_ALWAYS;
- } else if (strcmp(__openmode, "ab") == 0) {
- access = FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|
- STANDARD_RIGHTS_WRITE|SYNCHRONIZE;
- create = OPEN_ALWAYS;
- } else if (strcmp(__openmode, "ab+") == 0) {
- access = GENERIC_READ |FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|
- STANDARD_RIGHTS_WRITE|SYNCHRONIZE;
- create = OPEN_ALWAYS;
- } else {
- console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n");
- }
- } else if (__isArrayLike(openmode)) {
- OBJ *ap = __arrayVal(openmode);
- int numAttrib = __arraySize(openmode);
- int i;
+ if (__isStringLike(openmode)) {
+ share = FILE_SHARE_READ|FILE_SHARE_WRITE;
+ __openmode = __stringVal(openmode);
+ if (strcmp(__openmode, "rb") == 0) {
+ access = GENERIC_READ;
+ create = OPEN_EXISTING;
+ } else if (strcmp(__openmode, "rb+") == 0) {
+ access = GENERIC_READ | GENERIC_WRITE;
+ create = OPEN_EXISTING;
+ } else if (strcmp(__openmode, "wb") == 0) {
+ access = GENERIC_WRITE;
+ create = CREATE_ALWAYS;
+ } else if (strcmp(__openmode, "wb+") == 0) {
+ access = GENERIC_READ | GENERIC_WRITE;
+ create = CREATE_ALWAYS;
+ } else if (strcmp(__openmode, "ab") == 0) {
+ access = FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|
+ STANDARD_RIGHTS_WRITE|SYNCHRONIZE;
+ create = OPEN_ALWAYS;
+ } else if (strcmp(__openmode, "ab+") == 0) {
+ access = GENERIC_READ |FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|
+ STANDARD_RIGHTS_WRITE|SYNCHRONIZE;
+ create = OPEN_ALWAYS;
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n");
+ }
+ } else if (__isArrayLike(openmode)) {
+ OBJ *ap = __arrayVal(openmode);
+ int numAttrib = __arraySize(openmode);
+ int i;
- __openmode = "rb+";
+ __openmode = "rb+";
- for (i=0; i<numAttrib; i++) {
- OBJ attrSym = ap[i];
+ for (i=0; i<numAttrib; i++) {
+ OBJ attrSym = ap[i];
- if (attrSym == @symbol(FILE_SHARE_READ)) {
- share |= FILE_SHARE_READ;
- } else if (attrSym == @symbol(FILE_SHARE_WRITE)) {
- share |= FILE_SHARE_WRITE;
+ if (attrSym == @symbol(FILE_SHARE_READ)) {
+ share |= FILE_SHARE_READ;
+ } else if (attrSym == @symbol(FILE_SHARE_WRITE)) {
+ share |= FILE_SHARE_WRITE;
- } else if (attrSym == @symbol(GENERIC_READ)) {
- access |= GENERIC_READ;
- } else if (attrSym == @symbol(GENERIC_WRITE)) {
- access |= GENERIC_WRITE;
- } else if (attrSym == @symbol(GENERIC_READ_WRITE)) {
- access |= GENERIC_READ|GENERIC_WRITE;
+ } else if (attrSym == @symbol(GENERIC_READ)) {
+ access |= GENERIC_READ;
+ } else if (attrSym == @symbol(GENERIC_WRITE)) {
+ access |= GENERIC_WRITE;
+ } else if (attrSym == @symbol(GENERIC_READ_WRITE)) {
+ access |= GENERIC_READ|GENERIC_WRITE;
- } else if (attrSym == @symbol(CREATE_NEW)) {
- create |= CREATE_NEW;
- } else if (attrSym == @symbol(CREATE_ALWAYS)) {
- create |= CREATE_ALWAYS;
- } else if (attrSym == @symbol(OPEN_EXISTING)) {
- create |= OPEN_EXISTING;
- } else if (attrSym == @symbol(OPEN_ALWAYS)) {
- create |= OPEN_ALWAYS;
- } else if (attrSym == @symbol(TRUNCATE_EXISTING)) {
- create |= TRUNCATE_EXISTING;
+ } else if (attrSym == @symbol(CREATE_NEW)) {
+ create |= CREATE_NEW;
+ } else if (attrSym == @symbol(CREATE_ALWAYS)) {
+ create |= CREATE_ALWAYS;
+ } else if (attrSym == @symbol(OPEN_EXISTING)) {
+ create |= OPEN_EXISTING;
+ } else if (attrSym == @symbol(OPEN_ALWAYS)) {
+ create |= OPEN_ALWAYS;
+ } else if (attrSym == @symbol(TRUNCATE_EXISTING)) {
+ create |= TRUNCATE_EXISTING;
- } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) {
- attr |= FILE_ATTRIBUTE_HIDDEN;
- } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) {
- attr |= FILE_ATTRIBUTE_READONLY;
- } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) {
- attr |= FILE_FLAG_WRITE_THROUGH;
- } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) {
- attr |= FILE_FLAG_SEQUENTIAL_SCAN;
- } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) {
- attr |= FILE_FLAG_DELETE_ON_CLOSE;
- } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) {
- __openmode = __stringVal(attrSym);
- } else {
- console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n");
- }
- }
- }
- if (create == 0) {
+ } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) {
+ attr |= FILE_ATTRIBUTE_HIDDEN;
+ } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) {
+ attr |= FILE_ATTRIBUTE_READONLY;
+ } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) {
+ attr |= FILE_FLAG_WRITE_THROUGH;
+ } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) {
+ attr |= FILE_FLAG_SEQUENTIAL_SCAN;
+ } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) {
+ attr |= FILE_FLAG_DELETE_ON_CLOSE;
+ } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) {
+ __openmode = __stringVal(attrSym);
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n");
+ }
+ }
+ }
+ if (create == 0) {
// argumentError = @symbol(missingCreateMode);
- goto badArgument;
- }
- if (attr == 0) {
- attr = FILE_ATTRIBUTE_NORMAL;
- }
+ goto badArgument;
+ }
+ if (attr == 0) {
+ attr = FILE_ATTRIBUTE_NORMAL;
+ }
- /*
- * create security attributes - make handle inheritable by subprocesses
- */
- memset(&sa, 0, sizeof (sa));
- sa.nLength = sizeof( sa );
- // sa.bInheritHandle = TRUE;
- sa.bInheritHandle = FALSE;
+ /*
+ * create security attributes - make handle inheritable by subprocesses
+ */
+ memset(&sa, 0, sizeof (sa));
+ sa.nLength = sizeof( sa );
+ // sa.bInheritHandle = TRUE;
+ sa.bInheritHandle = FALSE;
- if (__isStringLike(pathName)) {
- char _aPathName[MAXPATHLEN];
+ if (__isStringLike(pathName)) {
+ char _aPathName[MAXPATHLEN];
- strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
- do {
- __threadErrno = 0;
- handle = STX_API_NOINT_CALL7( "CreateFileA", CreateFileA, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */);
- if (__threadErrno == EINTR) {
- handle = INVALID_HANDLE_VALUE;
- }
- } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR));
- } else if (__isUnicode16String(pathName)) {
- wchar_t _aPathName[MAXPATHLEN+1];
- int i, l;
+ strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+ do {
+ __threadErrno = 0;
+ handle = STX_API_NOINT_CALL7( "CreateFileA", CreateFileA, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */);
+ if (__threadErrno == EINTR) {
+ handle = INVALID_HANDLE_VALUE;
+ }
+ } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR));
+ } else if (__isUnicode16String(pathName)) {
+ wchar_t _aPathName[MAXPATHLEN+1];
+ int i, l;
- l = __unicode16StringSize(pathName);
- if (l > MAXPATHLEN) l = MAXPATHLEN;
- for (i=0; i<l; i++) {
- _aPathName[i] = __unicode16StringVal(pathName)[i];
- }
- _aPathName[i] = 0;
+ l = __unicode16StringSize(pathName);
+ if (l > MAXPATHLEN) l = MAXPATHLEN;
+ for (i=0; i<l; i++) {
+ _aPathName[i] = __unicode16StringVal(pathName)[i];
+ }
+ _aPathName[i] = 0;
- do {
- __threadErrno = 0;
- handle = STX_API_NOINT_CALL7( "CreateFileW", CreateFileW, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */);
- if (__threadErrno == EINTR) {
- handle = INVALID_HANDLE_VALUE;
- }
- } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR));
- }
- if (handle != INVALID_HANDLE_VALUE) {
- int fd;
- extern void __stxWrapApiEnterCritical(), __stxWrapApiLeaveCritical();
+ do {
+ __threadErrno = 0;
+ handle = STX_API_NOINT_CALL7( "CreateFileW", CreateFileW, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */);
+ if (__threadErrno == EINTR) {
+ handle = INVALID_HANDLE_VALUE;
+ }
+ } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR));
+ }
+ if (handle != INVALID_HANDLE_VALUE) {
+ int fd;
+ extern void __stxWrapApiEnterCritical(), __stxWrapApiLeaveCritical();
- __stxWrapApiEnterCritical();
- fd = _open_osfhandle((long)handle, O_BINARY);
- if (fd < 0) {
- if (__threadErrno == 0) {
- // no more file descriptors
- __threadErrno = EMFILE;
- }
- CloseHandle(handle);
- } else {
- f = fdopen(fd, __openmode);
- }
- __stxWrapApiLeaveCritical();
- } else {
- __threadErrno = __WIN32_ERR(GetLastError());
- }
+ __stxWrapApiEnterCritical();
+ fd = _open_osfhandle((long)handle, O_BINARY);
+ if (fd < 0) {
+ if (__threadErrno == 0) {
+ // no more file descriptors
+ __threadErrno = EMFILE;
+ }
+ CloseHandle(handle);
+ } else {
+ f = fdopen(fd, __openmode);
+ }
+ __stxWrapApiLeaveCritical();
+ } else {
+ __threadErrno = __WIN32_ERR(GetLastError());
+ }
}
# else /* not WIN32 */
if (__isStringLike(encodedPathName)) {
- int accessMode = 0666; // default access mode of fopen(), relies on umask()
- int flags = 0;
- int fd;
- char * __openmode;
+ int accessMode = 0666; // default access mode of fopen(), relies on umask()
+ int flags = 0;
+ int fd;
+ char * __openmode;
- if (__isStringLike(openmode)) {
- __openmode = __stringVal(openmode);
- if (strcmp(__openmode, "r") == 0) {
- flags = O_RDONLY;
- } else if (strcmp(__openmode, "r+") == 0) {
- flags = O_RDWR;
- } else if (strcmp(__openmode, "w") == 0) {
- flags = O_WRONLY | O_CREAT | O_TRUNC;
- } else if (strcmp(__openmode, "w+") == 0) {
- flags = O_RDWR | O_CREAT | O_TRUNC;
- } else if (strcmp(__openmode, "a") == 0) {
- flags = O_WRONLY | O_CREAT | O_APPEND;
- } else if (strcmp(__openmode, "a+") == 0) {
- flags = O_RDWR | O_CREAT| O_APPEND;
- } else {
- console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n");
- }
- } else if (__isArrayLike(openmode)) {
- OBJ *ap = __arrayVal(openmode);
- int numAttrib = __arraySize(openmode);
- int i;
+ if (__isStringLike(openmode)) {
+ __openmode = __stringVal(openmode);
+ if (strcmp(__openmode, "r") == 0) {
+ flags = O_RDONLY;
+ } else if (strcmp(__openmode, "r+") == 0) {
+ flags = O_RDWR;
+ } else if (strcmp(__openmode, "w") == 0) {
+ flags = O_WRONLY | O_CREAT | O_TRUNC;
+ } else if (strcmp(__openmode, "w+") == 0) {
+ flags = O_RDWR | O_CREAT | O_TRUNC;
+ } else if (strcmp(__openmode, "a") == 0) {
+ flags = O_WRONLY | O_CREAT | O_APPEND;
+ } else if (strcmp(__openmode, "a+") == 0) {
+ flags = O_RDWR | O_CREAT| O_APPEND;
+ } else {
+ console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n");
+ }
+ } else if (__isArrayLike(openmode)) {
+ OBJ *ap = __arrayVal(openmode);
+ int numAttrib = __arraySize(openmode);
+ int i;
- __openmode = "r+";
+ __openmode = "r+";
- for (i=0; i<numAttrib; i++) {
- OBJ attrSym = ap[i];
+ for (i=0; i<numAttrib; i++) {
+ OBJ attrSym = ap[i];
- if (attrSym == @symbol(FILE_SHARE_READ)) {
- // ignore
- } else if (attrSym == @symbol(FILE_SHARE_WRITE)) {
- // ignore
- } else if (attrSym == @symbol(GENERIC_READ)) {
- flags |= O_RDONLY;
- } else if (attrSym == @symbol(GENERIC_WRITE)) {
- flags |= O_WRONLY;
- } else if (attrSym == @symbol(GENERIC_READ_WRITE)) {
- flags |= O_RDWR;
+ if (attrSym == @symbol(FILE_SHARE_READ)) {
+ // ignore
+ } else if (attrSym == @symbol(FILE_SHARE_WRITE)) {
+ // ignore
+ } else if (attrSym == @symbol(GENERIC_READ)) {
+ flags |= O_RDONLY;
+ } else if (attrSym == @symbol(GENERIC_WRITE)) {
+ flags |= O_WRONLY;
+ } else if (attrSym == @symbol(GENERIC_READ_WRITE)) {
+ flags |= O_RDWR;
- } else if (attrSym == @symbol(CREATE_NEW)) {
- flags |= O_CREAT|O_EXCL;
- accessMode = 0600; // simulate mkstemp()
- } else if (attrSym == @symbol(CREATE_ALWAYS)) {
- flags |= O_CREAT|O_TRUNC;
- } else if (attrSym == @symbol(OPEN_EXISTING)) {
- // nothing to be set
- } else if (attrSym == @symbol(OPEN_ALWAYS)) {
- flags |= O_CREAT;
- } else if (attrSym == @symbol(TRUNCATE_EXISTING)) {
- flags |= O_TRUNC;
+ } else if (attrSym == @symbol(CREATE_NEW)) {
+ flags |= O_CREAT|O_EXCL;
+ accessMode = 0600; // simulate mkstemp()
+ } else if (attrSym == @symbol(CREATE_ALWAYS)) {
+ flags |= O_CREAT|O_TRUNC;
+ } else if (attrSym == @symbol(OPEN_EXISTING)) {
+ // nothing to be set
+ } else if (attrSym == @symbol(OPEN_ALWAYS)) {
+ flags |= O_CREAT;
+ } else if (attrSym == @symbol(TRUNCATE_EXISTING)) {
+ flags |= O_TRUNC;
- } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) {
- // ignore
- } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) {
- accessMode &= 0444;
- } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) {
+ } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) {
+ // ignore
+ } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) {
+ accessMode &= 0444;
+ } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) {
#ifdef O_DIRECT
- flags |= O_DIRECT;
+ flags |= O_DIRECT;
#endif
- } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) {
- // ignore
- } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) {
- // ignore;
- } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) {
- __openmode = __stringVal(attrSym);
- } else {
- console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n");
- }
- }
- }
- do {
- __BEGIN_INTERRUPTABLE__
- fd = open((char *) __stringVal(encodedPathName), flags, accessMode);
- __END_INTERRUPTABLE__
- } while ((fd < 0) && (__threadErrno == EINTR));
+ } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) {
+ // ignore
+ } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) {
+ // ignore;
+ } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) {
+ __openmode = __stringVal(attrSym);
+ } else {
+ console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n");
+ }
+ }
+ }
+ do {
+ __BEGIN_INTERRUPTABLE__
+ fd = open((char *) __stringVal(encodedPathName), flags, accessMode);
+ __END_INTERRUPTABLE__
+ } while ((fd < 0) && (__threadErrno == EINTR));
- if (fd >= 0) {
- __threadErrno = 0;
- f = fdopen(fd, __openmode);
- if (f == NULL) {
- close(fd); // fdopen failed, close before retry.
- }
- }
+ if (fd >= 0) {
+ __threadErrno = 0;
+ f = fdopen(fd, __openmode);
+ if (f == NULL) {
+ close(fd); // fdopen failed, close before retry.
+ }
+ }
}
# endif /* not WIN32 */
@@ -1628,81 +1637,87 @@
if (f == NULL) {
- /*
- * If no filedescriptors available, try to finalize
- * possibly collected fd's and try again.
- */
- if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) {
- pass = 1;
- __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
- __SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
- goto retry;
- }
+ /*
+ * If no filedescriptors available, try to finalize
+ * possibly collected fd's and try again.
+ */
+ if ((__threadErrno == ENFILE || __threadErrno == EMFILE) && pass == 0) {
+ pass = 1;
+ __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
+ __SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
+ goto retry;
+ }
badArgument:
getOutOfHere:
- __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
- __INST(position) = nil;
+ error = __mkSmallInteger(__threadErrno);
+ __INST(position) = nil;
} else {
#ifdef __VMS__
- /*
- * check to see if this is positionable ...
- */
- __INST(canPosition) = false;
+ /*
+ * check to see if this is positionable ...
+ */
+ __INST(canPosition) = false;
# ifndef _POSIX_C_SOURCE
- {
- struct stat statBuffer;
+ {
+ struct stat statBuffer;
- if (fstat(fileno(f), &statBuffer) >= 0) {
- switch (statBuffer.st_fab_rfm) {
- case FAB$C_UDF: /* undefined (also stream binary) */
- case FAB$C_VAR: /* variable length records */
- case FAB$C_VFC: /* variable fixed control */
- case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */
- default:
- __INST(canPosition) = false;
- break;
+ if (fstat(fileno(f), &statBuffer) >= 0) {
+ switch (statBuffer.st_fab_rfm) {
+ case FAB$C_UDF: /* undefined (also stream binary) */
+ case FAB$C_VAR: /* variable length records */
+ case FAB$C_VFC: /* variable fixed control */
+ case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */
+ default:
+ __INST(canPosition) = false;
+ break;
- case FAB$C_FIX: /* fixed length records */
- case FAB$C_STMLF: /* LF stream (valid only for sequential) */
- case FAB$C_STMCR: /* CR stream (valid only for sequential) */
- __INST(canPosition) = true;
- break;
- }
- }
- }
+ case FAB$C_FIX: /* fixed length records */
+ case FAB$C_STMLF: /* LF stream (valid only for sequential) */
+ case FAB$C_STMCR: /* CR stream (valid only for sequential) */
+ __INST(canPosition) = true;
+ break;
+ }
+ }
+ }
# endif
#else /* not VMS */
- __INST(canPosition) = true;
+ __INST(canPosition) = true;
#endif /* not VMS */
- if (@global(FileOpenTrace) == true) {
- console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f);
- }
- if (f != NULL) {
- OBJ fp;
+ if (@global(FileOpenTrace) == true) {
+ console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f);
+ }
+ if (f != NULL) {
+ OBJ fp;
- wasBlocked = __BLOCKINTERRUPTS();
+ wasBlocked = __BLOCKINTERRUPTS();
#if 0
- // The original code was:
- __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp);
- // but for that, gcc generates wrong code, which loads self (volatile) into
- // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp.
- // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old
- // object.
+ // The original code was:
+ __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp);
+ // but for that, gcc generates wrong code, which loads self (volatile) into
+ // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp.
+ // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old
+ // object.
#else
- fp = __MKEXTERNALADDRESS(f);
- __INST(handle) = fp;
- __STORE(self, fp);
+ fp = __MKEXTERNALADDRESS(f);
+ __INST(handle) = fp;
+ __STORE(self, fp);
#endif
- }
+ }
}
%}.
- handle notNil ifTrue:[
- position := 0.
- handleType := #filePointer.
- Lobby register:self.
- wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts].
+ error notNil ifTrue:[
+ lastErrorNumber := error.
+ ^ self openError:error.
].
+ handle isNil ifTrue:[
+ ^ self openError:0.
+ ].
+
+ position := 0.
+ handleType := #filePointer.
+ Lobby register:self.
+ wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts].
^ handle
!
@@ -1775,15 +1790,9 @@
handle notNil ifTrue:[^ self errorAlreadyOpen].
handle := self openFile:pathName withMode:openmode attributes:attributeSpec.
- handle isNil ifTrue:[
- "
- the open failed for some reason ...
- "
- ^ self openError:lastErrorNumber.
- ].
position := 0.
buffered isNil ifTrue:[
- buffered := true. "default is buffered"
+ buffered := true. "default is buffered"
].
!
@@ -1903,18 +1912,18 @@
fileSize
"return the size in bytes of the file"
+ |error|
%{
-
HFILE f;
#ifdef transputer
unsigned int size;
if (__INST(handle) != nil) {
- f = __FILEVal(__INST(handle));
- if ((size = filesize(fileno(f))) >= 0) {
- RETURN ( __MKUINT(size) );
- }
+ f = __FILEVal(__INST(handle));
+ if ((size = filesize(fileno(f))) >= 0) {
+ RETURN ( __MKUINT(size) );
+ }
}
#else
struct stat buf;
@@ -1922,35 +1931,39 @@
int fd;
if (__INST(handle) != nil) {
- f = __FILEVal(__INST(handle));
- fd = fileno(f);
- do {
- ret = fstat(fd, &buf);
- } while ((ret < 0) && (__threadErrno == EINTR));
- if (ret >= 0) {
- OBJ rslt;
+ f = __FILEVal(__INST(handle));
+ fd = fileno(f);
+ do {
+ ret = fstat(fd, &buf);
+ } while ((ret < 0) && (__threadErrno == EINTR));
+ if (ret >= 0) {
+ OBJ rslt;
- if (sizeof(buf.st_size) == 8) {
- rslt = __MKINT64(&buf.st_size);
- } else {
- rslt = __MKINT(buf.st_size);
- }
- RETURN(rslt);
- }
- __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
+ if (sizeof(buf.st_size) == 8) {
+ rslt = __MKINT64(&buf.st_size);
+ } else {
+ rslt = __MKINT(buf.st_size);
+ }
+ RETURN(rslt);
+ }
+ error = __mkSmallInteger(__threadErrno);
}
#endif
%}.
"could add a fall-back here:
- oldPosition := self position.
- self setToEnd.
- sz := self position.
- self position:oldPosition.
- ^ sz
+ oldPosition := self position.
+ self setToEnd.
+ sz := self position.
+ self position:oldPosition.
+ ^ sz
"
- lastErrorNumber notNil ifTrue:[^ self ioError].
+ error notNil ifTrue:[
+ lastErrorNumber := error.
+ self ioError:error.
+ ^ self.
+ ].
handle isNil ifTrue:[^ self errorNotOpen].
^ self primitiveFailed
!
@@ -1994,11 +2007,11 @@
!FileStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.171 2014-02-22 16:34:26 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.172 2014-04-03 13:03:29 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.171 2014-02-22 16:34:26 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.172 2014-04-03 13:03:29 stefan Exp $'
! !