710 HFILE f; |
710 HFILE f; |
711 long ret; |
711 long ret; |
712 OBJ fp; |
712 OBJ fp; |
713 |
713 |
714 if ((__INST(canPosition) != false) || (newPos == __MKSMALLINT(0))) { |
714 if ((__INST(canPosition) != false) || (newPos == __MKSMALLINT(0))) { |
715 if ((fp = __INST(filePointer)) != nil) { |
715 if ((fp = __INST(filePointer)) != nil) { |
716 |
716 |
717 #if defined(_LFS_LARGE_FILE) && !defined(WIN32) |
717 #if defined(_LFS_LARGE_FILE) && !defined(WIN32) |
718 # define FSEEK fseeko |
718 # define FSEEK fseeko |
719 off_t nP; |
719 off_t nP; |
720 #else |
720 #else |
721 #define FSEEK fseek |
721 #define FSEEK fseek |
722 long nP; |
722 long nP; |
723 #endif |
723 #endif |
724 |
724 |
725 if (__isSmallInteger(newPos)) { |
725 if (__isSmallInteger(newPos)) { |
726 nP = __intVal(newPos); |
726 nP = __intVal(newPos); |
727 if (nP < 0) { |
727 if (nP < 0) { |
728 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
728 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
729 goto getOutOfHere; |
729 goto getOutOfHere; |
730 } |
730 } |
731 } else { |
731 } else { |
732 nP = __signedLongIntVal(newPos); |
732 nP = __signedLongIntVal(newPos); |
733 if (nP < 0) { |
733 if (nP < 0) { |
734 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
734 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
735 goto getOutOfHere; |
735 goto getOutOfHere; |
736 } |
736 } |
737 if (nP == 0) { |
737 if (nP == 0) { |
738 if (sizeof(nP) == 8) { |
738 if (sizeof(nP) == 8) { |
739 if (__signedLong64IntVal(newPos, &nP) == 0 || nP < 0) { |
739 if (__signedLong64IntVal(newPos, &nP) == 0 || nP < 0) { |
740 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
740 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
741 goto getOutOfHere; |
741 goto getOutOfHere; |
742 } |
742 } |
743 } else { |
743 } else { |
744 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
744 __INST(lastErrorNumber) = __MKSMALLINT(EINVAL); |
745 goto getOutOfHere; |
745 goto getOutOfHere; |
746 } |
746 } |
747 } |
747 } |
748 } |
748 } |
749 |
749 |
750 f = __FILEVal(fp); |
750 f = __FILEVal(fp); |
751 |
751 |
752 do { |
752 do { |
753 #ifdef WIN32 |
753 #ifdef WIN32 |
754 __threadErrno = 0; |
754 __threadErrno = 0; |
755 if (__INST(buffered) == true) { |
755 if (__INST(buffered) == true) { |
756 ret = STX_C_CALL3( "fseek", fseek, f, nP, SEEK_SET); |
756 ret = STX_C_CALL3( "fseek", fseek, f, nP, SEEK_SET); |
757 } else { |
757 } else { |
758 __INST(readAhead) = nil; |
758 __INST(readAhead) = nil; |
759 ret = STX_C_CALL3( "lseek", lseek, fileno(f), nP, SEEK_SET); |
759 ret = STX_C_CALL3( "lseek", lseek, fileno(f), nP, SEEK_SET); |
760 } |
760 } |
761 #else |
761 #else |
762 if (__INST(buffered) == true) { |
762 if (__INST(buffered) == true) { |
763 ret = FSEEK(f, nP, SEEK_SET); |
763 ret = FSEEK(f, nP, SEEK_SET); |
764 } else { |
764 } else { |
765 ret = lseek(fileno(f), nP, SEEK_SET); |
765 ret = lseek(fileno(f), nP, SEEK_SET); |
766 } |
766 } |
767 #endif |
767 #endif |
768 } while ((ret < 0) && (__threadErrno == EINTR)); |
768 } while ((ret < 0) && (__threadErrno == EINTR)); |
769 if (ret >= 0) { |
769 if (ret >= 0) { |
770 __INST(position) = newPos; __STORE(self, newPos); |
770 __INST(position) = newPos; __STORE(self, newPos); |
771 /* |
771 /* |
772 * just to make certain ... |
772 * just to make certain ... |
773 */ |
773 */ |
774 __INST(hitEOF) = false; |
774 __INST(hitEOF) = false; |
775 RETURN ( self ); |
775 RETURN ( self ); |
776 } |
776 } |
777 __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno); |
777 __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno); |
778 } |
778 } |
779 } |
779 } |
780 getOutOfHere: ; |
780 getOutOfHere: ; |
781 #undef FSEEK |
781 #undef FSEEK |
782 %}. |
782 %}. |
783 canPosition == false ifTrue:[ |
783 canPosition == false ifTrue:[ |
784 "/ position by rewinding & re-reading everything up-to |
784 "/ position by rewinding & re-reading everything up-to |
785 "/ that point. |
785 "/ that point. |
786 ^ self slowPosition0Based:newPos |
786 ^ self slowPosition0Based:newPos |
787 ]. |
787 ]. |
788 lastErrorNumber notNil ifTrue:[ |
788 lastErrorNumber notNil ifTrue:[ |
789 (OperatingSystem errorSymbolForNumber:lastErrorNumber) == #EINVAL ifTrue:[ |
789 (OperatingSystem errorSymbolForNumber:lastErrorNumber) == #EINVAL ifTrue:[ |
790 "/ invalid position |
790 "/ invalid position |
791 ^ self positionError |
791 ^ self positionError |
792 ]. |
792 ]. |
793 "/ assume I/O error |
793 "/ assume I/O error |
794 ^ self ioError |
794 ^ self ioError |
795 ]. |
795 ]. |
796 filePointer isNil ifTrue:[^ self errorNotOpen]. |
796 filePointer isNil ifTrue:[^ self errorNotOpen]. |
797 |
797 |
798 rslt := self positionFile:filePointer position:newPos. |
798 rslt := self positionFile:filePointer position:newPos. |
799 rslt >= 0 ifTrue:[ |
799 rslt >= 0 ifTrue:[ |
800 position := newPos. |
800 position := newPos. |
801 ] ifFalse:[ |
801 ] ifFalse:[ |
802 hitEOF := true. |
802 hitEOF := true. |
803 ] |
803 ] |
804 ! |
804 ! |
805 |
805 |
806 setToEnd |
806 setToEnd |
807 "set the read/write position in the file to be at the end of the file" |
807 "set the read/write position in the file to be at the end of the file" |
967 |wasBlocked| |
967 |wasBlocked| |
968 |
968 |
969 %{ |
969 %{ |
970 HFILE f; |
970 HFILE f; |
971 HFILE fopen(); |
971 HFILE fopen(); |
972 OBJ fp; |
|
973 int pass = 0; |
972 int pass = 0; |
974 |
973 |
975 retry: |
974 retry: |
976 if (__isNonNilObject(pathName) && (__qClass(pathName)==String)) { |
975 if (__isNonNilObject(pathName) && (__qClass(pathName)==String)) { |
977 #ifdef __VMS__ |
976 #ifdef __VMS__ |
978 do { |
977 do { |
979 /* |
978 /* |
980 * allow passing additional RMS arguments. |
979 * allow passing additional RMS arguments. |
981 * stupid: DEC does not seem to offer an interface for passing a char **. |
980 * stupid: DEC does not seem to offer an interface for passing a char **. |
982 */ |
981 */ |
983 __threadErrno = 0; |
982 __threadErrno = 0; |
984 |
983 |
985 { |
984 { |
986 if (__isArray(attributeSpec)) { |
985 if (__isArray(attributeSpec)) { |
987 OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; |
986 OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; |
988 int numAttrib = 0; |
987 int numAttrib = 0; |
989 int i; |
988 int i; |
990 |
989 |
991 numAttrib = __arraySize(attributeSpec); |
990 numAttrib = __arraySize(attributeSpec); |
992 for (i=0; i<numAttrib;i++) { |
991 for (i=0; i<numAttrib;i++) { |
993 if (! __isString(ap[i])) { |
992 if (! __isString(ap[i])) { |
994 f = NULL; |
993 f = NULL; |
995 __threadErrno = EINVAL; /* invalid argument */ |
994 __threadErrno = EINVAL; /* invalid argument */ |
996 goto getOutOfHere; |
995 goto getOutOfHere; |
997 } |
996 } |
998 } |
997 } |
999 switch (numAttrib) { |
998 switch (numAttrib) { |
1000 case 0: |
999 case 0: |
1001 __BEGIN_INTERRUPTABLE__ |
1000 __BEGIN_INTERRUPTABLE__ |
1002 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode)); |
1001 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode)); |
1003 __END_INTERRUPTABLE__ |
1002 __END_INTERRUPTABLE__ |
1004 break; |
1003 break; |
1005 case 1: |
1004 case 1: |
1006 __BEGIN_INTERRUPTABLE__ |
1005 __BEGIN_INTERRUPTABLE__ |
1007 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1006 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1008 __stringVal(ap[0])); |
1007 __stringVal(ap[0])); |
1009 __END_INTERRUPTABLE__ |
1008 __END_INTERRUPTABLE__ |
1010 break; |
1009 break; |
1011 case 2: |
1010 case 2: |
1012 __BEGIN_INTERRUPTABLE__ |
1011 __BEGIN_INTERRUPTABLE__ |
1013 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1012 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1014 __stringVal(ap[0]), __stringVal(ap[1])); |
1013 __stringVal(ap[0]), __stringVal(ap[1])); |
1015 __END_INTERRUPTABLE__ |
1014 __END_INTERRUPTABLE__ |
1016 break; |
1015 break; |
1017 case 3: |
1016 case 3: |
1018 __BEGIN_INTERRUPTABLE__ |
1017 __BEGIN_INTERRUPTABLE__ |
1019 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1018 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1020 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2])); |
1019 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2])); |
1021 __END_INTERRUPTABLE__ |
1020 __END_INTERRUPTABLE__ |
1022 break; |
1021 break; |
1023 case 4: |
1022 case 4: |
1024 __BEGIN_INTERRUPTABLE__ |
1023 __BEGIN_INTERRUPTABLE__ |
1025 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1024 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1026 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1025 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1027 __stringVal(ap[3])); |
1026 __stringVal(ap[3])); |
1028 __END_INTERRUPTABLE__ |
1027 __END_INTERRUPTABLE__ |
1029 break; |
1028 break; |
1030 case 5: |
1029 case 5: |
1031 __BEGIN_INTERRUPTABLE__ |
1030 __BEGIN_INTERRUPTABLE__ |
1032 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1031 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1033 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1032 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1034 __stringVal(ap[3]), __stringVal(ap[4])); |
1033 __stringVal(ap[3]), __stringVal(ap[4])); |
1035 __END_INTERRUPTABLE__ |
1034 __END_INTERRUPTABLE__ |
1036 break; |
1035 break; |
1037 case 6: |
1036 case 6: |
1038 __BEGIN_INTERRUPTABLE__ |
1037 __BEGIN_INTERRUPTABLE__ |
1039 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1038 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1040 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1039 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1041 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5])); |
1040 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5])); |
1042 __END_INTERRUPTABLE__ |
1041 __END_INTERRUPTABLE__ |
1043 break; |
1042 break; |
1044 case 7: |
1043 case 7: |
1045 __BEGIN_INTERRUPTABLE__ |
1044 __BEGIN_INTERRUPTABLE__ |
1046 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1045 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1047 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1046 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1048 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1047 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1049 __stringVal(ap[6])); |
1048 __stringVal(ap[6])); |
1050 __END_INTERRUPTABLE__ |
1049 __END_INTERRUPTABLE__ |
1051 break; |
1050 break; |
1052 case 8: |
1051 case 8: |
1053 __BEGIN_INTERRUPTABLE__ |
1052 __BEGIN_INTERRUPTABLE__ |
1054 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1053 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1055 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1054 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1056 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1055 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1057 __stringVal(ap[6]), __stringVal(ap[7])); |
1056 __stringVal(ap[6]), __stringVal(ap[7])); |
1058 __END_INTERRUPTABLE__ |
1057 __END_INTERRUPTABLE__ |
1059 break; |
1058 break; |
1060 case 9: |
1059 case 9: |
1061 __BEGIN_INTERRUPTABLE__ |
1060 __BEGIN_INTERRUPTABLE__ |
1062 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1061 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1063 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1062 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1064 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1063 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1065 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8])); |
1064 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8])); |
1066 __END_INTERRUPTABLE__ |
1065 __END_INTERRUPTABLE__ |
1067 break; |
1066 break; |
1068 case 10: |
1067 case 10: |
1069 __BEGIN_INTERRUPTABLE__ |
1068 __BEGIN_INTERRUPTABLE__ |
1070 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1069 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1071 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1070 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1072 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1071 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1073 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]), |
1072 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]), |
1074 __stringVal(ap[9])); |
1073 __stringVal(ap[9])); |
1075 __END_INTERRUPTABLE__ |
1074 __END_INTERRUPTABLE__ |
1076 break; |
1075 break; |
1077 default: |
1076 default: |
1078 f = NULL; |
1077 f = NULL; |
1079 __threadErrno = E2BIG; /* too many args */ |
1078 __threadErrno = E2BIG; /* too many args */ |
1080 goto getOutOfHere; |
1079 goto getOutOfHere; |
1081 } |
1080 } |
1082 } else if (attributeSpec != nil) { |
1081 } else if (attributeSpec != nil) { |
1083 f = NULL; |
1082 f = NULL; |
1084 __threadErrno = EINVAL; /* invalid argument */ |
1083 __threadErrno = EINVAL; /* invalid argument */ |
1085 goto getOutOfHere; |
1084 goto getOutOfHere; |
1086 } else { |
1085 } else { |
1087 /* |
1086 /* |
1088 * create file as sequential streamLF by default. |
1087 * create file as sequential streamLF by default. |
1089 */ |
1088 */ |
1090 __BEGIN_INTERRUPTABLE__ |
1089 __BEGIN_INTERRUPTABLE__ |
1091 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf"); |
1090 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf"); |
1092 __END_INTERRUPTABLE__ |
1091 __END_INTERRUPTABLE__ |
1093 } |
1092 } |
1094 } |
1093 } |
1095 } while ((f == NULL) && (__threadErrno == EINTR)); |
1094 } while ((f == NULL) && (__threadErrno == EINTR)); |
1096 |
1095 |
1097 #else /* not VMS */ |
1096 #else /* not VMS */ |
1098 |
1097 |
1099 # ifdef WIN32 |
1098 # ifdef WIN32 |
1100 { |
1099 { |
1101 char _aPathName[MAXPATHLEN]; |
1100 char _aPathName[MAXPATHLEN]; |
1102 char _openMode[64]; |
1101 char _openMode[64]; |
1103 |
1102 |
1104 strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
1103 strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
1105 strncpy(_openMode, __stringVal(openmode), sizeof(_openMode)-1); _openMode[sizeof(_openMode)-1] = '\0'; |
1104 strncpy(_openMode, __stringVal(openmode), sizeof(_openMode)-1); _openMode[sizeof(_openMode)-1] = '\0'; |
1106 do { |
1105 do { |
1107 __threadErrno = 0; |
1106 __threadErrno = 0; |
1108 f = STX_C_CALL2( "fopen", fopen, _aPathName, _openMode); |
1107 f = STX_C_CALL2( "fopen", fopen, _aPathName, _openMode); |
1109 if (__threadErrno == EINTR) { |
1108 if (__threadErrno == EINTR) { |
1110 f = NULL; |
1109 f = NULL; |
1111 } |
1110 } |
1112 } while ((f == NULL) && (__threadErrno == EINTR)); |
1111 } while ((f == NULL) && (__threadErrno == EINTR)); |
1113 } |
1112 } |
1114 # else /* not WIN32 */ |
1113 # else /* not WIN32 */ |
1115 |
1114 |
1116 do { |
1115 do { |
1117 __BEGIN_INTERRUPTABLE__ |
1116 __BEGIN_INTERRUPTABLE__ |
1118 # ifdef LINUX |
1117 # ifdef LINUX |
1119 /* |
1118 /* |
1120 * LINUX may ret a non-NULL f even when interrupted. |
1119 * LINUX may ret a non-NULL f even when interrupted. |
1121 * Therefore, check errno and fake a null-ret. |
1120 * Therefore, check errno and fake a null-ret. |
1122 */ |
1121 */ |
1123 __threadErrno = 0; |
1122 __threadErrno = 0; |
1124 f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode)); |
1123 f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode)); |
1125 if (__threadErrno == EINTR) |
1124 if (__threadErrno == EINTR) |
1126 f = NULL; |
1125 f = NULL; |
1127 # else /* not LINUX */ |
1126 # else /* not LINUX */ |
1128 f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode)); |
1127 f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode)); |
1129 # endif /* not LINUX */ |
1128 # endif /* not LINUX */ |
1130 __END_INTERRUPTABLE__ |
1129 __END_INTERRUPTABLE__ |
1131 } while ((f == NULL) && (__threadErrno == EINTR)); |
1130 } while ((f == NULL) && (__threadErrno == EINTR)); |
1132 |
1131 |
1133 # endif /* not WIN32 */ |
1132 # endif /* not WIN32 */ |
1134 #endif /* not VMS */ |
1133 #endif /* not VMS */ |
1135 |
1134 |
1136 if (f == NULL) { |
1135 if (f == NULL) { |
1137 /* |
1136 /* |
1138 * If no filedescriptors available, try to finalize |
1137 * If no filedescriptors available, try to finalize |
1139 * possibly collected fd's and try again. |
1138 * possibly collected fd's and try again. |
1140 */ |
1139 */ |
1141 if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) { |
1140 if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) { |
1142 pass = 1; |
1141 pass = 1; |
1143 __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); |
1142 __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); |
1144 __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); |
1143 __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); |
1145 goto retry; |
1144 goto retry; |
1146 } |
1145 } |
1147 getOutOfHere: ; |
1146 getOutOfHere: ; |
1148 __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno); |
1147 __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno); |
1149 __INST(position) = nil; |
1148 __INST(position) = nil; |
1150 } else { |
1149 } else { |
1151 #ifdef __VMS__ |
1150 #ifdef __VMS__ |
1152 /* |
1151 /* |
1153 * check to see if this is positionable ... |
1152 * check to see if this is positionable ... |
1154 */ |
1153 */ |
1155 __INST(canPosition) = false; |
1154 __INST(canPosition) = false; |
1156 # ifndef _POSIX_C_SOURCE |
1155 # ifndef _POSIX_C_SOURCE |
1157 { |
1156 { |
1158 struct stat statBuffer; |
1157 struct stat statBuffer; |
1159 |
1158 |
1160 if (fstat(fileno(f), &statBuffer) >= 0) { |
1159 if (fstat(fileno(f), &statBuffer) >= 0) { |
1161 switch (statBuffer.st_fab_rfm) { |
1160 switch (statBuffer.st_fab_rfm) { |
1162 case FAB$C_UDF: /* undefined (also stream binary) */ |
1161 case FAB$C_UDF: /* undefined (also stream binary) */ |
1163 case FAB$C_VAR: /* variable length records */ |
1162 case FAB$C_VAR: /* variable length records */ |
1164 case FAB$C_VFC: /* variable fixed control */ |
1163 case FAB$C_VFC: /* variable fixed control */ |
1165 case FAB$C_STM: /* RMS-11 stream (valid only for sequen> */ |
1164 case FAB$C_STM: /* RMS-11 stream (valid only for sequen> */ |
1166 default: |
1165 default: |
1167 __INST(canPosition) = false; |
1166 __INST(canPosition) = false; |
1168 break; |
1167 break; |
1169 |
1168 |
1170 case FAB$C_FIX: /* fixed length records */ |
1169 case FAB$C_FIX: /* fixed length records */ |
1171 case FAB$C_STMLF: /* LF stream (valid only for sequential> */ |
1170 case FAB$C_STMLF: /* LF stream (valid only for sequential> */ |
1172 case FAB$C_STMCR: /* CR stream (valid only for sequential> */ |
1171 case FAB$C_STMCR: /* CR stream (valid only for sequential> */ |
1173 __INST(canPosition) = true; |
1172 __INST(canPosition) = true; |
1174 break; |
1173 break; |
1175 } |
1174 } |
1176 } |
1175 } |
1177 } |
1176 } |
1178 # endif |
1177 # endif |
1179 #else /* not VMS */ |
1178 #else /* not VMS */ |
1180 __INST(canPosition) = true; |
1179 __INST(canPosition) = true; |
1181 #endif /* poor VMS */ |
1180 #endif /* poor VMS */ |
1182 |
1181 |
1183 if (@global(FileOpenTrace) == true) { |
1182 if (@global(FileOpenTrace) == true) { |
1184 fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f); |
1183 fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f); |
1185 } |
1184 } |
1186 if (f != NULL) { |
1185 if (f != NULL) { |
1187 wasBlocked = __BLOCKINTERRUPTS(); |
1186 OBJ fp; |
1188 __INST(filePointer) = fp = __MKOBJ((INT)f); __STORE(self, fp); |
1187 |
1189 } |
1188 wasBlocked = __BLOCKINTERRUPTS(); |
1190 } |
1189 #if 0 |
|
1190 // The original code was: |
|
1191 __INST(filePointer) = fp = __MKOBJ((INT)f); __STORE(self, fp); |
|
1192 // but for that, gcc generates wrong code, which loads self (volatile) into |
|
1193 // a register (bp), then calls __MKOBJ, then stores indirect bp. |
|
1194 // That is wrong if a scavenge occurs in MKOBJ, as bp is now still pointing to the old |
|
1195 // object. |
|
1196 #else |
|
1197 fp = __MKOBJ((INT)f); |
|
1198 __INST(filePointer) = fp; |
|
1199 __STORE(self, fp); |
|
1200 #endif |
|
1201 } |
|
1202 } |
1191 } |
1203 } |
1192 %}. |
1204 %}. |
1193 position := ZeroPosition. |
1205 position := ZeroPosition. |
1194 filePointer notNil ifTrue:[ |
1206 filePointer notNil ifTrue:[ |
1195 Lobby register:self. |
1207 Lobby register:self. |
1196 wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts]. |
1208 wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts]. |
1197 ]. |
1209 ]. |
1198 ^ filePointer |
1210 ^ filePointer |
1199 ! |
1211 ! |
1200 |
1212 |
1201 openForAppending |
1213 openForAppending |
1202 "open the file for writeonly appending to the end. |
1214 "open the file for writeonly appending to the end. |
1203 If the file does not exist its an error, raise OpenError; |
1215 If the file does not exist its an error, raise OpenError; |
1204 otherwise return the receiver." |
1216 otherwise return the receiver." |
1205 |
1217 |
1206 mode := #writeonly. |
1218 mode := #writeonly. |
1207 didWrite := true. |
1219 didWrite := true. |
1208 ^ self openWithMode:AppendMode |
1220 ^ self openWithMode:AppendMode |
1209 ! |
1221 ! |
1210 |
1222 |
1211 openForReadWrite |
1223 openForReadWrite |
1212 "open the file for read/write. |
1224 "open the file for read/write. |
1213 If the file does not exist its an error, raise OpenError; |
1225 If the file does not exist its an error, raise OpenError; |
1214 otherwise return the receiver." |
1226 otherwise return the receiver." |
1215 |
1227 |
1216 mode := #readwrite. |
1228 mode := #readwrite. |
1217 ^ self openWithMode:ReadWriteMode |
1229 ^ self openWithMode:ReadWriteMode |
1218 ! |
1230 ! |
1219 |
1231 |
1220 openForReading |
1232 openForReading |
1221 "open the file for readonly. |
1233 "open the file for readonly. |
1222 If the file does not exist its an error, raise OpenError; |
1234 If the file does not exist its an error, raise OpenError; |
1223 otherwise return the receiver." |
1235 otherwise return the receiver." |
1224 |
1236 |
1225 mode := #readonly. |
1237 mode := #readonly. |
1226 didWrite := false. |
1238 didWrite := false. |
1227 ^ self openWithMode:ReadMode |
1239 ^ self openWithMode:ReadMode |
1228 ! |
1240 ! |
1229 |
1241 |
1230 openForWriting |
1242 openForWriting |
1231 "open the file writeonly. The contents of the file is preserved. |
1243 "open the file writeonly. The contents of the file is preserved. |
1232 If the file does not exist its an error, raise OpenError; |
1244 If the file does not exist its an error, raise OpenError; |
1233 otherwise return the receiver." |
1245 otherwise return the receiver." |
1234 |
1246 |
1235 mode := #writeonly. |
1247 mode := #writeonly. |
1236 didWrite := true. |
1248 didWrite := true. |
1237 "we must not truncate the file!! So do not use WriteMode" |
1249 "we must not truncate the file!! So do not use WriteMode" |