FileStream.st
changeset 4910 33b0edbb1920
parent 4907 0b09209a95c8
child 5120 13143fbcbdf8
--- a/FileStream.st	Wed Oct 13 17:04:18 1999 +0200
+++ b/FileStream.st	Fri Oct 15 01:51:02 1999 +0200
@@ -28,15 +28,19 @@
 #define _ERRNO_H_INCLUDED_
 
 #ifdef transputer
+
 # include <iocntrl.h>
 # ifndef fileno
    /* kludge: inmos forgot fileno */
 #  define fileno(f)     ((f)->__file)
 # endif
-#else
+
+#else /* not transputer */
+
 # include <sys/types.h>
 # include <sys/stat.h>
-#endif
+
+#endif /* not transputer */
 
 #ifdef hpux
 # define fileno(f)      ((f->__fileH << 8) | (f->__fileL))
@@ -72,9 +76,142 @@
 #endif
 
 #ifndef WIN32
- extern long ftell(), lseek();
+  extern long ftell(), lseek();
+# define HFILE FILE *
+
 #endif
 
+#ifdef WIN32
+# define NO_STDIO
+# ifdef i386
+#  define _X86_
+# endif
+
+# undef INT
+# undef Array
+# undef Number
+# undef Method
+# undef Point
+# undef Rectangle
+# undef Block
+# undef Time
+# undef Date
+
+# define NOATOM
+# define NOGDICAPMASKS
+# define NOMETAFILE
+# define NOMINMAX
+//# define NOOPENFILE
+# define NOSOUND
+# define NOWH
+//# define NOCOMM
+# define NOKANJI
+# define NOCRYPT
+//# define NOMCX
+# define WIN32_LEAN_AND_MEAN
+
+# include <windows.h>
+# include <winsock.h> /* */
+
+# if !defined(__BORLANDC__)
+#  define stat _stat
+# endif
+
+# ifdef __DEF_Array
+#  define Array __DEF_Array
+# endif
+# ifdef __DEF_Number
+#  define Number __DEF_Number
+# endif
+# ifdef __DEF_Method
+#  define Method __DEF_Method
+# endif
+# ifdef __DEF_Point
+#  define Point __DEF_Point
+# endif
+# ifdef __DEF_Block
+#  define Block __DEF_Block
+# endif
+# ifdef __DEF_Time
+#  define Time __DEF_Time
+# endif
+# ifdef __DEF_Date
+#  define Date __DEF_Date
+# endif
+
+# define INT int
+
+# ifdef NO_STDIO
+
+/*#  define HFILE HANDLE*/
+#  define HFILE FILE *
+//#  define fileno(f) f
+
+#  define TELL(currentPosition,f,buffered)                       \
+    if (buffered) {                                             \
+	currentPosition = ftell(f);                             \
+    } else {                                                    \
+	OBJ rA = __INST(readAhead);                             \
+	if (rA != nil) {                                        \
+	    __INST(readAhead) = nil;                            \
+	    currentPosition = lseek(fileno(f), -1L, SEEK_CUR);  \
+	} else {                                                \
+	  currentPosition = lseek(fileno(f), 0L, SEEK_CUR);     \
+	}                                                       \
+    }
+
+#  define SEEK(ret,f,nP,buffered)                        \
+    if (buffered) {                                     \
+	ret = fseek(f, nP, SEEK_SET);                   \
+    } else {                                            \
+	OBJ rA = __INST(readAhead);                     \
+	if (rA != nil) {                                \
+	    __INST(readAhead) = nil;                    \
+	}                                               \
+	ret = lseek(fileno(f), nP, SEEK_SET);           \
+    }
+
+#  define TOEND(ret,f,buffered)                          \
+    if (buffered) {                                     \
+	ret = fseek(f, 0L, SEEK_END);                   \
+    } else {                                            \
+	OBJ rA = __INST(readAhead);                     \
+	if (rA != nil) {                                \
+	    __INST(readAhead) = nil;                    \
+	}                                               \
+	ret = lseek(fileno(f), 0L, SEEK_END);           \
+    }
+
+# else /* use STDIO */
+
+#  define HFILE FILE *
+
+#  define TELL(currentPosition,f,buffered)                 \
+    if (buffered) {                                       \
+	currentPosition = ftell(f);                       \
+    } else {                                              \
+	currentPosition = lseek(fileno(f), 0L, SEEK_CUR); \
+    }
+
+#  define SEEK(ret,f,nP,buffered)                        \
+    if (buffered) {                                     \
+	ret = fseek(f, nP, SEEK_SET);                   \
+    } else {                                            \
+	ret = lseek(fileno(f), nP, SEEK_SET);           \
+    }
+
+#  define TOEND(ret,f,buffered)                          \
+    if (buffered) {                                     \
+	ret = fseek(f, 0L, SEEK_END);                   \
+    } else {                                            \
+	ret = lseek(fileno(f), 0L, SEEK_END);           \
+    }
+
+  extern long ftell(), lseek();
+# endif /* use STDIO */
+
+#endif /* WIN32 */
+
 /*
  * on some systems errno is a macro ... check for it here
  */
