Large file support (off_t with 64 bits) for UNIX
authorStefan Vogel <sv@exept.de>
Fri, 06 Feb 2004 12:40:43 +0100
changeset 7883 1039acd0624b
parent 7882 6e1883fa220d
child 7884 a164a1259744
Large file support (off_t with 64 bits) for UNIX
ExternalStream.st
FileStream.st
UnixOperatingSystem.st
--- a/ExternalStream.st	Fri Feb 06 11:41:15 2004 +0100
+++ b/ExternalStream.st	Fri Feb 06 12:40:43 2004 +0100
@@ -2729,10 +2729,14 @@
     char *cp;
     char *matchString;
     int gotFirst = 0;
-#ifdef __VMS__
+#if defined(__VMS__)
     fpos_t firstpos, lastpos;
 #   define FTELL(__f__, __pos__)        fgetpos(__f__, &(__pos__))
 #   define FSEEK(__f__, __pos__)        fsetpos(__f__, &(__pos__))
+#elif defined(_LFS_LARGEFILE)
+    off_t firstpos, lastpos;
+#   define FTELL(__f__, __pos__)        __pos__ = ftello(__f__)
+#   define FSEEK(__f__, __pos__)        fseeko(__f__, __pos__, SEEK_SET)
 #else
     long firstpos, lastpos;
 #   define FTELL(__f__, __pos__)        __pos__ = ftell(__f__)
@@ -5853,7 +5857,7 @@
 !ExternalStream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.269 2004-02-05 15:04:27 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.270 2004-02-06 11:39:18 stefan Exp $'
 ! !
 
 ExternalStream initialize!
--- a/FileStream.st	Fri Feb 06 11:41:15 2004 +0100
+++ b/FileStream.st	Fri Feb 06 12:40:43 2004 +0100
@@ -695,11 +695,11 @@
 # endif
             } else {                                                   
                 OBJ rA = __INST(readAhead);                            
-                long offs = 0L;
+                off_t offs = 0;
 
                 if (rA != nil) {                                       
                     __INST(readAhead) = nil;                           
-                    offs = -1L;
+                    offs = -1;
                 }                                                      
 # if 0
                 currentPosition = STX_C_CALL3( "lseek", lseek, fileno(f), offs, SEEK_CUR); 
@@ -709,9 +709,13 @@
             }
 #else
             if (__INST(buffered) == true) {
+#ifdef _LFS_LARGEFILE
+                currentPosition = ftello(f);
+#else
                 currentPosition = ftell(f);
+#endif
             } else {
-                currentPosition = lseek(fileno(f), 0L, SEEK_CUR);
+                currentPosition = lseek(fileno(f), (off_t)0, SEEK_CUR);
             }
 #endif
         } while ((currentPosition < 0) && (__threadErrno == EINTR));
@@ -744,12 +748,16 @@
     long ret;
     OBJ fp;
 
