FileStream.st
changeset 8034 716b32d832bf
parent 7970 2ae69eb663eb
child 8039 6ef0379296cc
equal deleted inserted replaced
8033:1d053d9909a1 8034:716b32d832bf
   999      This argument is ignored in UNIX & MSDOS systems.
   999      This argument is ignored in UNIX & MSDOS systems.
  1000 
  1000 
  1001      This is a private entry, but maybe useful to open/create a file in a special mode,
  1001      This is a private entry, but maybe useful to open/create a file in a special mode,
  1002      which is proprietrary to the operatingSystem."
  1002      which is proprietrary to the operatingSystem."
  1003 
  1003 
  1004     |filePointer|
  1004     |wasBlocked|
  1005 
  1005 
  1006 %{
  1006 %{
  1007     HFILE f;
  1007     HFILE f;
  1008     HFILE fopen();
  1008     HFILE fopen();
  1009     OBJ fp;
  1009     OBJ fp;
  1010     int pass = 0;
  1010     int pass = 0;
  1011 
  1011 
  1012 retry:
  1012 retry:
  1013     if (__isNonNilObject(pathName) && (__qClass(pathName)==String)) {
  1013     if (__isNonNilObject(pathName) && (__qClass(pathName)==String)) {
  1014 #ifdef __VMS__
  1014 #ifdef __VMS__
  1015 	do {
  1015         do {
  1016 	    /*
  1016             /*
  1017 	     * allow passing additional RMS arguments.
  1017              * allow passing additional RMS arguments.
  1018 	     * stupid: DEC does not seem to offer an interface for passing a char **.
  1018              * stupid: DEC does not seem to offer an interface for passing a char **.
  1019 	     */
  1019              */
  1020 	    __threadErrno = 0;
  1020             __threadErrno = 0;
  1021 
  1021 
  1022 	    {
  1022             {
  1023 		if (__isArray(attributeSpec)) {
  1023                 if (__isArray(attributeSpec)) {
  1024 		    OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element;
  1024                     OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element;
  1025 		    int numAttrib = 0;
  1025                     int numAttrib = 0;
  1026 		    int i;
  1026                     int i;
  1027 
  1027 
  1028 		    numAttrib = __arraySize(attributeSpec);
  1028                     numAttrib = __arraySize(attributeSpec);
  1029 		    for (i=0; i<numAttrib;i++) {
  1029                     for (i=0; i<numAttrib;i++) {
  1030 			if (! __isString(ap[i])) {
  1030                         if (! __isString(ap[i])) {
  1031 			    f = NULL;
  1031                             f = NULL;
  1032 			    __threadErrno = EINVAL; /* invalid argument */
  1032                             __threadErrno = EINVAL; /* invalid argument */
  1033 			    goto getOutOfHere;
  1033                             goto getOutOfHere;
  1034 			}
  1034                         }
  1035 		    }
  1035                     }
  1036 		    switch (numAttrib) {
  1036                     switch (numAttrib) {
  1037 			case 0:
  1037                         case 0:
  1038 			    __BEGIN_INTERRUPTABLE__
  1038                             __BEGIN_INTERRUPTABLE__
  1039 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode));
  1039                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode));
  1040 			    __END_INTERRUPTABLE__
  1040                             __END_INTERRUPTABLE__
  1041 			    break;
  1041                             break;
  1042 			case 1:
  1042                         case 1:
  1043 			    __BEGIN_INTERRUPTABLE__
  1043                             __BEGIN_INTERRUPTABLE__
  1044 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1044                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1045 				      __stringVal(ap[0]));
  1045                                       __stringVal(ap[0]));
  1046 			    __END_INTERRUPTABLE__
  1046                             __END_INTERRUPTABLE__
  1047 			    break;
  1047                             break;
  1048 			case 2:
  1048                         case 2:
  1049 			    __BEGIN_INTERRUPTABLE__
  1049                             __BEGIN_INTERRUPTABLE__
  1050 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1050                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1051 				      __stringVal(ap[0]), __stringVal(ap[1]));
  1051                                       __stringVal(ap[0]), __stringVal(ap[1]));
  1052 			    __END_INTERRUPTABLE__
  1052                             __END_INTERRUPTABLE__
  1053 			    break;
  1053                             break;
  1054 			case 3:
  1054                         case 3:
  1055 			    __BEGIN_INTERRUPTABLE__
  1055                             __BEGIN_INTERRUPTABLE__
  1056 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1056                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1057 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]));
  1057                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]));
  1058 			    __END_INTERRUPTABLE__
  1058                             __END_INTERRUPTABLE__
  1059 			    break;
  1059                             break;
  1060 			case 4:
  1060                         case 4:
  1061 			    __BEGIN_INTERRUPTABLE__
  1061                             __BEGIN_INTERRUPTABLE__
  1062 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1062                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1063 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1063                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1064 				      __stringVal(ap[3]));
  1064                                       __stringVal(ap[3]));
  1065 			    __END_INTERRUPTABLE__
  1065                             __END_INTERRUPTABLE__
  1066 			    break;
  1066                             break;
  1067 			case 5:
  1067                         case 5:
  1068 			    __BEGIN_INTERRUPTABLE__
  1068                             __BEGIN_INTERRUPTABLE__
  1069 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1069                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1070 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1070                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1071 				      __stringVal(ap[3]), __stringVal(ap[4]));
  1071                                       __stringVal(ap[3]), __stringVal(ap[4]));
  1072 			    __END_INTERRUPTABLE__
  1072                             __END_INTERRUPTABLE__
  1073 			    break;
  1073                             break;
  1074 			case 6:
  1074                         case 6:
  1075 			    __BEGIN_INTERRUPTABLE__
  1075                             __BEGIN_INTERRUPTABLE__
  1076 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1076                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1077 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1077                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1078 				      __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]));
  1078                                       __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]));
  1079 			    __END_INTERRUPTABLE__
  1079                             __END_INTERRUPTABLE__
  1080 			    break;
  1080                             break;
  1081 			case 7:
  1081                         case 7:
  1082 			    __BEGIN_INTERRUPTABLE__
  1082                             __BEGIN_INTERRUPTABLE__
  1083 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1083                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1084 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1084                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1085 				      __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1085                                       __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1086 				      __stringVal(ap[6]));
  1086                                       __stringVal(ap[6]));
  1087 			    __END_INTERRUPTABLE__
  1087                             __END_INTERRUPTABLE__
  1088 			    break;
  1088                             break;
  1089 			case 8:
  1089                         case 8:
  1090 			    __BEGIN_INTERRUPTABLE__
  1090                             __BEGIN_INTERRUPTABLE__
  1091 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1091                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1092 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1092                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1093 				      __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1093                                       __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1094 				      __stringVal(ap[6]), __stringVal(ap[7]));
  1094                                       __stringVal(ap[6]), __stringVal(ap[7]));
  1095 			    __END_INTERRUPTABLE__
  1095                             __END_INTERRUPTABLE__
  1096 			    break;
  1096                             break;
  1097 			case 9:
  1097                         case 9:
  1098 			    __BEGIN_INTERRUPTABLE__
  1098                             __BEGIN_INTERRUPTABLE__
  1099 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1099                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1100 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1100                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1101 				      __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1101                                       __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1102 				      __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]));
  1102                                       __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]));
  1103 			    __END_INTERRUPTABLE__
  1103                             __END_INTERRUPTABLE__
  1104 			    break;
  1104                             break;
  1105 			case 10:
  1105                         case 10:
  1106 			    __BEGIN_INTERRUPTABLE__
  1106                             __BEGIN_INTERRUPTABLE__
  1107 			    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1107                             f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode),
  1108 				      __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1108                                       __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]),
  1109 				      __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1109                                       __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]),
  1110 				      __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]),
  1110                                       __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]),
  1111 				      __stringVal(ap[9]));
  1111                                       __stringVal(ap[9]));
  1112 			    __END_INTERRUPTABLE__
  1112                             __END_INTERRUPTABLE__
  1113 			    break;
  1113                             break;
  1114 			default:
  1114                         default:
  1115 			    f = NULL;
  1115                             f = NULL;
  1116 			    __threadErrno = E2BIG; /* too many args */
  1116                             __threadErrno = E2BIG; /* too many args */
  1117 			    goto getOutOfHere;
  1117                             goto getOutOfHere;
  1118 		    }
  1118                     }
  1119 		} else if (attributeSpec != nil) {
  1119                 } else if (attributeSpec != nil) {
  1120 		    f = NULL;
  1120                     f = NULL;
  1121 		    __threadErrno = EINVAL; /* invalid argument */
  1121                     __threadErrno = EINVAL; /* invalid argument */
  1122 		    goto getOutOfHere;
  1122                     goto getOutOfHere;
  1123 		} else {
  1123                 } else {
  1124 		    /*
  1124                     /*
  1125 		     * create file as sequential streamLF by default.
  1125                      * create file as sequential streamLF by default.
  1126 		     */
  1126                      */
  1127 		    __BEGIN_INTERRUPTABLE__
  1127                     __BEGIN_INTERRUPTABLE__
  1128 		    f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf");
  1128                     f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf");
  1129 		    __END_INTERRUPTABLE__
  1129                     __END_INTERRUPTABLE__
  1130 		}
  1130                 }
  1131 	    }
  1131             }
  1132 	} while ((f == NULL) && (__threadErrno == EINTR));
  1132         } while ((f == NULL) && (__threadErrno == EINTR));
  1133 
  1133 
  1134 #else /* not VMS */
  1134 #else /* not VMS */
  1135 
  1135 
  1136 # ifdef WIN32
  1136 # ifdef WIN32
  1137 	{
  1137         {
  1138 	    char _aPathName[MAXPATHLEN];
  1138             char _aPathName[MAXPATHLEN];
  1139 	    char _openMode[64];
  1139             char _openMode[64];
  1140 
  1140 
  1141 	    strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
  1141             strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
  1142 	    strncpy(_openMode, __stringVal(openmode), sizeof(_openMode)-1); _openMode[sizeof(_openMode)-1] = '\0';
  1142             strncpy(_openMode, __stringVal(openmode), sizeof(_openMode)-1); _openMode[sizeof(_openMode)-1] = '\0';
  1143 	    do {
  1143             do {
  1144 		__threadErrno = 0;
  1144                 __threadErrno = 0;
  1145 		f = STX_C_CALL2( "fopen", fopen, _aPathName, _openMode);
  1145                 f = STX_C_CALL2( "fopen", fopen, _aPathName, _openMode);
  1146 		if (__threadErrno == EINTR) {
  1146                 if (__threadErrno == EINTR) {
  1147 		    f = NULL;
  1147                     f = NULL;
  1148 		}
  1148                 }
  1149 	    } while ((f == NULL) && (__threadErrno == EINTR));
  1149             } while ((f == NULL) && (__threadErrno == EINTR));
  1150 	}
  1150         }
  1151 # else /* not WIN32 */
  1151 # else /* not WIN32 */
  1152 
  1152 
  1153 	do {
  1153         do {
  1154 	    __BEGIN_INTERRUPTABLE__
  1154             __BEGIN_INTERRUPTABLE__
  1155 #  ifdef LINUX
  1155 #  ifdef LINUX
  1156 	    /* 
  1156             /* 
  1157 	     * LINUX may ret a non-NULL f even when interrupted.
  1157              * LINUX may ret a non-NULL f even when interrupted.
  1158 	     * Therefore, check errno and fake a null-ret.
  1158              * Therefore, check errno and fake a null-ret.
  1159 	     */
  1159              */
  1160 	    __threadErrno = 0;
  1160             __threadErrno = 0;
  1161 	    f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
  1161             f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
  1162 	    if (__threadErrno == EINTR)
  1162             if (__threadErrno == EINTR)
  1163 		f = NULL;
  1163                 f = NULL;
  1164 #  else /* not LINUX */
  1164 #  else /* not LINUX */
  1165 	    f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
  1165             f = fopen((char *) __stringVal(pathName), (char *) __stringVal(openmode));
  1166 #  endif /* not LINUX */
  1166 #  endif /* not LINUX */
  1167 	    __END_INTERRUPTABLE__
  1167             __END_INTERRUPTABLE__
  1168 	} while ((f == NULL) && (__threadErrno == EINTR));
  1168         } while ((f == NULL) && (__threadErrno == EINTR));
  1169 
  1169 
  1170 # endif /* not WIN32 */
  1170 # endif /* not WIN32 */
  1171 #endif /* not VMS */
  1171 #endif /* not VMS */
  1172 
  1172 
  1173 	if (f == NULL) {
  1173         if (f == NULL) {
  1174 	    /*
  1174             /*
  1175 	     * If no filedescriptors available, try to finalize
  1175              * If no filedescriptors available, try to finalize
  1176 	     * possibly collected fd's and try again.
  1176              * possibly collected fd's and try again.
  1177 	     */
  1177              */
  1178 	    if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) {
  1178             if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) {
  1179 		pass = 1;
  1179                 pass = 1;
  1180 		__SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
  1180                 __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
  1181 		__SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
  1181                 __SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
  1182 		goto retry;
  1182                 goto retry;
  1183 	    }
  1183             }
  1184 	getOutOfHere: ;
  1184         getOutOfHere: ;
  1185 	    __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
  1185             __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
  1186 	    __INST(position) = nil;
  1186             __INST(position) = nil;
  1187 	} else {
  1187         } else {
  1188 #ifdef __VMS__
  1188 #ifdef __VMS__
  1189 	    /*
  1189             /*
  1190 	     * check to see if this is positionable ...
  1190              * check to see if this is positionable ...
  1191 	     */
  1191              */
  1192 	    __INST(canPosition) = false;
  1192             __INST(canPosition) = false;
  1193 # ifndef _POSIX_C_SOURCE
  1193 # ifndef _POSIX_C_SOURCE
  1194 	    {
  1194             {
  1195 		struct stat statBuffer;
  1195                 struct stat statBuffer;
  1196 
  1196 
  1197 		if (fstat(fileno(f), &statBuffer) >= 0) {
  1197                 if (fstat(fileno(f), &statBuffer) >= 0) {
  1198 		    switch (statBuffer.st_fab_rfm) {
  1198                     switch (statBuffer.st_fab_rfm) {
  1199 			case FAB$C_UDF: /* undefined (also stream binary)   */
  1199                         case FAB$C_UDF: /* undefined (also stream binary)   */
  1200 			case FAB$C_VAR: /* variable length records          */
  1200                         case FAB$C_VAR: /* variable length records          */
  1201 			case FAB$C_VFC: /* variable fixed control           */
  1201                         case FAB$C_VFC: /* variable fixed control           */
  1202 			case FAB$C_STM: /* RMS-11 stream (valid only for sequen> */
  1202                         case FAB$C_STM: /* RMS-11 stream (valid only for sequen> */
  1203 			default:
  1203                         default:
  1204 			    __INST(canPosition) = false;
  1204                             __INST(canPosition) = false;
  1205 			    break;
  1205                             break;
  1206 
  1206 
  1207 			case FAB$C_FIX: /* fixed length records             */
  1207                         case FAB$C_FIX: /* fixed length records             */
  1208 			case FAB$C_STMLF: /* LF stream (valid only for sequential> */
  1208                         case FAB$C_STMLF: /* LF stream (valid only for sequential> */
  1209 			case FAB$C_STMCR: /* CR stream (valid only for sequential> */
  1209                         case FAB$C_STMCR: /* CR stream (valid only for sequential> */
  1210 			    __INST(canPosition) = true;
  1210                             __INST(canPosition) = true;
  1211 			    break;
  1211                             break;
  1212 		    }
  1212                     }
  1213 		}
  1213                 }
  1214 	    }
  1214             }
  1215 # endif 
  1215 # endif 
  1216 #else /* not VMS */
  1216 #else /* not VMS */
  1217 	    __INST(canPosition) = true;
  1217             __INST(canPosition) = true;
  1218 #endif /* poor VMS */
  1218 #endif /* poor VMS */
  1219 
  1219 
  1220 	    if (@global(FileOpenTrace) == true) {
  1220             if (@global(FileOpenTrace) == true) {
  1221 		fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f);
  1221                 fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f);
  1222 	    }
  1222             }
  1223 
  1223             if (f != NULL) {
  1224 	    filePointer = __MKOBJ((INT)f); 
  1224                 wasBlocked = __BLOCKINTERRUPTS();
  1225 	    __INST(position) = @global(PositionableStream:ZeroPosition);
  1225                 __INST(filePointer) = __MKOBJ((INT)f); 
  1226 	}
  1226             }
       
  1227             __INST(position) = @global(PositionableStream:ZeroPosition);
       
  1228         }
  1227     }
  1229     }
  1228 %}.
  1230 %}.
       
  1231     filePointer notNil ifTrue:[
       
  1232         Lobby register:self.
       
  1233         wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts].
       
  1234     ].
  1229     ^ filePointer
  1235     ^ filePointer
  1230 !
  1236 !
  1231 
  1237 
  1232 openForAppending
  1238 openForAppending
  1233     "open the file for writeonly appending to the end.
  1239     "open the file for writeonly appending to the end.
  1296 
  1302 
  1297     filePointer notNil ifTrue:[^ self errorAlreadyOpen].
  1303     filePointer notNil ifTrue:[^ self errorAlreadyOpen].
  1298 
  1304 
  1299     filePointer := self openFile:pathName withMode:openmode attributes:attributeSpec.
  1305     filePointer := self openFile:pathName withMode:openmode attributes:attributeSpec.
  1300     filePointer isNil ifTrue:[
  1306     filePointer isNil ifTrue:[
  1301 	"
  1307         "
  1302 	 the open failed for some reason ...
  1308          the open failed for some reason ...
  1303 	"
  1309         "
  1304 	^ self openError
  1310         ^ self openError
  1305     ].
  1311     ].
  1306     position := ZeroPosition.
  1312     position := ZeroPosition.
  1307     buffered := true.       "default is buffered"
  1313     buffered := true.       "default is buffered"
  1308     Lobby register:self.
       
  1309 !
  1314 !
  1310 
  1315 
  1311 pathName:filename
  1316 pathName:filename
  1312     "set the pathname"
  1317     "set the pathname"
  1313 
  1318 
  1441 ! !
  1446 ! !
  1442 
  1447 
  1443 !FileStream class methodsFor:'documentation'!
  1448 !FileStream class methodsFor:'documentation'!
  1444 
  1449 
  1445 version
  1450 version
  1446     ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.104 2004-02-19 14:13:00 cg Exp $'
  1451     ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.105 2004-03-02 14:16:08 ca Exp $'
  1447 ! !
  1452 ! !
  1448 
  1453 
  1449 FileStream initialize!
  1454 FileStream initialize!