@@ -121,8 +258,8 @@
     I know, this is ugly, but what else could we do ?
 
     [instance variables:]
-	pathName	<String>	the files path (if known)
-	canPosition	<Boolean>	positionable - read above comment
+	pathName        <String>        the files path (if known)
+	canPosition     <Boolean>       positionable - read above comment
 
     [author:]
 	Claus Gittinger
@@ -161,19 +298,19 @@
 
 initialize
     OpenErrorSignal isNil ifTrue:[
-        "/
-        "/ this is temporary - for now allow an openError to
-        "/ be unhandled and proceed by returning a nil from the
-        "/ stream creation method.
-        "/ In the future, this will be a hard signal.
-        "/
-        OpenErrorSignal := QuerySignal new.
-        OpenErrorSignal parent:(super openErrorSignal) mayProceed:true.
-        OpenErrorSignal nameClass:self message:#openErrorSignal.
-        OpenErrorSignal notifierString:'open error'.
+	"/
+	"/ this is temporary - for now allow an openError to
+	"/ be unhandled and proceed by returning a nil from the
+	"/ stream creation method.
+	"/ In the future, this will be a hard signal.
+	"/
+	OpenErrorSignal := QuerySignal new.
+	OpenErrorSignal parent:(super openErrorSignal) mayProceed:true.
+	OpenErrorSignal nameClass:self message:#openErrorSignal.
+	OpenErrorSignal notifierString:'open error'.
 
-        UserInitiatedFileSaveQuerySignal := QuerySignal new defaultAnswer:true.
-        UserInitiatedFileSaveQuerySignal nameClass:self message:#userInitiatedFileSaveQuerySignal.
+	UserInitiatedFileSaveQuerySignal := QuerySignal new defaultAnswer:true.
+	UserInitiatedFileSaveQuerySignal nameClass:self message:#userInitiatedFileSaveQuerySignal.
     ]
 
     "Modified: 8.10.1997 / 11:56:39 / cg"
@@ -468,7 +605,7 @@
 
     super closeFile.
     removeOnClose == true ifTrue:[
-        pathName asFilename remove.
+	pathName asFilename remove.
     ]
 
     "Created: / 13.8.1998 / 12:11:22 / cg"