-    if ((__INST(canPosition) != false) 
-     || (newPos == __MKSMALLINT(0))) {
+    if ((__INST(canPosition) != false) || (newPos == __MKSMALLINT(0))) {
         if ((fp = __INST(filePointer)) != nil) {
+
+#if defined(_LFS_LARGE_FILE) && !defined(WIN32)
+# define FSEEK fseeko
+            off_t nP;
+#else
+#define FSEEK fseek
             long nP;
-            __int64__ nP64;
-            int need64BitPosition = 0;
+#endif
 
             if (__isSmallInteger(newPos)) {
                 nP = __intVal(newPos);
@@ -764,17 +772,15 @@
                     goto getOutOfHere;
                 }
                 if (nP == 0) {
-                    __int64__ nP64;
-
-                    if (__signedLong64IntVal(newPos, &nP64) == 0) {
+                    if (sizeof(nP) == 8) {
+                        if (__signedLong64IntVal(newPos, &nP) == 0 || nP < 0) {
+                            __INST(lastErrorNumber) = __MKSMALLINT(EINVAL);
+                            goto getOutOfHere;
+                        }
+                    } else {
                         __INST(lastErrorNumber) = __MKSMALLINT(EINVAL);
                         goto getOutOfHere;
                     }
-                    if (nP64.hi < 0) {
-                        __INST(lastErrorNumber) = __MKSMALLINT(EINVAL);
-                        goto getOutOfHere;
-                    }
-                    need64BitPosition = 1;
                 }
             }
 
@@ -784,36 +790,16 @@
 #ifdef WIN32
                 __threadErrno = 0;
                 if (__INST(buffered) == true) {                                          
-                    if (need64BitPosition) {
-                        __INST(lastErrorNumber) = __MKSMALLINT(EINVAL);
-                        goto getOutOfHere;
-                    } else {
-                        ret = STX_C_CALL3( "fseek", fseek, f, nP, SEEK_SET);    
-                    }
+                    ret = STX_C_CALL3( "fseek", fseek, f, nP, SEEK_SET);    
                 } else {                                                    
                     __INST(readAhead) = nil;                            
-                    if (need64BitPosition) {
-                        __INST(lastErrorNumber) = __MKSMALLINT(EINVAL);
-                        goto getOutOfHere;
-                    } else {
-                        ret = STX_C_CALL3( "lseek", lseek, fileno(f), nP, SEEK_SET); 
-                    }
+                    ret = STX_C_CALL3( "lseek", lseek, fileno(f), nP, SEEK_SET); 
                 }
 #else
                 if (__INST(buffered) == true) {
-                    if (need64BitPosition) {
-                        __INST(lastErrorNumber) = __MKSMALLINT(EINVAL);
-                        goto getOutOfHere;
-                    } else {
-                        ret = fseek(f, nP, SEEK_SET);
-                    }
+                    ret = FSEEK(f, nP, SEEK_SET);
                 } else {
-                    if (need64BitPosition) {
-                        __INST(lastErrorNumber) = __MKSMALLINT(EINVAL);
-                        goto getOutOfHere;
-                    } else {
-                        ret = lseek(fileno(f), nP, SEEK_SET);
-                    }
+                    ret = lseek(fileno(f), nP, SEEK_SET);
                 }
 #endif
             } while ((ret < 0) && (__threadErrno == EINTR));
@@ -829,6 +815,7 @@
         }
     }
     getOutOfHere: ;
+#undef FSEEK
 %}.
     canPosition == false ifTrue:[
         "/ position by rewinding & re-reading everything up-to
@@ -858,32 +845,36 @@
 
 %{
     HFILE f;
-    long ret;
+    off_t ret;
 
     if (__INST(filePointer) != nil) {
-	f = __FILEVal(__INST(filePointer));
-	__INST(position) = nil;    /* i.e. unknown */
-	do {
+        f = __FILEVal(__INST(filePointer));
+        __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) {
-		ret = fseek(f, 0L, SEEK_END);
-	    } else {
-		ret = lseek(fileno(f), 0L, SEEK_END);
-	    }
+            if (__INST(buffered) == true) {
+#ifdef _LFS_LARGE_FILE
+                ret = fseeko(f, (off_t)0, SEEK_END);
+#else                
+                ret = fseek(f, 0L, SEEK_END);
 #endif
-	} while ((ret < 0) && (__threadErrno == EINTR));
-	if (ret >= 0) {
-	    RETURN ( self );
-	}
-	__INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
+            } else {
+                ret = lseek(fileno(f), (off_t)0, SEEK_END);
+            }
+#endif
+        } while ((ret < 0) && (__threadErrno == EINTR));
+        if (ret >= 0) {
+            RETURN ( self );
+        }
+        __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
     }
 %}.
     lastErrorNumber notNil ifTrue:[^ self ioError].
