FileStream.st
changeset 16298 5fd8d5ceab59
parent 16113 411bfb1ec52c
child 16369 a938f5cbc31d
--- 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 $'
 ! !