@@ -482,17 +619,21 @@
 
 %{
 
-    FILE *f;
+    HFILE f;
     long currentPosition;
 
     if (__INST(filePointer) != nil) {
 	f = __FILEVal(__INST(filePointer));
 	do {
+#ifdef WIN32
+	    TELL(currentPosition,f,__INST(buffered) == true);
+#else
 	    if (__INST(buffered) == true) {
 		currentPosition = ftell(f);
 	    } else {
 		currentPosition = lseek(fileno(f), 0L, SEEK_CUR);
 	    }
+#endif
 	} while ((currentPosition < 0) && (errno == EINTR));
 	if (currentPosition >= 0) {
 	    /*
@@ -513,39 +654,43 @@
 
 %{
 
-    FILE *f;
+    HFILE f;
     long ret;
     OBJ fp;
     long nP;
 
     if ((__INST(canPosition) != false) 
      || (newPos == __MKSMALLINT(1))) {
-        if ((fp = __INST(filePointer)) != nil) {
+	if ((fp = __INST(filePointer)) != nil) {
 	    if (__isSmallInteger(newPos)) {
-	        f = __FILEVal(fp);
-	        nP = (long)__intVal(newPos);
+		f = __FILEVal(fp);
+		nP = (long)__intVal(newPos);
+
+		/*
+		 * notice: Smalltalk index starts at 1
+		 */
+		nP--;
 
-	        /*
-	         * notice: Smalltalk index starts at 1
-	         */
-	        nP--;
-
-	        do {
+		do {
+#ifdef WIN32
+		    SEEK(ret,f,nP,__INST(buffered) == true);
+#else
 		    if (__INST(buffered) == true) {
-		        ret = fseek(f, nP, SEEK_SET);
+			ret = fseek(f, nP, SEEK_SET);
 		    } else {
-		        ret = lseek(fileno(f), nP, SEEK_SET);
+			ret = lseek(fileno(f), nP, SEEK_SET);
 		    }
-	        } while ((ret < 0) && (errno == EINTR));
-	        if (ret >= 0) {
+#endif
+		} while ((ret < 0) && (errno == EINTR));
+		if (ret >= 0) {
 		    __INST(position) = newPos;
 		    /*
 		     * just to make certain ...
 		     */
 		    __INST(hitEOF) = false;
 		    RETURN ( self );
-	        }
-	        __INST(lastErrorNumber) = __MKSMALLINT(errno);
+		}
+		__INST(lastErrorNumber) = __MKSMALLINT(errno);
 	    }
 	}
     }