@@ -1022,213 +1013,213 @@
 retry:
     if (__isNonNilObject(pathName) && (__qClass(pathName)==String)) {
 #ifdef __VMS__
-	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 (! __isString(ap[i])) {
-			    f = NULL;
-			    __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:
-			    f = NULL;
-			    __threadErrno = E2BIG; /* too many args */
-			    goto getOutOfHere;
-		    }
-		} else if (attributeSpec != nil) {
-		    f = NULL;
-		    __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 (! __isString(ap[i])) {
+                            f = NULL;
+                            __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:
+                            f = NULL;
+                            __threadErrno = E2BIG; /* too many args */
+                            goto getOutOfHere;
+                    }
+                } else if (attributeSpec != nil) {
+                    f = NULL;
+                    __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
 
-	do {
-	    __threadErrno = 0;
-	    f = STX_C_CALL2( "fopen", fopen, (char *)__stringVal(pathName), (char *)__stringVal(openmode));
-	    if (__threadErrno == EINTR) {
-		f = NULL;
-	    }
-	} while ((f == NULL) && (__threadErrno == EINTR));
+        do {
+            __threadErrno = 0;
+            f = STX_C_CALL2( "fopen", fopen, (char *)__stringVal(pathName), (char *)__stringVal(openmode));
+            if (__threadErrno == EINTR) {
+                f = NULL;
+            }
+        } while ((f == NULL) && (__threadErrno == EINTR));
 
 # else /* not WIN32 */
 
-	do {
-	    __BEGIN_INTERRUPTABLE__
+        do {
+            __BEGIN_INTERRUPTABLE__
 #  ifdef LINUX
-	    /* 
-	     * LINUX may ret a non-NULL f even when interrupted.
-	     * Therefore, check errno and fake a null-ret.
-	     */
-	    __threadErrno = 0;
-	    f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
-	    if (__threadErrno == EINTR)
-		f = NULL;
+            /* 
+             * LINUX may ret a non-NULL f even when interrupted.
+             * Therefore, check errno and fake a null-ret.
+             */
+            __threadErrno = 0;
+            f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
+            if (__threadErrno == EINTR)
+                f = NULL;
 #  else /* not LINUX */
-	    f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
+            f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
 #  endif /* not LINUX */
-	    __END_INTERRUPTABLE__
-	} while ((f == NULL) && (__threadErrno == EINTR));
+            __END_INTERRUPTABLE__
+        } while ((f == NULL) && (__threadErrno == 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 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) {
-		pass = 1;
-		__SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
-		__SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
-		goto retry;
-	    }
-	getOutOfHere: ;
-	    __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
-	    __INST(position) = nil;
-	} else {
+        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;
+            }
+        getOutOfHere: ;
+            __INST(lastErrorNumber) = __MKSMALLINT(__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 /* poor VMS */
 
-	    if (@global(FileOpenTrace) == true) {
-		fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f);
-	    }
+            if (@global(FileOpenTrace) == true) {
+                fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f);
+            }
 
-	    filePointer = __MKOBJ((INT)f); 
-	    __INST(position) = @global(PositionableStream:ZeroPosition);
-	}
+            filePointer = __MKOBJ((INT)f); 
+            __INST(position) = @global(PositionableStream:ZeroPosition);
+        }
     }
 %}.
     ^ filePointer
@@ -1389,7 +1380,14 @@
             ret = fstat(fd, &buf);
         } while ((ret < 0) && (__threadErrno == EINTR));
         if (ret >= 0) {
-            RETURN ( __MKUINT( (int)(buf.st_size) ) );
+            OBJ rslt;
+
+            if (sizeof(buf.st_size) == 8) {
+                rslt = __MKINT64(&buf.st_size);
+            } else {
+                rslt = __MKINT(buf.st_size);
+            }
+            RETURN(rslt);
         }
         __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
     }
@@ -1441,7 +1439,7 @@
 !FileStream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.101 2004-02-05 12:20:13 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.102 2004-02-06 11:40:43 stefan Exp $'
 ! !
 
 FileStream initialize!
--- a/UnixOperatingSystem.st	Fri Feb 06 11:41:15 2004 +0100
+++ b/UnixOperatingSystem.st	Fri Feb 06 12:40:43 2004 +0100
@@ -4466,21 +4466,21 @@
     "return some object filled with info for the file 'aPathName';
      the info (for which corresponding access methods are understood by
      the returned object) is:
-	 type            - a symbol giving the files type
-	 mode            - numeric access mode 
-	 uid             - owners user id
-	 gid             - owners group id
-	 size            - files size
-	 id              - files number (i.e. inode number)
-	 accessed        - last access time (as Timestamp)
-	 modified        - last modification time (as Timestamp)
-	 statusChanged   - last status change time (as Timestamp)
-	 alternativeName     - (windows only:) the MSDOS name of the file
-	 recordFormatNumeric - (VMS only:) numeric value of the recordFormat
-	 recordFormat        - (VMS only:) symbolic value of the recordFormat
-	 recordAttributes    - (VMS only:) recordAttributes
-	 fixedHeaderSize     - (VMS only:) fixed header size in a variable record format
-	 recordSize          - (VMS only:) record size.
+         type            - a symbol giving the files type
+         mode            - numeric access mode 
+         uid             - owners user id
+         gid             - owners group id
+         size            - files size
+         id              - files number (i.e. inode number)
+         accessed        - last access time (as Timestamp)
+         modified        - last modification time (as Timestamp)
+         statusChanged   - last status change time (as Timestamp)
+         alternativeName     - (windows only:) the MSDOS name of the file
+         recordFormatNumeric - (VMS only:) numeric value of the recordFormat
+         recordFormat        - (VMS only:) symbolic value of the recordFormat
+         recordAttributes    - (VMS only:) recordAttributes
+         fixedHeaderSize     - (VMS only:) fixed header size in a variable record format
+         recordSize          - (VMS only:) record size.
 
      Some of the fields may be returned as nil on systems which do not provide
      all of the information.
