FileStream.st
changeset 5120 13143fbcbdf8
parent 4910 33b0edbb1920
child 5186 ed0c5597034f
equal deleted inserted replaced
5119:3103440ffcc7 5120:13143fbcbdf8
    20 !FileStream primitiveDefinitions!
    20 !FileStream primitiveDefinitions!
    21 %{
    21 %{
    22 
    22 
    23 #include <stdio.h>
    23 #include <stdio.h>
    24 #define _STDIO_H_INCLUDED_
    24 #define _STDIO_H_INCLUDED_
    25 
       
    26 
    25 
    27 #include <errno.h>
    26 #include <errno.h>
    28 #define _ERRNO_H_INCLUDED_
    27 #define _ERRNO_H_INCLUDED_
    29 
    28 
    30 #ifdef transputer
    29 #ifdef transputer
    94 # undef Point
    93 # undef Point
    95 # undef Rectangle
    94 # undef Rectangle
    96 # undef Block
    95 # undef Block
    97 # undef Time
    96 # undef Time
    98 # undef Date
    97 # undef Date
       
    98 # undef Set
       
    99 # undef Delay
       
   100 # undef Signal
    99 
   101 
   100 # define NOATOM
   102 # define NOATOM
   101 # define NOGDICAPMASKS
   103 # define NOGDICAPMASKS
   102 # define NOMETAFILE
   104 # define NOMETAFILE
   103 # define NOMINMAX
   105 # define NOMINMAX
   136 #  define Time __DEF_Time
   138 #  define Time __DEF_Time
   137 # endif
   139 # endif
   138 # ifdef __DEF_Date
   140 # ifdef __DEF_Date
   139 #  define Date __DEF_Date
   141 #  define Date __DEF_Date
   140 # endif
   142 # endif
       
   143 # ifdef __DEF_Set
       
   144 #  define Set __DEF_Set
       
   145 # endif
       
   146 # ifdef __DEF_Signal
       
   147 #  define Signal __DEF_Signal
       
   148 # endif
       
   149 # ifdef __DEF_Delay
       
   150 #  define Delay __DEF_Delay
       
   151 # endif
   141 
   152 
   142 # define INT int
   153 # define INT int
   143 
   154 
   144 # ifdef NO_STDIO
   155 # ifdef NO_STDIO
   145 
   156 
   632 		currentPosition = ftell(f);
   643 		currentPosition = ftell(f);
   633 	    } else {
   644 	    } else {
   634 		currentPosition = lseek(fileno(f), 0L, SEEK_CUR);
   645 		currentPosition = lseek(fileno(f), 0L, SEEK_CUR);
   635 	    }
   646 	    }
   636 #endif
   647 #endif
   637 	} while ((currentPosition < 0) && (errno == EINTR));
   648 	} while ((currentPosition < 0) && (__threadErrno == EINTR));
   638 	if (currentPosition >= 0) {
   649 	if (currentPosition >= 0) {
   639 	    /*
   650 	    /*
   640 	     * notice: Smalltalk index starts at 1
   651 	     * notice: Smalltalk index starts at 1
   641 	     */
   652 	     */
   642 	    RETURN ( __MKSMALLINT(currentPosition + 1) );
   653 	    RETURN ( __MKSMALLINT(currentPosition + 1) );
   643 	}
   654 	}
   644 	__INST(lastErrorNumber) = __MKSMALLINT(errno);
   655 	__INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
   645     }
   656     }
   646 %}.
   657 %}.
   647     lastErrorNumber notNil ifTrue:[^ self ioError].
   658     lastErrorNumber notNil ifTrue:[^ self ioError].
   648     filePointer isNil ifTrue:[^ self errorNotOpen].
   659     filePointer isNil ifTrue:[^ self errorNotOpen].
   649     ^ self primitiveFailed
   660     ^ self primitiveFailed
   679 			ret = fseek(f, nP, SEEK_SET);
   690 			ret = fseek(f, nP, SEEK_SET);
   680 		    } else {
   691 		    } else {
   681 			ret = lseek(fileno(f), nP, SEEK_SET);
   692 			ret = lseek(fileno(f), nP, SEEK_SET);
   682 		    }
   693 		    }
   683 #endif
   694 #endif
   684 		} while ((ret < 0) && (errno == EINTR));
   695 		} while ((ret < 0) && (__threadErrno == EINTR));
   685 		if (ret >= 0) {
   696 		if (ret >= 0) {
   686 		    __INST(position) = newPos;
   697 		    __INST(position) = newPos;
   687 		    /*
   698 		    /*
   688 		     * just to make certain ...
   699 		     * just to make certain ...
   689 		     */
   700 		     */
   690 		    __INST(hitEOF) = false;
   701 		    __INST(hitEOF) = false;
   691 		    RETURN ( self );
   702 		    RETURN ( self );
   692 		}
   703 		}
   693 		__INST(lastErrorNumber) = __MKSMALLINT(errno);
   704 		__INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
   694 	    }
   705 	    }
   695 	}
   706 	}
   696     }
   707     }
   697 %}.
   708 %}.
   698     canPosition == false ifTrue:[
   709     canPosition == false ifTrue:[
   730 		ret = fseek(f, 0L, SEEK_END);
   741 		ret = fseek(f, 0L, SEEK_END);
   731 	    } else {
   742 	    } else {
   732 		ret = lseek(fileno(f), 0L, SEEK_END);
   743 		ret = lseek(fileno(f), 0L, SEEK_END);
   733 	    }
   744 	    }
   734 #endif
   745 #endif
   735 	} while ((ret < 0) && (errno == EINTR));
   746 	} while ((ret < 0) && (__threadErrno == EINTR));
   736 	if (ret >= 0) {
   747 	if (ret >= 0) {
   737 	    RETURN ( self );
   748 	    RETURN ( self );
   738 	}
   749 	}
   739 	__INST(lastErrorNumber) = __MKSMALLINT(errno);
   750 	__INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
   740     }
   751     }
   741 %}.
   752 %}.
   742     lastErrorNumber notNil ifTrue:[^ self ioError].
   753     lastErrorNumber notNil ifTrue:[^ self ioError].
   743     filePointer isNil ifTrue:[^ self errorNotOpen].
   754     filePointer isNil ifTrue:[^ self errorNotOpen].
   744     ^ self primitiveFailed
   755     ^ self primitiveFailed
   918 	do {
   929 	do {
   919 	    /*
   930 	    /*
   920 	     * allow passing additional RMS arguments.
   931 	     * allow passing additional RMS arguments.
   921 	     * stupid: DEC does not seem to offer an interface for passing a char **.
   932 	     * stupid: DEC does not seem to offer an interface for passing a char **.
   922 	     */
   933 	     */
   923 	    errno = 0;
   934 	    __threadErrno = 0;
   924 
   935 
   925 	    {
   936 	    {
   926 		if (__isArray(attributeSpec)) {
   937 		if (__isArray(attributeSpec)) {
   927 		    OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element;
   938 		    OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element;
   928 		    int numAttrib = 0;
   939 		    int numAttrib = 0;
   930 
   941 
   931 		    numAttrib = __arraySize(attributeSpec);
   942 		    numAttrib = __arraySize(attributeSpec);
   932 		    for (i=0; i<numAttrib;i++) {
   943 		    for (i=0; i<numAttrib;i++) {
   933 			if (! __isString(ap[i])) {
   944 			if (! __isString(ap[i])) {
   934 			    f = NULL;
   945 			    f = NULL;
   935 			    errno = EINVAL; /* invalid argument */
   946 			    __threadErrno = EINVAL; /* invalid argument */
   936 			    goto getOutOfHere;
   947 			    goto getOutOfHere;
   937 			}
   948 			}
   938 		    }
   949 		    }
   939 		    switch (numAttrib) {
   950 		    switch (numAttrib) {
   940 			case 0:
   951 			case 0:
  1014 				      __stringVal(ap[9]));
  1025 				      __stringVal(ap[9]));
  1015 			    __END_INTERRUPTABLE__
  1026 			    __END_INTERRUPTABLE__
  1016 			    break;
  1027 			    break;
  1017 			default:
  1028 			default:
  1018 			    f = NULL;
  1029 			    f = NULL;
  1019 			    errno = E2BIG; /* too many args */
  1030 			    __threadErrno = E2BIG; /* too many args */
  1020 			    goto getOutOfHere;
  1031 			    goto getOutOfHere;
  1021 		    }
  1032 		    }
  1022 		} else if (attributeSpec != nil) {
  1033 		} else if (attributeSpec != nil) {
  1023 		    f = NULL;
  1034 		    f = NULL;
  1024 		    errno = EINVAL; /* invalid argument */
  1035 		    __threadErrno = EINVAL; /* invalid argument */
  1025 		    goto getOutOfHere;
  1036 		    goto getOutOfHere;
  1026 		} else {
  1037 		} else {
  1027 		    /*
  1038 		    /*
  1028 		     * create file as sequential streamLF by default.
  1039 		     * create file as sequential streamLF by default.
  1029 		     */
  1040 		     */
  1032 		    __END_INTERRUPTABLE__
  1043 		    __END_INTERRUPTABLE__
  1033 		}
  1044 		}
  1034 	    }
  1045 	    }
  1035 	    /* must refetch - could be GC'd */
  1046 	    /* must refetch - could be GC'd */
  1036 	    path = __INST(pathName);
  1047 	    path = __INST(pathName);
  1037 	} while ((f == NULL) && (errno == EINTR));
  1048 	} while ((f == NULL) && (__threadErrno == EINTR));
  1038 
  1049 
  1039 #else /* not VMS */
  1050 #else /* not VMS */
  1040 
  1051 
  1041 # ifdef WIN32
  1052 # ifdef WIN32
  1042 
  1053 
  1053 	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode)); 
  1064 	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode)); 
  1054 	    __END_INTERRUPTABLE__
  1065 	    __END_INTERRUPTABLE__
  1055 #  endif /* use_STDIO */
  1066 #  endif /* use_STDIO */
  1056 	    /* must refetch - could be GC'd */
  1067 	    /* must refetch - could be GC'd */
  1057 	    path = __INST(pathName);
  1068 	    path = __INST(pathName);
  1058 	} while ((f == NULL) && (errno == EINTR));
  1069 	} while ((f == NULL) && (__threadErrno == EINTR));
  1059 
  1070 
  1060 # else /* not WIN32 */
  1071 # else /* not WIN32 */
  1061 
  1072 
  1062 	do {
  1073 	do {
  1063 	    __BEGIN_INTERRUPTABLE__
  1074 	    __BEGIN_INTERRUPTABLE__
  1064 #  ifdef LINUX
  1075 #  ifdef LINUX
  1065 	    /* 
  1076 	    /* 
  1066 	     * LINUX may ret a non-NULL f even when interrupted.
  1077 	     * LINUX may ret a non-NULL f even when interrupted.
  1067 	     * Therefore, check errno and fake a null-ret.
  1078 	     * Therefore, check errno and fake a null-ret.
  1068 	     */
  1079 	     */
  1069 	    errno = 0;
  1080 	    __threadErrno = 0;
  1070 	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
  1081 	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
  1071 	    if (errno == EINTR)
  1082 	    if (__threadErrno == EINTR)
  1072 		f = NULL;
  1083 		f = NULL;
  1073 #  else /* not LINUX */
  1084 #  else /* not LINUX */
  1074 	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
  1085 	    f = fopen((char *) __stringVal(path), (char *) __stringVal(openmode));
  1075 #  endif /* not LINUX */
  1086 #  endif /* not LINUX */
  1076 	    __END_INTERRUPTABLE__
  1087 	    __END_INTERRUPTABLE__
  1077 	    /* must refetch - could be GC'd */
  1088 	    /* must refetch - could be GC'd */
  1078 	    path = __INST(pathName);
  1089 	    path = __INST(pathName);
  1079 	} while ((f == NULL) && (errno == EINTR));
  1090 	} while ((f == NULL) && (__threadErrno == EINTR));
  1080 
  1091 
  1081 # endif /* not WIN32 */
  1092 # endif /* not WIN32 */
  1082 #endif /* not VMS */
  1093 #endif /* not VMS */
  1083 
  1094 
  1084 	if (f == NULL) {
  1095 	if (f == NULL) {
  1085 	    /*
  1096 	    /*
  1086 	     * If no filedescriptors available, try to finalize
  1097 	     * If no filedescriptors available, try to finalize
  1087 	     * possibly collected fd's and try again.
  1098 	     * possibly collected fd's and try again.
  1088 	     */
  1099 	     */
  1089 	    if (pass == 0 && (errno == ENFILE || errno == EMFILE)) {
  1100 	    if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) {
  1090 		pass = 1;
  1101 		pass = 1;
  1091 		__SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
  1102 		__SSEND0(@global(ObjectMemory), @symbol(scavenge), 0);
  1092 		__SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
  1103 		__SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
  1093 		goto retry;
  1104 		goto retry;
  1094 	    }
  1105 	    }
  1095 	getOutOfHere: ;
  1106 	getOutOfHere: ;
  1096 	    __INST(lastErrorNumber) = __MKSMALLINT(errno);
  1107 	    __INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
  1097 	    __INST(position) = nil;
  1108 	    __INST(position) = nil;
  1098 	} else {
  1109 	} else {
  1099 #ifdef __VMS__
  1110 #ifdef __VMS__
  1100 	    /*
  1111 	    /*
  1101 	     * check to see if this is positionable ...
  1112 	     * check to see if this is positionable ...
  1216     if (__INST(filePointer) != nil) {
  1227     if (__INST(filePointer) != nil) {
  1217 	f = __FILEVal(__INST(filePointer));
  1228 	f = __FILEVal(__INST(filePointer));
  1218 	fd = fileno(f);
  1229 	fd = fileno(f);
  1219 	do {
  1230 	do {
  1220 	    ret = fstat(fd, &buf);
  1231 	    ret = fstat(fd, &buf);
  1221 	} while ((ret < 0) && (errno == EINTR));
  1232 	} while ((ret < 0) && (__threadErrno == EINTR));
  1222 	if (ret >= 0) {
  1233 	if (ret >= 0) {
  1223 	    RETURN ( __MKSMALLINT(buf.st_size) );
  1234 	    RETURN ( __MKSMALLINT(buf.st_size) );
  1224 	}
  1235 	}
  1225 	__INST(lastErrorNumber) = __MKSMALLINT(errno);
  1236 	__INST(lastErrorNumber) = __MKSMALLINT(__threadErrno);
  1226     }
  1237     }
  1227 #endif
  1238 #endif
  1228 %}.
  1239 %}.
  1229 
  1240 
  1230     "could add a fall-back here:
  1241     "could add a fall-back here:
  1262 ! !
  1273 ! !
  1263 
  1274 
  1264 !FileStream class methodsFor:'documentation'!
  1275 !FileStream class methodsFor:'documentation'!
  1265 
  1276 
  1266 version
  1277 version
  1267     ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.68 1999-10-14 23:51:01 cg Exp $'
  1278     ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.69 1999-12-17 11:35:52 cg Exp $'
  1268 ! !
  1279 ! !
  1269 FileStream initialize!
  1280 FileStream initialize!