@@ -571,18 +716,22 @@
     "set the read/write position in the file to be at the end of the file"
 
 %{
-    FILE *f;
+    HFILE f;
     long ret;
 
     if (__INST(filePointer) != nil) {
 	f = __FILEVal(__INST(filePointer));
 	__INST(position) = nil;
 	do {
+#ifdef WIN32
+	    TOEND(ret,f,__INST(buffered) == true);
+#else
 	    if (__INST(buffered) == true) {
 		ret = fseek(f, 0L, SEEK_END);
 	    } else {
 		ret = lseek(fileno(f), 0L, SEEK_END);
 	    }
+#endif
 	} while ((ret < 0) && (errno == EINTR));
 	if (ret >= 0) {
 	    RETURN ( self );
@@ -601,7 +750,7 @@
      This is required to reposition nonPositionable streams, such
      as tape-streams or variable-record-RMS files under VMS.
      Caveat:
-         This should really be done transparently by the stdio library."
+	 This should really be done transparently by the stdio library."
 
     |buffer amount|
 
@@ -614,7 +763,7 @@
 
     (position isNil "/ i.e. unknown
     or:[newPos < position]) ifTrue:[
-        self reset.
+	self reset.
     ].
     [position < newPos] whileTrue:[
 	amount := (buffer size) min:(newPos-position).
@@ -645,8 +794,8 @@
     aStream nextPutAll:'(FileStream oldFileNamed:'.
     aStream nextPutAll:pathName storeString.
     (self position ~~ 1) ifTrue:[
-        aStream nextPutAll:'; position:'.
-        self position storeOn:aStream
+	aStream nextPutAll:'; position:'.
+	self position storeOn:aStream
     ].
     aStream nextPut:$)
 
@@ -757,8 +906,8 @@
     filePointer notNil ifTrue:[^ self errorAlreadyOpen].
     ok := false.
 %{
-    FILE *f;
-    FILE *fopen();
+    HFILE f;
+    HFILE fopen();
     OBJ path, fp;
     int pass = 0;
 
@@ -766,205 +915,230 @@
     path = __INST(pathName);
     if (__isNonNilObject(path) && (__qClass(path)==String)) {
 #ifdef __VMS__
-        do {
-            /*
-             * allow passing additional RMS arguments.
-             * stupid: DEC does not seem to offer an interface for passing a char **.
-             */
-            errno = 0;
+	do {
+	    /*
+	     * allow passing additional RMS arguments.
+	     * stupid: DEC does not seem to offer an interface for passing a char **.
+	     */
+	    errno = 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 (! __isString(ap[i])) {
-                            f = NULL;
-                            errno = EINVAL; /* invalid argument */
-                            goto getOutOfHere;
-                        }
-                    }
-                    switch (numAttrib) {
-                        case 0:
-                            __BEGIN_INTERRUPTABLE__
-                            f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode));
-                            __END_INTERRUPTABLE__
-                            break;
-                        case 1:
-                            __BEGIN_INTERRUPTABLE__
-                            f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode),
-                                      __stringVal(ap[0]));
-                            __END_INTERRUPTABLE__
-                            break;
-                        case 2:
-                            __BEGIN_INTERRUPTABLE__
-                            f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode),
-                                      __stringVal(ap[0]), __stringVal(ap[1]));
-                            __END_INTERRUPTABLE__
-                            break;
-                        case 3:
-                            __BEGIN_INTERRUPTABLE__
-                            f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode),
-                                      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]));
-                            __END_INTERRUPTABLE__
-                            break;
-                        case 4:
-                            __BEGIN_INTERRUPTABLE__
-                            f = fopen((char *)__stringVal(path), (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(path), (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(path), (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(path), (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(path), (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(path), (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(path), (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:
-                            f = NULL;
-                            errno = E2BIG; /* too many args */
-                            goto getOutOfHere;
-                    }
-                } else if (attributeSpec != nil) {
-                    f = NULL;
-                    errno = EINVAL; /* invalid argument */
-                    goto getOutOfHere;
-                } else {
-                    /*
-                     * create file as sequential streamLF by default.
-                     */
-                    __BEGIN_INTERRUPTABLE__
-                    f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode), "rfm=stmlf");
-                    __END_INTERRUPTABLE__
-                }
-            }
-            /* must refetch - could be GC'd */
-            path = __INST(pathName);
-        } while ((f == NULL) && (errno == EINTR));
-#else
-        do {
-            __BEGIN_INTERRUPTABLE__
-# ifdef LINUX
-            /* 
-             * LINUX may ret a non-NULL f even when interrupted.
-             * Therefore, check errno and fake a null-ret.
-             */
-            errno = 0;
-            f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
-            if (errno == EINTR)
-                f = NULL;
-# else
-            f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
-# endif
-            __END_INTERRUPTABLE__
-            /* must refetch - could be GC'd */
-            path = __INST(pathName);
-        } while ((f == NULL) && (errno == EINTR));
-#endif
+		    numAttrib = __arraySize(attributeSpec);
+		    for (i=0; i<numAttrib;i++) {
+			if (! __isString(ap[i])) {
+			    f = NULL;
+			    errno = EINVAL; /* invalid argument */
+			    goto getOutOfHere;
+			}
+		    }
+		    switch (numAttrib) {
+			case 0:
+			    __BEGIN_INTERRUPTABLE__
+			    f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode));
+			    __END_INTERRUPTABLE__
+			    break;
+			case 1:
+			    __BEGIN_INTERRUPTABLE__
+			    f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode),
+				      __stringVal(ap[0]));
+			    __END_INTERRUPTABLE__
+			    break;
+			case 2:
+			    __BEGIN_INTERRUPTABLE__
+			    f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode),
+				      __stringVal(ap[0]), __stringVal(ap[1]));
+			    __END_INTERRUPTABLE__
+			    break;
+			case 3:
+			    __BEGIN_INTERRUPTABLE__
+			    f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode),
+				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]));
+			    __END_INTERRUPTABLE__
+			    break;
+			case 4:
+			    __BEGIN_INTERRUPTABLE__
+			    f = fopen((char *)__stringVal(path), (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(path), (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(path), (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(path), (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(path), (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(path), (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(path), (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:
+			    f = NULL;
+			    errno = E2BIG; /* too many args */
+			    goto getOutOfHere;
+		    }
+		} else if (attributeSpec != nil) {
+		    f = NULL;
+		    errno = EINVAL; /* invalid argument */
+		    goto getOutOfHere;
+		} else {
+		    /*
+		     * create file as sequential streamLF by default.
+		     */
+		    __BEGIN_INTERRUPTABLE__
+		    f = fopen((char *)__stringVal(path), (char *)__stringVal(openmode), "rfm=stmlf");
+		    __END_INTERRUPTABLE__
+		}
+	    }
+	    /* must refetch - could be GC'd */
+	    path = __INST(pathName);
+	} while ((f == NULL) && (errno == EINTR));
 
-        if (f == NULL) {
-            /*
-             * If no filedescriptors available, try to finalize
-             * possibly collected fd's and try again.
-             */
-            if (pass == 0 && (errno == ENFILE || errno == EMFILE)) {
-                pass = 1;
-                __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
-                __SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
-                goto retry;
-            }
-        getOutOfHere: ;
-            __INST(lastErrorNumber) = __MKSMALLINT(errno);
-            __INST(position) = nil;
-        } else {
+#else /* not VMS */
+
+# ifdef WIN32
+
+	do {
+#  ifdef NO_STDIO
+	    /*printf("open %s mode=%s\n",__stringVal(path),__stringVal(openmode)); */
+#   ifdef DO_WRAP_CALLS
+	    f = __STX_C_CALL2((void*)fopen,(void *)__stringVal(path), (void *)__stringVal(openmode));
+#   else
+	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
+#   endif
+#  else /* use_STDIO */
+	    __BEGIN_INTERRUPTABLE__
+	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode)); 
+	    __END_INTERRUPTABLE__
+#  endif /* use_STDIO */
+	    /* must refetch - could be GC'd */
+	    path = __INST(pathName);
+	} while ((f == NULL) && (errno == EINTR));
+
+# else /* not WIN32 */
+
+	do {
+	    __BEGIN_INTERRUPTABLE__
+#  ifdef LINUX
+	    /* 
+	     * LINUX may ret a non-NULL f even when interrupted.
+	     * Therefore, check errno and fake a null-ret.
+	     */
+	    errno = 0;
+	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
+	    if (errno == EINTR)
+		f = NULL;
+#  else /* not LINUX */
+	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
+#  endif /* not LINUX */
+	    __END_INTERRUPTABLE__
+	    /* must refetch - could be GC'd */
+	    path = __INST(pathName);
+	} while ((f == NULL) && (errno == EINTR));
+
+# endif /* not WIN32 */
+#endif /* not VMS */
+
+	if (f == NULL) {
+	    /*
+	     * If no filedescriptors available, try to finalize
+	     * possibly collected fd's and try again.
+	     */
+	    if (pass == 0 && (errno == ENFILE || errno == EMFILE)) {
+		pass = 1;
+		__SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
+		__SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
+		goto retry;
+	    }
+	getOutOfHere: ;
+	    __INST(lastErrorNumber) = __MKSMALLINT(errno);
+	    __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 /* poor VMS */
 
-            __INST(filePointer) = fp = __MKOBJ((INT)f); __STORE(self, fp);
-            __INST(position) = __MKSMALLINT(1);
-            ok = true;
-        }
+	    __INST(filePointer) = fp = __MKOBJ((INT)f); __STORE(self, fp);
+	    __INST(position) = __MKSMALLINT(1);
+	    ok = true;
+	}
     }
 %}.
     ok ifFalse:[
-        "
-         the open failed for some reason ...
-        "
-        ^ self openError
+	"
+	 the open failed for some reason ...
+	"
+	^ self openError
     ].
     buffered := true.       "default is buffered"
     Lobby register:self.
@@ -1004,7 +1178,7 @@
 	    (self class name , ' [warning]: could not reOpen file: ', pathName) errorPrintCR.
 	] ifFalse:[
 	    oldPos notNil ifTrue:[
-	        self position:oldPos.
+		self position:oldPos.
 	    ]
 	]
     ]
@@ -1023,8 +1197,9 @@
 
 %{
 
+    HFILE f;
+
 #ifdef transputer
-    FILE *f;
     int size;
 
     if (__INST(filePointer) != nil) {
@@ -1034,7 +1209,6 @@
 	}
     }
 #else
-    FILE *f;
     struct stat buf;
     int ret;
     int fd;
@@ -1090,6 +1264,6 @@
 !FileStream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.67 1999-10-13 12:25:40 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.68 1999-10-14 23:51:01 cg Exp $'
 ! !
 FileStream initialize!