@@ -4500,98 +4500,103 @@
 
     if (__isString(aPathName)) {
 # ifdef TRACE_STAT_CALLS
-	printf("stat on '%s' for info\n", __stringVal(aPathName));
-# endif
-	__BEGIN_INTERRUPTABLE__
-	do {
-	    ret = stat((char *) __stringVal(aPathName), &buf);
-	} while ((ret < 0) && (errno == EINTR));
-	__END_INTERRUPTABLE__
-
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __MKSMALLINT(errno);
-	    RETURN ( nil );
-	}
-	switch (buf.st_mode & S_IFMT) {
-	    case S_IFDIR:
-		type = @symbol(directory);
-		break;
-
-	    case S_IFREG:
-		type = @symbol(regular);
-		break;
+        printf("stat on '%s' for info\n", __stringVal(aPathName));
+# endif
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = stat((char *) __stringVal(aPathName), &buf);
+        } while ((ret < 0) && (errno == EINTR));
+        __END_INTERRUPTABLE__
+
+        if (ret < 0) {
+            @global(LastErrorNumber) = __MKSMALLINT(errno);
+            RETURN ( nil );
+        }
+        switch (buf.st_mode & S_IFMT) {
+            case S_IFDIR:
+                type = @symbol(directory);
+                break;
+
+            case S_IFREG:
+                type = @symbol(regular);
+                break;
 # ifdef S_IFCHR
-	    case S_IFCHR:
-		type = @symbol(characterSpecial);
-		break;
+            case S_IFCHR:
+                type = @symbol(characterSpecial);
+                break;
 # endif
 # ifdef S_IFBLK
-	    case S_IFBLK:
-		type = @symbol(blockSpecial);
-		break;
+            case S_IFBLK:
+                type = @symbol(blockSpecial);
+                break;
 # endif
 # ifdef S_IFMPC
-	    case S_IFMPC:
-		type = @symbol(multiplexedCharacterSpecial);
-		break;
+            case S_IFMPC:
+                type = @symbol(multiplexedCharacterSpecial);
+                break;
 # endif
 # ifdef S_IFMPB
-	    case S_IFMPB:
-		type = @symbol(multiplexedBlockSpecial);
-		break;
+            case S_IFMPB:
+                type = @symbol(multiplexedBlockSpecial);
+                break;
 # endif
 # ifdef S_IFLNK
-	    case S_IFLNK:
-		type = @symbol(symbolicLink);
-		break;
+            case S_IFLNK:
+                type = @symbol(symbolicLink);
+                break;
 # endif
 # ifdef S_IFSOCK
-	    case S_IFSOCK:
-		type = @symbol(socket);
-		break;
+            case S_IFSOCK:
+                type = @symbol(socket);
+                break;
 # endif
 # ifdef S_IFIFO
-	    case S_IFIFO:
-		type = @symbol(fifo);
-		break;
-# endif
-	    default:
-		type = @symbol(unknown);
-		break;
-	}
-
-	ino = buf.st_ino;
-	id = __MKUINT(ino);
-
-	mode = __MKSMALLINT(buf.st_mode & 0777);
-	uid = __MKSMALLINT(buf.st_uid);
-	gid = __MKSMALLINT(buf.st_gid);
-	nLink = __MKSMALLINT(buf.st_nlink);
-	size = __MKUINT(buf.st_size);
-	aOStime = __MKUINT(buf.st_atime);
-	mOStime = __MKUINT(buf.st_mtime);
-	cOStime = __MKUINT(buf.st_ctime);
+            case S_IFIFO:
+                type = @symbol(fifo);
+                break;
+# endif
+            default:
+                type = @symbol(unknown);
+                break;
+        }
+
+        ino = buf.st_ino;
+        id = __MKUINT(ino);
+
+        mode = __MKSMALLINT(buf.st_mode & 0777);
+        uid = __MKSMALLINT(buf.st_uid);
+        gid = __MKSMALLINT(buf.st_gid);
+        nLink = __MKSMALLINT(buf.st_nlink);
+        size = __MKUINT(buf.st_size);
+        if (sizeof(buf.st_size) == 8) {
+            size = __MKINT64(&buf.st_size);
+        } else {
+            size = __MKINT(buf.st_size);
+        }
+        aOStime = __MKUINT(buf.st_atime);
+        mOStime = __MKUINT(buf.st_mtime);
+        cOStime = __MKUINT(buf.st_ctime);
     }
 %}.
     mode notNil ifTrue:[
-	"/ now done lazy in FileStatusInfo
-	"/ atime := AbsoluteTime fromOSTime:(aOStime * 1000).
-	"/ mtime := AbsoluteTime fromOSTime:(mOStime * 1000).
-	"/ ctime := AbsoluteTime fromOSTime:(cOStime * 1000).
-
-	info := FileStatusInfo
-		    type:type 
-		    mode:mode 
-		    uid:uid 
-		    gid:gid 
-		    size:size 
-		    id:id 
-		    accessed:aOStime 
-		    modified:mOStime 
-		    statusChanged:cOStime
-		    path:nil
-		    numLinks:nLink.
-	^ info
+        "/ now done lazy in FileStatusInfo
+        "/ atime := AbsoluteTime fromOSTime:(aOStime * 1000).
+        "/ mtime := AbsoluteTime fromOSTime:(mOStime * 1000).
+        "/ ctime := AbsoluteTime fromOSTime:(cOStime * 1000).
+
+        info := FileStatusInfo
+                    type:type 
+                    mode:mode 
+                    uid:uid 
+                    gid:gid 
+                    size:size 
+                    id:id 
+                    accessed:aOStime 
+                    modified:mOStime 
+                    statusChanged:cOStime
+                    path:nil
+                    numLinks:nLink.
+        ^ info
    ].
    ^ self primitiveFailed
 
@@ -4773,61 +4778,65 @@
     unsigned INT ino;
 
     if (__isString(aPathName)) {
-	__BEGIN_INTERRUPTABLE__
-	do {
-	    ret = lstat((char *) __stringVal(aPathName), &buf);
-	} while ((ret < 0) && (errno == EINTR));
-	__END_INTERRUPTABLE__
-
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __MKSMALLINT(errno);
-	    RETURN ( nil );
-	}
-	switch (buf.st_mode & S_IFMT) {
-	    default:
-		RETURN ( nil ); /* not a symbolic link */
-
-	    case S_IFLNK:
-		type = @symbol(symbolicLink);
-		break;
-	}
-
-	ino = buf.st_ino;
-	id = __MKUINT(ino);
-
-	mode = __MKSMALLINT(buf.st_mode & 0777);
-	nLink = __MKSMALLINT(buf.st_nlink);
-	uid = __MKSMALLINT(buf.st_uid);
-	gid = __MKSMALLINT(buf.st_gid);
-	size = __MKUINT(buf.st_size);
-	atime = __MKUINT(buf.st_atime);
-	mtime = __MKUINT(buf.st_mtime);
-	ctime = __MKUINT(buf.st_ctime);
-	if ((ret = readlink((char *) __stringVal(aPathName), pathBuffer, sizeof(pathBuffer))) < 0) {
-	    @global(LastErrorNumber) = __MKSMALLINT(errno);
-	    RETURN ( nil );
-	} 
-	pathBuffer[ret] = '\0';  /* readlink does not 0-terminate */
-	path = __MKSTRING(pathBuffer);
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = lstat((char *) __stringVal(aPathName), &buf);
+        } while ((ret < 0) && (errno == EINTR));
+        __END_INTERRUPTABLE__
+
+        if (ret < 0) {
+            @global(LastErrorNumber) = __MKSMALLINT(errno);
+            RETURN ( nil );
+        }
+        switch (buf.st_mode & S_IFMT) {
+            default:
+                RETURN ( nil ); /* not a symbolic link */
+
+            case S_IFLNK:
+                type = @symbol(symbolicLink);
+                break;
+        }
+
+        ino = buf.st_ino;
+        id = __MKUINT(ino);
+
+        mode = __MKSMALLINT(buf.st_mode & 0777);
+        nLink = __MKSMALLINT(buf.st_nlink);
+        uid = __MKSMALLINT(buf.st_uid);
+        gid = __MKSMALLINT(buf.st_gid);
+        if (sizeof(buf.st_size) == 8) {
+            size = __MKINT64(&buf.st_size);
+        } else {
+            size = __MKINT(buf.st_size);
+        }
+        atime = __MKUINT(buf.st_atime);
+        mtime = __MKUINT(buf.st_mtime);
+        ctime = __MKUINT(buf.st_ctime);
+        if ((ret = readlink((char *) __stringVal(aPathName), pathBuffer, sizeof(pathBuffer))) < 0) {
+            @global(LastErrorNumber) = __MKSMALLINT(errno);
+            RETURN ( nil );
+        } 
+        pathBuffer[ret] = '\0';  /* readlink does not 0-terminate */
+        path = __MKSTRING(pathBuffer);
     }
 #else
     RETURN ( nil );
 #endif
 %}.
     mode notNil ifTrue:[
-	info := IdentityDictionary new.
-	^ FileStatusInfo
-	    type:type 
-	    mode:mode 
-	    uid:uid 
-	    gid:gid 
-	    size:size 
-	    id:id 
-	    accessed:(AbsoluteTime fromOSTime:(atime * 1000)) 
-	    modified:(AbsoluteTime fromOSTime:(mtime * 1000)) 
-	    statusChanged:(AbsoluteTime fromOSTime:(ctime * 1000))
-	    path:path
-	    numLinks:nLink.
+        info := IdentityDictionary new.
+        ^ FileStatusInfo
+            type:type 
+            mode:mode 
+            uid:uid 
+            gid:gid 
+            size:size 
+            id:id 
+            accessed:(AbsoluteTime fromOSTime:(atime * 1000)) 
+            modified:(AbsoluteTime fromOSTime:(mtime * 1000)) 
+            statusChanged:(AbsoluteTime fromOSTime:(ctime * 1000))
+            path:path
+            numLinks:nLink.
    ].
    ^ self primitiveFailed
 
@@ -9961,55 +9970,63 @@
 seekTo:newPosition from:whence
     "seek to newPosition
      whence is one of: #begin #current #end.
-     Return the new position.
-
-     TODO: 64 bit handling"
+     Return the new position."
 
     |error|
 
 %{
-    INT fd, pos, ret;
+    INT fd;
     INT __whence;
-    __uint64__ pos64;
+    off_t pos, ret;
+    OBJ rslt;
 
     if (! __isSmallInteger(__INST(fd))) {
-	error = @symbol(errorNotOpen);
-	goto bad;
+        error = @symbol(errorNotOpen);
+        goto bad;
     }
     if (__isSmallInteger(newPosition)) {
-	pos = __smallIntegerVal(newPosition);
-    } else if (__signedLong64IntVal(newPosition, &pos64) == 0) {
-	error = @symbol(badArgument1);
-	goto bad;
-    }
+        pos = __smallIntegerVal(newPosition);
+    } else {
+        pos = __signedLongIntVal(newPosition);
+        if (pos < 0 && (sizeof(pos) < 8 || __signedLong64IntVal(newPosition, &pos) == 0)) {
+            error = @symbol(badArgument1);
+            goto bad;
+        }
+    }
+
     fd = __smallIntegerVal(__INST(fd));
     if (fd < 0) {
-	error = @symbol(internalError);
-	goto bad;
+        error = @symbol(internalError);
+        goto bad;
     }
     if (whence == @symbol(begin)) {
-	__whence = SEEK_SET;    
+        __whence = SEEK_SET;    
     } else if (whence == @symbol(current)) {
-	__whence = SEEK_CUR;    
+        __whence = SEEK_CUR;    
     } else if (whence == @symbol(end)) {
-	__whence = SEEK_END;    
+        __whence = SEEK_END;    
     } else {
-	error = @symbol(badArgument2);
-	goto bad;
+        error = @symbol(badArgument2);
+        goto bad;
     }
 
 again:
     ret = lseek(fd, pos, __whence);
     if (ret < 0) {
-	if (errno == EINTR) {
-	    __HANDLE_INTERRUPTS__;
-	    goto again;
-	}
-	error = __mkSmallInteger(errno);
-	goto bad;
-    }
-    /* RETURN (__mkInteger(ret)); */
-    RETURN (__mkSmallInteger(ret));
+        if (errno == EINTR) {
+            __HANDLE_INTERRUPTS__;
+            goto again;
+        }
+        error = __mkSmallInteger(errno);
+        goto bad;
+    }
+
+    if (sizeof(ret) == 8) {
+        rslt = __MKINT64 (&ret);
+    } else {
+        rslt = __MKINT(ret);
+    }
+    RETURN (rslt);
 
 bad: ;   
 %}.
@@ -12273,7 +12290,7 @@
 !UnixOperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.202 2004-02-05 12:09:32 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.203 2004-02-06 11:40:13 stefan Exp $'
 ! !
 
 UnixOperatingSystem initialize!