ExternalStream.st
changeset 23032 3555c5883830
parent 22978 589f146aebcd
child 23110 6c43a792029a
equal deleted inserted replaced
23031:9baa6604dedb 23032:3555c5883830
     1 "{ Encoding: utf8 }"
     1 "{ Encoding: utf8 }"
     2 
     2 
     3 "
     3 "
     4  COPYRIGHT (c) 1988 by Claus Gittinger
     4  COPYRIGHT (c) 1988 by Claus Gittinger
     5               All Rights Reserved
     5 	      All Rights Reserved
     6 
     6 
     7  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
     8  only in accordance with the terms of that license and with the
     8  only in accordance with the terms of that license and with the
     9  inclusion of the above copyright notice.   This software may not
     9  inclusion of the above copyright notice.   This software may not
    10  be provided or otherwise made available to, or used by, any
    10  be provided or otherwise made available to, or used by, any
   204 #ifdef DEBUGGING
   204 #ifdef DEBUGGING
   205   extern char *__survStartPtr, *__survEndPtr;
   205   extern char *__survStartPtr, *__survEndPtr;
   206 # define DEBUGBUFFER(buf)  \
   206 # define DEBUGBUFFER(buf)  \
   207     if (((char *)(buf) >= __survStartPtr) \
   207     if (((char *)(buf) >= __survStartPtr) \
   208      && ((char *)(buf) < __survEndPtr)) { \
   208      && ((char *)(buf) < __survEndPtr)) { \
   209         __fatal0("read into survivor\n"); \
   209 	__fatal0("read into survivor\n"); \
   210     }
   210     }
   211 
   211 
   212 #else
   212 #else
   213 # define DEBUGBUFFER(buf) /* nothing */
   213 # define DEBUGBUFFER(buf) /* nothing */
   214 #endif
   214 #endif
   225 # define OPT_FSEEK(f, pos, whence)      /* nothing */
   225 # define OPT_FSEEK(f, pos, whence)      /* nothing */
   226 #endif
   226 #endif
   227 
   227 
   228 #ifdef __win32__
   228 #ifdef __win32__
   229 #  define READ(ret, f, cp, n, handleType) { \
   229 #  define READ(ret, f, cp, n, handleType) { \
   230         if (handleType == @symbol(socketHandle)) { \
   230 	if (handleType == @symbol(socketHandle)) { \
   231           (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \
   231 	  (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \
   232         } else { \
   232 	} else { \
   233           HANDLE h = _get_osfhandle(fileno(f)); \
   233 	  HANDLE h = _get_osfhandle(fileno(f)); \
   234           if (handleType == @symbol(socketFilePointer)) { \
   234 	  if (handleType == @symbol(socketFilePointer)) { \
   235             (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   235 	    (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   236           } else { \
   236 	  } else { \
   237             int __res; \
   237 	    int __res; \
   238             (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   238 	    (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   239             (ret) = (ret) > 0 ? __res : (__threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1); \
   239 	    (ret) = (ret) > 0 ? __res : (__threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1); \
   240           } \
   240 	  } \
   241         } \
   241 	} \
   242       }
   242       }
   243 
   243 
   244 #  define WRITE(ret, f, cp, n, handleType) { \
   244 #  define WRITE(ret, f, cp, n, handleType) { \
   245         if (handleType == @symbol(socketHandle)) { \
   245 	if (handleType == @symbol(socketHandle)) { \
   246           (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \
   246 	  (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \
   247         } else {\
   247 	} else {\
   248           HANDLE h = _get_osfhandle(fileno(f)); \
   248 	  HANDLE h = _get_osfhandle(fileno(f)); \
   249           if (handleType == @symbol(socketFilePointer)) { \
   249 	  if (handleType == @symbol(socketFilePointer)) { \
   250             (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   250 	    (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   251           } else {\
   251 	  } else {\
   252             int __res; \
   252 	    int __res; \
   253             (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\
   253 	    (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\
   254             (ret) = (ret) ? __res : -1; \
   254 	    (ret) = (ret) ? __res : -1; \
   255           } \
   255 	  } \
   256         } \
   256 	} \
   257       }
   257       }
   258 
   258 
   259 # define FFLUSH(fp)             fflush(fp)
   259 # define FFLUSH(fp)             fflush(fp)
   260 # undef STDIO_NEEDS_FSEEK
   260 # undef STDIO_NEEDS_FSEEK
   261 # define FILEPOINTER            FILE *
   261 # define FILEPOINTER            FILE *
   262 # define FILENO(f)              fileno(f)
   262 # define FILENO(f)              fileno(f)
   263 
   263 
   264 # define __READING__(f)                          \
   264 # define __READING__(f)                          \
   265     if ((__INST(didWrite) != false)              \
   265     if ((__INST(didWrite) != false)              \
   266      && (__INST(mode) == @symbol(readwrite))) {  \
   266      && (__INST(mode) == @symbol(readwrite))) {  \
   267         __INST(didWrite) = false;                \
   267 	__INST(didWrite) = false;                \
   268         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   268 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   269     }
   269     }
   270 
   270 
   271 # define __WRITING__(f)                          \
   271 # define __WRITING__(f)                          \
   272     if ((__INST(didWrite) != true)               \
   272     if ((__INST(didWrite) != true)               \
   273      && (__INST(mode) == @symbol(readwrite))) {  \
   273      && (__INST(mode) == @symbol(readwrite))) {  \
   274         __INST(didWrite) = true;                 \
   274 	__INST(didWrite) = true;                 \
   275         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   275 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   276     }
   276     }
   277 
   277 
   278 # define __UNGETC__(c, f, isBuffered)                   \
   278 # define __UNGETC__(c, f, isBuffered)                   \
   279     if (isBuffered) {                                   \
   279     if (isBuffered) {                                   \
   280         ungetc((c), (f));                               \
   280 	ungetc((c), (f));                               \
   281     } else {                                            \
   281     } else {                                            \
   282       __INST(readAhead) = __mkSmallInteger((c));        \
   282       __INST(readAhead) = __mkSmallInteger((c));        \
   283     }
   283     }
   284 
   284 
   285 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \
   285 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \
   286     if (isBuffered) {                                   \
   286     if (isBuffered) {                                   \
   287         for (;;) {                                      \
   287 	for (;;) {                                      \
   288             CLEAR_ERRNO;                                \
   288 	    CLEAR_ERRNO;                                \
   289             (ret) = getc(f);                            \
   289 	    (ret) = getc(f);                            \
   290             if ((ret) >= 0) {                           \
   290 	    if ((ret) >= 0) {                           \
   291                 *(buf) = (ret);                         \
   291 		*(buf) = (ret);                         \
   292                 (ret) = 1;                              \
   292 		(ret) = 1;                              \
   293             } else if (ferror(f)) {                     \
   293 	    } else if (ferror(f)) {                     \
   294                 if (__threadErrno == EINTR) {           \
   294 		if (__threadErrno == EINTR) {           \
   295                     clearerr(f);                        \
   295 		    clearerr(f);                        \
   296                     continue;                           \
   296 		    continue;                           \
   297                 }                                       \
   297 		}                                       \
   298             } else {                                    \
   298 	    } else {                                    \
   299                 (ret) = 0;                              \
   299 		(ret) = 0;                              \
   300             }                                           \
   300 	    }                                           \
   301             break;                                      \
   301 	    break;                                      \
   302         }                                               \
   302 	}                                               \
   303     } else {                                            \
   303     } else {                                            \
   304         OBJ rA = __INST(readAhead);                     \
   304 	OBJ rA = __INST(readAhead);                     \
   305         if (rA != nil) {                                \
   305 	if (rA != nil) {                                \
   306             *(buf) = (char)__intVal(rA);                \
   306 	    *(buf) = (char)__intVal(rA);                \
   307             __INST(readAhead) = nil;                    \
   307 	    __INST(readAhead) = nil;                    \
   308             (ret) = 1;                                  \
   308 	    (ret) = 1;                                  \
   309         } else {                                        \
   309 	} else {                                        \
   310             for (;;) {                                  \
   310 	    for (;;) {                                  \
   311                 CLEAR_ERRNO;                            \
   311 		CLEAR_ERRNO;                            \
   312                 READ((ret), f, buf, 1, handleType);       \
   312 		READ((ret), f, buf, 1, handleType);       \
   313                 if ((ret) >= 0 || __threadErrno != EINTR) \
   313 		if ((ret) >= 0 || __threadErrno != EINTR) \
   314                     break;                              \
   314 		    break;                              \
   315             }                                           \
   315 	    }                                           \
   316         }                                               \
   316 	}                                               \
   317     }
   317     }
   318 
   318 
   319   /*
   319   /*
   320    * read_bytes into a c-buffer
   320    * read_bytes into a c-buffer
   321    * (which may NOT move)
   321    * (which may NOT move)
   322    */
   322    */
   323 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
   323 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
   324     (ret) = 0;                                          \
   324     (ret) = 0;                                          \
   325     if (isBuffered) {                                   \
   325     if (isBuffered) {                                   \
   326         int __offs = 0;                                 \
   326 	int __offs = 0;                                 \
   327         while (__offs < (cnt)) {                        \
   327 	while (__offs < (cnt)) {                        \
   328             CLEAR_ERRNO;                                \
   328 	    CLEAR_ERRNO;                                \
   329             (ret) = getc(f);                            \
   329 	    (ret) = getc(f);                            \
   330             if ((ret) < 0) {                            \
   330 	    if ((ret) < 0) {                            \
   331                 if (ferror(f)) {                        \
   331 		if (ferror(f)) {                        \
   332                     if (__threadErrno == EINTR) {       \
   332 		    if (__threadErrno == EINTR) {       \
   333                         clearerr(f);                    \
   333 			clearerr(f);                    \
   334                         continue;                       \
   334 			continue;                       \
   335                     }                                   \
   335 		    }                                   \
   336                 } else {                                \
   336 		} else {                                \
   337                     (ret) = 0;                          \
   337 		    (ret) = 0;                          \
   338                 }                                       \
   338 		}                                       \
   339                 break;                                  \
   339 		break;                                  \
   340             }                                           \
   340 	    }                                           \
   341             (buf)[__offs++] = (ret);                    \
   341 	    (buf)[__offs++] = (ret);                    \
   342         }                                               \
   342 	}                                               \
   343         if (__offs > 0)                                 \
   343 	if (__offs > 0)                                 \
   344             (ret) = __offs;                             \
   344 	    (ret) = __offs;                             \
   345     } else {                                            \
   345     } else {                                            \
   346         int __offs = 0;                                 \
   346 	int __offs = 0;                                 \
   347                                                         \
   347 							\
   348         while (__offs < (cnt)) {                        \
   348 	while (__offs < (cnt)) {                        \
   349             OBJ rA = __INST(readAhead);                 \
   349 	    OBJ rA = __INST(readAhead);                 \
   350             if (rA != nil) {                            \
   350 	    if (rA != nil) {                            \
   351                 (buf)[__offs] = __intVal(rA);           \
   351 		(buf)[__offs] = __intVal(rA);           \
   352                 __INST(readAhead) = nil;                \
   352 		__INST(readAhead) = nil;                \
   353                 (ret) = 1;                              \
   353 		(ret) = 1;                              \
   354             } else {                                    \
   354 	    } else {                                    \
   355                 CLEAR_ERRNO;                            \
   355 		CLEAR_ERRNO;                            \
   356                 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   356 		READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   357                 if ((ret) <= 0) {                       \
   357 		if ((ret) <= 0) {                       \
   358                     if ((ret) < 0 && __threadErrno == EINTR) {  \
   358 		    if ((ret) < 0 && __threadErrno == EINTR) {  \
   359                         continue;                       \
   359 			continue;                       \
   360                     }                                   \
   360 		    }                                   \
   361                     break;                              \
   361 		    break;                              \
   362                 }                                       \
   362 		}                                       \
   363             }                                           \
   363 	    }                                           \
   364             __offs += (ret);                            \
   364 	    __offs += (ret);                            \
   365         }                                               \
   365 	}                                               \
   366         if (__offs > 0)                                 \
   366 	if (__offs > 0)                                 \
   367             (ret) = __offs;                             \
   367 	    (ret) = __offs;                             \
   368    }
   368    }
   369 
   369 
   370 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   370 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   371   {                                                     \
   371   {                                                     \
   372     int __offs = 0;                                     \
   372     int __offs = 0;                                     \
   373     int oldFlags;                                       \
   373     int oldFlags;                                       \
   374                                                         \
   374 							\
   375     (ret) = 0;                                          \
   375     (ret) = 0;                                          \
   376     if (isBuffered) {                                   \
   376     if (isBuffered) {                                   \
   377         while (__offs < (cnt)) {                        \
   377 	while (__offs < (cnt)) {                        \
   378             CLEAR_ERRNO;                                \
   378 	    CLEAR_ERRNO;                                \
   379             (ret) = getc(f);                            \
   379 	    (ret) = getc(f);                            \
   380             if ((ret) < 0) {                            \
   380 	    if ((ret) < 0) {                            \
   381                 if (ferror(f)) {                        \
   381 		if (ferror(f)) {                        \
   382                     if (__threadErrno == EINTR) {       \
   382 		    if (__threadErrno == EINTR) {       \
   383                         clearerr(f);                    \
   383 			clearerr(f);                    \
   384                         continue;                       \
   384 			continue;                       \
   385                     }                                   \
   385 		    }                                   \
   386                 } else {                                \
   386 		} else {                                \
   387                     (ret) = 0;                          \
   387 		    (ret) = 0;                          \
   388                 }                                       \
   388 		}                                       \
   389                 break;                                  \
   389 		break;                                  \
   390             }                                           \
   390 	    }                                           \
   391             (buf)[__offs++] = (ret);                    \
   391 	    (buf)[__offs++] = (ret);                    \
   392         }                                               \
   392 	}                                               \
   393         if (__offs > 0)                                 \
   393 	if (__offs > 0)                                 \
   394             (ret) = __offs;                             \
   394 	    (ret) = __offs;                             \
   395     } else {                                            \
   395     } else {                                            \
   396         while (__offs < (cnt)) {                        \
   396 	while (__offs < (cnt)) {                        \
   397             OBJ rA = __INST(readAhead);                 \
   397 	    OBJ rA = __INST(readAhead);                 \
   398             if (rA != nil) {                            \
   398 	    if (rA != nil) {                            \
   399                 (buf)[__offs] = __intVal(rA);           \
   399 		(buf)[__offs] = __intVal(rA);           \
   400                 __INST(readAhead) = nil;                \
   400 		__INST(readAhead) = nil;                \
   401                 (ret) = 1;                              \
   401 		(ret) = 1;                              \
   402                 __offs ++;                              \
   402 		__offs ++;                              \
   403                 continue;                               \
   403 		continue;                               \
   404             }                                           \
   404 	    }                                           \
   405             CLEAR_ERRNO;                                \
   405 	    CLEAR_ERRNO;                                \
   406             {                                           \
   406 	    {                                           \
   407               int res = -1, ok = 0;                     \
   407 	      int res = -1, ok = 0;                     \
   408               SOCKET sock = 0;                          \
   408 	      SOCKET sock = 0;                          \
   409               if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   409 	      if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   410                   || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   410 		  || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   411                   || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   411 		  || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   412                    if (!ok) {                                                               \
   412 		   if (!ok) {                                                               \
   413                         __threadErrno = sock ? WSAGetLastError() : __WIN32_ERR(GetLastError()); \
   413 			__threadErrno = sock ? WSAGetLastError() : __WIN32_ERR(GetLastError()); \
   414                         (ret) = __threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1;   \
   414 			(ret) = __threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1;   \
   415                         break;                                                              \
   415 			break;                                                              \
   416                    }                                \
   416 		   }                                \
   417                   if (res > 0) {                        \
   417 		  if (res > 0) {                        \
   418                       if (res > ((cnt)-__offs))         \
   418 		      if (res > ((cnt)-__offs))         \
   419                           res = (cnt)-__offs;           \
   419 			  res = (cnt)-__offs;           \
   420                       READ((ret), f, (buf)+__offs, res, handleType); \
   420 		      READ((ret), f, (buf)+__offs, res, handleType); \
   421                   } else {                              \
   421 		  } else {                              \
   422                       if (sock && send(sock, NULL, 0, 0) == SOCKET_ERROR) {     \
   422 		      if (sock && send(sock, NULL, 0, 0) == SOCKET_ERROR) {     \
   423                         (ret) = -1; __threadErrno = WSAGetLastError();          \
   423 			(ret) = -1; __threadErrno = WSAGetLastError();          \
   424                       } else {                          \
   424 		      } else {                          \
   425                         (ret) = 0;                      \
   425 			(ret) = 0;                      \
   426                       }                                 \
   426 		      }                                 \
   427                       break;                            \
   427 		      break;                            \
   428                   }                                     \
   428 		  }                                     \
   429               } else {                                  \
   429 	      } else {                                  \
   430                   READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   430 		  READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   431               }                                         \
   431 	      }                                         \
   432             }                                           \
   432 	    }                                           \
   433             if ((ret) <= 0) {                           \
   433 	    if ((ret) <= 0) {                           \
   434                 if ((ret) < 0 && __threadErrno == EINTR)\
   434 		if ((ret) < 0 && __threadErrno == EINTR)\
   435                     continue;                           \
   435 		    continue;                           \
   436                 break;                                  \
   436 		break;                                  \
   437             }                                           \
   437 	    }                                           \
   438             __offs += (ret);                            \
   438 	    __offs += (ret);                            \
   439         }                                               \
   439 	}                                               \
   440         if (__offs > 0)                                 \
   440 	if (__offs > 0)                                 \
   441             (ret) = __offs;                             \
   441 	    (ret) = __offs;                             \
   442     }                                                   \
   442     }                                                   \
   443   }
   443   }
   444 
   444 
   445 # define IO_BUFFER_SIZE        (8*1024)
   445 # define IO_BUFFER_SIZE        (8*1024)
   446 
   446 
   447 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   447 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   448   {                                                     \
   448   {                                                     \
   449     int __ooffs = obj_offs;                             \
   449     int __ooffs = obj_offs;                             \
   450     int __offs = 0;                                     \
   450     int __offs = 0;                                     \
   451     char *buf = (char *)(obj);                          \
   451     char *buf = (char *)(obj);                          \
   452                                                         \
   452 							\
   453     (ret) = 0;                                          \
   453     (ret) = 0;                                          \
   454     if (isBuffered) {                                   \
   454     if (isBuffered) {                                   \
   455         while (__offs < (cnt)) {                        \
   455 	while (__offs < (cnt)) {                        \
   456             CLEAR_ERRNO;                                \
   456 	    CLEAR_ERRNO;                                \
   457             (ret) = getc(f);                            \
   457 	    (ret) = getc(f);                            \
   458             if ((ret) < 0) {                            \
   458 	    if ((ret) < 0) {                            \
   459                 if (ferror(f)) {                        \
   459 		if (ferror(f)) {                        \
   460                     if (__threadErrno == EINTR) {       \
   460 		    if (__threadErrno == EINTR) {       \
   461                         clearerr(f);                    \
   461 			clearerr(f);                    \
   462                         /* refetch */                   \
   462 			/* refetch */                   \
   463                         buf = (char *)(obj);            \
   463 			buf = (char *)(obj);            \
   464                         continue;                       \
   464 			continue;                       \
   465                     }                                   \
   465 		    }                                   \
   466                 } else {                                \
   466 		} else {                                \
   467                     (ret) = 0;                          \
   467 		    (ret) = 0;                          \
   468                 }                                       \
   468 		}                                       \
   469                 break;                                  \
   469 		break;                                  \
   470             }                                           \
   470 	    }                                           \
   471             (buf)[__ooffs+__offs] = (ret);              \
   471 	    (buf)[__ooffs+__offs] = (ret);              \
   472             __offs++;                                   \
   472 	    __offs++;                                   \
   473         }                                               \
   473 	}                                               \
   474         if (__offs > 0)                                 \
   474 	if (__offs > 0)                                 \
   475             (ret) = __offs;                             \
   475 	    (ret) = __offs;                             \
   476     } else {                                            \
   476     } else {                                            \
   477         while (__offs < (cnt)) {                        \
   477 	while (__offs < (cnt)) {                        \
   478             char __buf[IO_BUFFER_SIZE];                 \
   478 	    char __buf[IO_BUFFER_SIZE];                 \
   479             OBJ rA = __INST(readAhead);                 \
   479 	    OBJ rA = __INST(readAhead);                 \
   480             if (rA != nil) {                            \
   480 	    if (rA != nil) {                            \
   481                 (buf)[__ooffs+__offs] = __intVal(rA);   \
   481 		(buf)[__ooffs+__offs] = __intVal(rA);   \
   482                 __INST(readAhead) = nil;                \
   482 		__INST(readAhead) = nil;                \
   483                 (ret) = 1;                              \
   483 		(ret) = 1;                              \
   484             } else {                                    \
   484 	    } else {                                    \
   485                 int l;                                  \
   485 		int l;                                  \
   486                 CLEAR_ERRNO;                            \
   486 		CLEAR_ERRNO;                            \
   487                 l = (cnt)-__offs;                       \
   487 		l = (cnt)-__offs;                       \
   488                 if ( l > IO_BUFFER_SIZE)                \
   488 		if ( l > IO_BUFFER_SIZE)                \
   489                   l = IO_BUFFER_SIZE;                   \
   489 		  l = IO_BUFFER_SIZE;                   \
   490                 READ((ret),f, __buf, l, handleType);    \
   490 		READ((ret),f, __buf, l, handleType);    \
   491                 if ((ret) <= 0) {                       \
   491 		if ((ret) <= 0) {                       \
   492                     if ((ret) < 0 && __threadErrno == EINTR) {  \
   492 		    if ((ret) < 0 && __threadErrno == EINTR) {  \
   493                         continue;                       \
   493 			continue;                       \
   494                     }                                   \
   494 		    }                                   \
   495                     break;                              \
   495 		    break;                              \
   496                 }                                       \
   496 		}                                       \
   497             }                                           \
   497 	    }                                           \
   498             if ((ret) > 0 ) {                           \
   498 	    if ((ret) > 0 ) {                           \
   499                 /* refetch */                               \
   499 		/* refetch */                               \
   500                 buf = (char *)(obj);                        \
   500 		buf = (char *)(obj);                        \
   501                 memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   501 		memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   502                 __offs += (ret);                            \
   502 		__offs += (ret);                            \
   503             } else {                                        \
   503 	    } else {                                        \
   504                 (ret) = 0;                                  \
   504 		(ret) = 0;                                  \
   505             }                                               \
   505 	    }                                               \
   506         }                                               \
   506 	}                                               \
   507         if (__offs > 0)                                 \
   507 	if (__offs > 0)                                 \
   508             (ret) = __offs;                             \
   508 	    (ret) = __offs;                             \
   509     }                                                   \
   509     }                                                   \
   510   }
   510   }
   511 
   511 
   512 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   512 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   513   {                                                  \
   513   {                                                  \
   514     int __ooffs = obj_offs;                          \
   514     int __ooffs = obj_offs;                          \
   515     int __offs = 0;                                  \
   515     int __offs = 0;                                  \
   516     char *buf = (char *)(obj);                       \
   516     char *buf = (char *)(obj);                       \
   517                                                      \
   517 						     \
   518     (ret) = 0;                                       \
   518     (ret) = 0;                                       \
   519     if (isBuffered) {                                \
   519     if (isBuffered) {                                \
   520         while (__offs < (cnt)) {                     \
   520 	while (__offs < (cnt)) {                     \
   521             CLEAR_ERRNO;                             \
   521 	    CLEAR_ERRNO;                             \
   522             (ret) = getc(f);                         \
   522 	    (ret) = getc(f);                         \
   523             if ((ret) < 0) {                         \
   523 	    if ((ret) < 0) {                         \
   524                 if (ferror(f)) {                     \
   524 		if (ferror(f)) {                     \
   525                     if (__threadErrno == EINTR) {    \
   525 		    if (__threadErrno == EINTR) {    \
   526                         clearerr(f);                 \
   526 			clearerr(f);                 \
   527                         /* refetch */                \
   527 			/* refetch */                \
   528                         buf = (char *)(obj);         \
   528 			buf = (char *)(obj);         \
   529                         continue;                    \
   529 			continue;                    \
   530                     }                                \
   530 		    }                                \
   531                 } else {                             \
   531 		} else {                             \
   532                     (ret) = 0;                       \
   532 		    (ret) = 0;                       \
   533                 }                                    \
   533 		}                                    \
   534                 break;                               \
   534 		break;                               \
   535             }                                        \
   535 	    }                                        \
   536             (buf)[__ooffs+__offs] = (ret);           \
   536 	    (buf)[__ooffs+__offs] = (ret);           \
   537             __offs++;                                \
   537 	    __offs++;                                \
   538         }                                            \
   538 	}                                            \
   539         if (__offs > 0)                              \
   539 	if (__offs > 0)                              \
   540             (ret) = __offs;                          \
   540 	    (ret) = __offs;                          \
   541     } else {                                         \
   541     } else {                                         \
   542         while (__offs < (cnt)) {                     \
   542 	while (__offs < (cnt)) {                     \
   543             char __buf[IO_BUFFER_SIZE];              \
   543 	    char __buf[IO_BUFFER_SIZE];              \
   544             OBJ rA = __INST(readAhead);              \
   544 	    OBJ rA = __INST(readAhead);              \
   545             if (rA != nil) {                         \
   545 	    if (rA != nil) {                         \
   546                 (buf)[__ooffs+__offs] = __intVal(rA);\
   546 		(buf)[__ooffs+__offs] = __intVal(rA);\
   547                 __INST(readAhead) = nil;             \
   547 		__INST(readAhead) = nil;             \
   548                 (ret) = 1;                           \
   548 		(ret) = 1;                           \
   549                 __offs++;                            \
   549 		__offs++;                            \
   550                 continue;                            \
   550 		continue;                            \
   551             }                                        \
   551 	    }                                        \
   552             {                                        \
   552 	    {                                        \
   553                 int res = -1, ok = 0;                \
   553 		int res = -1, ok = 0;                \
   554                 SOCKET sock = 0;                     \
   554 		SOCKET sock = 0;                     \
   555                 int l = (cnt)-__offs;                \
   555 		int l = (cnt)-__offs;                \
   556                 CLEAR_ERRNO;                         \
   556 		CLEAR_ERRNO;                         \
   557                 if (l > IO_BUFFER_SIZE) l = IO_BUFFER_SIZE;              \
   557 		if (l > IO_BUFFER_SIZE) l = IO_BUFFER_SIZE;              \
   558                 if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   558 		if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   559                     || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   559 		    || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   560                     || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   560 		    || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   561                    if (!ok) {                                                               \
   561 		   if (!ok) {                                                               \
   562                         __threadErrno = sock ? WSAGetLastError() : __WIN32_ERR(GetLastError()); \
   562 			__threadErrno = sock ? WSAGetLastError() : __WIN32_ERR(GetLastError()); \
   563                         (ret) = __threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1;   \
   563 			(ret) = __threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1;   \
   564                         break;                                                              \
   564 			break;                                                              \
   565                    }                                \
   565 		   }                                \
   566                    if (res > 0) {                   \
   566 		   if (res > 0) {                   \
   567                         if (res > l) res = l;       \
   567 			if (res > l) res = l;       \
   568                         READ((ret), f, __buf, res, handleType); \
   568 			READ((ret), f, __buf, res, handleType); \
   569                    } else {                              \
   569 		   } else {                              \
   570                        if (sock && send(sock, NULL, 0, 0) == SOCKET_ERROR) {     \
   570 		       if (sock && send(sock, NULL, 0, 0) == SOCKET_ERROR) {     \
   571                          (ret) = -1; __threadErrno = WSAGetLastError();          \
   571 			 (ret) = -1; __threadErrno = WSAGetLastError();          \
   572                        } else {                          \
   572 		       } else {                          \
   573                          (ret) = 0;                      \
   573 			 (ret) = 0;                      \
   574                        }                                 \
   574 		       }                                 \
   575                        break;                            \
   575 		       break;                            \
   576                    }                                     \
   576 		   }                                     \
   577                 } else {                                  \
   577 		} else {                                  \
   578                     READ((ret), f, __buf, l, handleType); \
   578 		    READ((ret), f, __buf, l, handleType); \
   579                 }                                     \
   579 		}                                     \
   580                 if ((ret) <= 0) {                     \
   580 		if ((ret) <= 0) {                     \
   581                     if ((ret) < 0 && __threadErrno == EINTR) \
   581 		    if ((ret) < 0 && __threadErrno == EINTR) \
   582                         continue;                       \
   582 			continue;                       \
   583                     break;                              \
   583 		    break;                              \
   584                 }                                       \
   584 		}                                       \
   585             }                                           \
   585 	    }                                           \
   586             if ((ret) > 0) {                            \
   586 	    if ((ret) > 0) {                            \
   587                 buf = (char *)(obj);                    \
   587 		buf = (char *)(obj);                    \
   588                 memcpy((buf)+__ooffs+__offs, __buf, (ret)); \
   588 		memcpy((buf)+__ooffs+__offs, __buf, (ret)); \
   589                 __offs += (ret);                        \
   589 		__offs += (ret);                        \
   590             } else {                                    \
   590 	    } else {                                    \
   591                 (ret) = 0;                              \
   591 		(ret) = 0;                              \
   592             }                                           \
   592 	    }                                           \
   593         }                                               \
   593 	}                                               \
   594         if (__offs > 0)                                 \
   594 	if (__offs > 0)                                 \
   595             (ret) = __offs;                             \
   595 	    (ret) = __offs;                             \
   596     }                                                   \
   596     }                                                   \
   597   }
   597   }
   598 
   598 
   599 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)         \
   599 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)         \
   600     if (isBuffered) {                                   \
   600     if (isBuffered) {                                   \
   601         for (;;) {                                      \
   601 	for (;;) {                                      \
   602             CLEAR_ERRNO;                                \
   602 	    CLEAR_ERRNO;                                \
   603             ret = putc(*(buf), f);                      \
   603 	    ret = putc(*(buf), f);                      \
   604             if ((ret) >= 0) {                           \
   604 	    if ((ret) >= 0) {                           \
   605                 (ret) = 1;                              \
   605 		(ret) = 1;                              \
   606             } else if (ferror(f)) {                     \
   606 	    } else if (ferror(f)) {                     \
   607                 if (__threadErrno == EINTR) {           \
   607 		if (__threadErrno == EINTR) {           \
   608                     clearerr(f);                        \
   608 		    clearerr(f);                        \
   609                     continue;                           \
   609 		    continue;                           \
   610                 }                                       \
   610 		}                                       \
   611             } else                                      \
   611 	    } else                                      \
   612                 (ret) = 0;                              \
   612 		(ret) = 0;                              \
   613             break;                                      \
   613 	    break;                                      \
   614         }                                               \
   614 	}                                               \
   615     } else {                                            \
   615     } else {                                            \
   616         for (;;) {                                      \
   616 	for (;;) {                                      \
   617             CLEAR_ERRNO;                                \
   617 	    CLEAR_ERRNO;                                \
   618             WRITE(ret,f, buf, 1, handleType);           \
   618 	    WRITE(ret,f, buf, 1, handleType);           \
   619             if ((ret) >= 0 || __threadErrno != EINTR)   \
   619 	    if ((ret) >= 0 || __threadErrno != EINTR)   \
   620                 break;                                  \
   620 		break;                                  \
   621         }                                               \
   621 	}                                               \
   622    }
   622    }
   623 
   623 
   624 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   624 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   625     (ret) = 0;                                          \
   625     (ret) = 0;                                          \
   626     if (isBuffered) {                                   \
   626     if (isBuffered) {                                   \
   627         int __offs = 0;                                 \
   627 	int __offs = 0;                                 \
   628         while (__offs < (cnt)) {                        \
   628 	while (__offs < (cnt)) {                        \
   629             CLEAR_ERRNO;                                \
   629 	    CLEAR_ERRNO;                                \
   630             (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
   630 	    (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
   631             if ((ret) <= 0) {                           \
   631 	    if ((ret) <= 0) {                           \
   632                 if (ferror(f)) {                        \
   632 		if (ferror(f)) {                        \
   633                     if (__threadErrno == EINTR) {       \
   633 		    if (__threadErrno == EINTR) {       \
   634                         clearerr(f);                    \
   634 			clearerr(f);                    \
   635                         continue;                       \
   635 			continue;                       \
   636                     }                                   \
   636 		    }                                   \
   637                     break;                              \
   637 		    break;                              \
   638                 } else {                                \
   638 		} else {                                \
   639                     (ret) = 0;                          \
   639 		    (ret) = 0;                          \
   640                 }                                       \
   640 		}                                       \
   641             }                                           \
   641 	    }                                           \
   642             __offs += (ret);                            \
   642 	    __offs += (ret);                            \
   643         }                                               \
   643 	}                                               \
   644         if (__offs > 0)                                 \
   644 	if (__offs > 0)                                 \
   645             (ret) = __offs;                             \
   645 	    (ret) = __offs;                             \
   646     } else {                                            \
   646     } else {                                            \
   647         int __offs = 0;                                 \
   647 	int __offs = 0;                                 \
   648         while (__offs < (cnt)) {                        \
   648 	while (__offs < (cnt)) {                        \
   649             CLEAR_ERRNO;                                \
   649 	    CLEAR_ERRNO;                                \
   650             WRITE((ret),f, (buf)+__offs, (cnt)-__offs, handleType);   \
   650 	    WRITE((ret),f, (buf)+__offs, (cnt)-__offs, handleType);   \
   651             if ((ret) <= 0) {                           \
   651 	    if ((ret) <= 0) {                           \
   652                 if ((ret) < 0 && __threadErrno == EINTR) { \
   652 		if ((ret) < 0 && __threadErrno == EINTR) { \
   653                     continue;                           \
   653 		    continue;                           \
   654                 }                                       \
   654 		}                                       \
   655                 break;                                  \
   655 		break;                                  \
   656             }                                           \
   656 	    }                                           \
   657             __offs += (ret);                            \
   657 	    __offs += (ret);                            \
   658         }                                               \
   658 	}                                               \
   659         if (__offs > 0)                                 \
   659 	if (__offs > 0)                                 \
   660             (ret) = __offs;                             \
   660 	    (ret) = __offs;                             \
   661    }
   661    }
   662 
   662 
   663 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   663 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   664   {                                                     \
   664   {                                                     \
   665     int __ooffs = obj_offs;                             \
   665     int __ooffs = obj_offs;                             \
   666     int __offs = 0;                                     \
   666     int __offs = 0;                                     \
   667     char *buf = (char *)(obj);                          \
   667     char *buf = (char *)(obj);                          \
   668                                                         \
   668 							\
   669     (ret) = 0;                                          \
   669     (ret) = 0;                                          \
   670     if (isBuffered) {                                   \
   670     if (isBuffered) {                                   \
   671         while (__offs < (cnt)) {                        \
   671 	while (__offs < (cnt)) {                        \
   672             CLEAR_ERRNO;                                \
   672 	    CLEAR_ERRNO;                                \
   673             ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \
   673 	    ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \
   674             if ((ret) <= 0) {                           \
   674 	    if ((ret) <= 0) {                           \
   675                 if (ferror(f)) {                        \
   675 		if (ferror(f)) {                        \
   676                     if (__threadErrno == EINTR) {       \
   676 		    if (__threadErrno == EINTR) {       \
   677                         /* refetch */                   \
   677 			/* refetch */                   \
   678                         buf = (char *)(obj);            \
   678 			buf = (char *)(obj);            \
   679                         clearerr(f);                    \
   679 			clearerr(f);                    \
   680                         continue;                       \
   680 			continue;                       \
   681                     }                                   \
   681 		    }                                   \
   682                     break;                              \
   682 		    break;                              \
   683                 } else {                                \
   683 		} else {                                \
   684                     (ret) = 0;                          \
   684 		    (ret) = 0;                          \
   685                 }                                       \
   685 		}                                       \
   686             }                                           \
   686 	    }                                           \
   687             __offs += (ret);                            \
   687 	    __offs += (ret);                            \
   688         }                                               \
   688 	}                                               \
   689         if (__offs > 0)                                 \
   689 	if (__offs > 0)                                 \
   690             (ret) = __offs;                             \
   690 	    (ret) = __offs;                             \
   691     } else {                                            \
   691     } else {                                            \
   692         while (__offs < (cnt)) {                        \
   692 	while (__offs < (cnt)) {                        \
   693             char __buf[IO_BUFFER_SIZE];                 \
   693 	    char __buf[IO_BUFFER_SIZE];                 \
   694             int l;                                      \
   694 	    int l;                                      \
   695             CLEAR_ERRNO;                                \
   695 	    CLEAR_ERRNO;                                \
   696             l = (cnt)-__offs;                           \
   696 	    l = (cnt)-__offs;                           \
   697             if ( l > IO_BUFFER_SIZE)                    \
   697 	    if ( l > IO_BUFFER_SIZE)                    \
   698               l = IO_BUFFER_SIZE;                       \
   698 	      l = IO_BUFFER_SIZE;                       \
   699             /* refetch */                               \
   699 	    /* refetch */                               \
   700             buf = (char *)(obj);                        \
   700 	    buf = (char *)(obj);                        \
   701             memcpy(__buf,(buf)+__ooffs+__offs,l);       \
   701 	    memcpy(__buf,(buf)+__ooffs+__offs,l);       \
   702             WRITE(ret,f, __buf, l, handleType);         \
   702 	    WRITE(ret,f, __buf, l, handleType);         \
   703             if ((ret) <= 0) {                           \
   703 	    if ((ret) <= 0) {                           \
   704                 if ((ret) < 0 && __threadErrno == EINTR) { \
   704 		if ((ret) < 0 && __threadErrno == EINTR) { \
   705                     continue;                           \
   705 		    continue;                           \
   706                 }                                       \
   706 		}                                       \
   707                 break;                                  \
   707 		break;                                  \
   708             }                                           \
   708 	    }                                           \
   709             __offs += (ret);                            \
   709 	    __offs += (ret);                            \
   710         }                                               \
   710 	}                                               \
   711         if (__offs > 0)                                 \
   711 	if (__offs > 0)                                 \
   712             (ret) = __offs;                             \
   712 	    (ret) = __offs;                             \
   713     }                                                   \
   713     }                                                   \
   714   }
   714   }
   715 
   715 
   716 #else /* ! __win32__ */
   716 #else /* ! __win32__ */
   717 /* ========================   UNIX / LINUX ====================================================== */
   717 /* ========================   UNIX / LINUX ====================================================== */
   718 typedef int SOCKET;
   718 typedef int SOCKET;
   719 
   719 
   720 # define __READING__(f)                          \
   720 # define __READING__(f)                          \
   721     if ((__INST(didWrite) != false)              \
   721     if ((__INST(didWrite) != false)              \
   722      && (__INST(mode) == @symbol(readwrite))) {  \
   722      && (__INST(mode) == @symbol(readwrite))) {  \
   723         __INST(didWrite) = false;                \
   723 	__INST(didWrite) = false;                \
   724         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   724 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   725     }
   725     }
   726 
   726 
   727 # define __WRITING__(f)                          \
   727 # define __WRITING__(f)                          \
   728     if ((__INST(didWrite) != true)               \
   728     if ((__INST(didWrite) != true)               \
   729      && (__INST(mode) == @symbol(readwrite))) {  \
   729      && (__INST(mode) == @symbol(readwrite))) {  \
   730         __INST(didWrite) = true;                 \
   730 	__INST(didWrite) = true;                 \
   731         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   731 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   732     }
   732     }
   733 
   733 
   734 
   734 
   735 # ifdef NO_STDIO
   735 # ifdef NO_STDIO
   736 #  define __UNGETC__(c, f, isBuffered)                  \
   736 #  define __UNGETC__(c, f, isBuffered)                  \
   737     __INST(readAhead) = __mkSmallInteger((c));
   737     __INST(readAhead) = __mkSmallInteger((c));
   738 # else /* use STDIO */
   738 # else /* use STDIO */
   739 #  define __UNGETC__(c, f, isBuffered)                  \
   739 #  define __UNGETC__(c, f, isBuffered)                  \
   740     if (isBuffered) {                                   \
   740     if (isBuffered) {                                   \
   741         ungetc((c), (f));                               \
   741 	ungetc((c), (f));                               \
   742     } else {                                            \
   742     } else {                                            \
   743         __INST(readAhead) = __mkSmallInteger((c));          \
   743 	__INST(readAhead) = __mkSmallInteger((c));          \
   744     }
   744     }
   745 # endif /* use STDIO */
   745 # endif /* use STDIO */
   746 
   746 
   747 # ifdef NO_STDIO
   747 # ifdef NO_STDIO
   748 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   748 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   749     {                                                   \
   749     {                                                   \
   750         OBJ rA = __INST(readAhead);                     \
   750 	OBJ rA = __INST(readAhead);                     \
   751         if (rA != nil) {                                \
   751 	if (rA != nil) {                                \
   752             *(buf) = __intVal(rA);                      \
   752 	    *(buf) = __intVal(rA);                      \
   753             DEBUGBUFFER(buf);                           \
   753 	    DEBUGBUFFER(buf);                           \
   754             __INST(readAhead) = nil;                    \
   754 	    __INST(readAhead) = nil;                    \
   755             (ret) = 1;                                  \
   755 	    (ret) = 1;                                  \
   756         } else {                                        \
   756 	} else {                                        \
   757             for (;;) {                                  \
   757 	    for (;;) {                                  \
   758                 CLEAR_ERRNO;                            \
   758 		CLEAR_ERRNO;                            \
   759                 (ret) = READ(f, buf, 1, handleType);    \
   759 		(ret) = READ(f, buf, 1, handleType);    \
   760                 DEBUGBUFFER(buf);                       \
   760 		DEBUGBUFFER(buf);                       \
   761                 if ((ret) >= 0) break;                  \
   761 		if ((ret) >= 0) break;                  \
   762                 if (errno != EINTR) {                   \
   762 		if (errno != EINTR) {                   \
   763                     break;                              \
   763 		    break;                              \
   764                 }                                       \
   764 		}                                       \
   765                 __HANDLE_INTERRUPTS__;                  \
   765 		__HANDLE_INTERRUPTS__;                  \
   766             }                                           \
   766 	    }                                           \
   767         }                                               \
   767 	}                                               \
   768     }
   768     }
   769 # else /* use STDIO */
   769 # else /* use STDIO */
   770 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   770 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   771     if (isBuffered) {                                   \
   771     if (isBuffered) {                                   \
   772         for (;;) {                                      \
   772 	for (;;) {                                      \
   773             CLEAR_ERRNO;                                \
   773 	    CLEAR_ERRNO;                                \
   774             (ret) = getc(f);                            \
   774 	    (ret) = getc(f);                            \
   775             if ((ret) >= 0) {                           \
   775 	    if ((ret) >= 0) {                           \
   776                 DEBUGBUFFER(buf);                       \
   776 		DEBUGBUFFER(buf);                       \
   777                 *(buf) = (ret);                         \
   777 		*(buf) = (ret);                         \
   778                 (ret) = 1;                              \
   778 		(ret) = 1;                              \
   779             } else if (ferror(f)) {                     \
   779 	    } else if (ferror(f)) {                     \
   780                 if (errno == EINTR) {                   \
   780 		if (errno == EINTR) {                   \
   781                     __HANDLE_INTERRUPTS__;              \
   781 		    __HANDLE_INTERRUPTS__;              \
   782                     clearerr(f);                        \
   782 		    clearerr(f);                        \
   783                     continue;                           \
   783 		    continue;                           \
   784                 }                                       \
   784 		}                                       \
   785             } else                                      \
   785 	    } else                                      \
   786                 (ret) = 0;                              \
   786 		(ret) = 0;                              \
   787             break;                                      \
   787 	    break;                                      \
   788         }                                               \
   788 	}                                               \
   789     } else {                                            \
   789     } else {                                            \
   790         OBJ rA = __INST(readAhead);                     \
   790 	OBJ rA = __INST(readAhead);                     \
   791         if (rA != nil) {                                \
   791 	if (rA != nil) {                                \
   792             *(buf) = __intVal(rA);                      \
   792 	    *(buf) = __intVal(rA);                      \
   793             DEBUGBUFFER(buf);                           \
   793 	    DEBUGBUFFER(buf);                           \
   794             __INST(readAhead) = nil;                    \
   794 	    __INST(readAhead) = nil;                    \
   795             (ret) = 1;                                  \
   795 	    (ret) = 1;                                  \
   796         } else {                                        \
   796 	} else {                                        \
   797             for (;;) {                                  \
   797 	    for (;;) {                                  \
   798                 CLEAR_ERRNO;                            \
   798 		CLEAR_ERRNO;                            \
   799                 (ret) = read(fileno(f), buf, 1);        \
   799 		(ret) = read(fileno(f), buf, 1);        \
   800                 DEBUGBUFFER(buf);                       \
   800 		DEBUGBUFFER(buf);                       \
   801                 if ((ret) >= 0) break;                  \
   801 		if ((ret) >= 0) break;                  \
   802                 if (errno != EINTR) {                   \
   802 		if (errno != EINTR) {                   \
   803                     break;                              \
   803 		    break;                              \
   804                 }                                       \
   804 		}                                       \
   805                 __HANDLE_INTERRUPTS__;                  \
   805 		__HANDLE_INTERRUPTS__;                  \
   806             }                                           \
   806 	    }                                           \
   807         }                                               \
   807 	}                                               \
   808    }
   808    }
   809 # endif /* use STDIO */
   809 # endif /* use STDIO */
   810 
   810 
   811 /*
   811 /*
   812  * read_bytes into a c-buffer
   812  * read_bytes into a c-buffer
   813  * (which may NOT move)
   813  * (which may NOT move)
   814  */
   814  */
   815 # ifdef NO_STDIO
   815 # ifdef NO_STDIO
   816 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   816 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   817     {                                                   \
   817     {                                                   \
   818         int __offs = 0, __cnt;                          \
   818 	int __offs = 0, __cnt;                          \
   819                                                         \
   819 							\
   820         while (__offs < (cnt)) {                        \
   820 	while (__offs < (cnt)) {                        \
   821             OBJ rA = __INST(readAhead);                 \
   821 	    OBJ rA = __INST(readAhead);                 \
   822             if (rA != nil) {                            \
   822 	    if (rA != nil) {                            \
   823                 (buf)[__offs] = __intVal(rA);           \
   823 		(buf)[__offs] = __intVal(rA);           \
   824                 DEBUGBUFFER(buf);                       \
   824 		DEBUGBUFFER(buf);                       \
   825                 __INST(readAhead) = nil;                \
   825 		__INST(readAhead) = nil;                \
   826                 __offs++;                               \
   826 		__offs++;                               \
   827             } else {                                    \
   827 	    } else {                                    \
   828                 CLEAR_ERRNO;                            \
   828 		CLEAR_ERRNO;                            \
   829                 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \
   829 		__cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \
   830                 DEBUGBUFFER(buf);                       \
   830 		DEBUGBUFFER(buf);                       \
   831                 if (__cnt <= 0) {                       \
   831 		if (__cnt <= 0) {                       \
   832                     if (__cnt < 0 && errno == EINTR) {  \
   832 		    if (__cnt < 0 && errno == EINTR) {  \
   833                         __HANDLE_INTERRUPTS__;          \
   833 			__HANDLE_INTERRUPTS__;          \
   834                         continue;                       \
   834 			continue;                       \
   835                     }                                   \
   835 		    }                                   \
   836                     break;                              \
   836 		    break;                              \
   837                 }                                       \
   837 		}                                       \
   838                 __offs += __cnt;                        \
   838 		__offs += __cnt;                        \
   839             }                                           \
   839 	    }                                           \
   840         }                                               \
   840 	}                                               \
   841         if (__offs > 0)                                 \
   841 	if (__offs > 0)                                 \
   842             (ret) = __offs;                             \
   842 	    (ret) = __offs;                             \
   843    }
   843    }
   844 # else /* use STDIO */
   844 # else /* use STDIO */
   845 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)     \
   845 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)     \
   846     (ret) = 0;                                          \
   846     (ret) = 0;                                          \
   847     if (isBuffered) {                                   \
   847     if (isBuffered) {                                   \
   848         int __offs = 0;                                 \
   848 	int __offs = 0;                                 \
   849         while (__offs < (cnt)) {                        \
   849 	while (__offs < (cnt)) {                        \
   850             CLEAR_ERRNO;                                \
   850 	    CLEAR_ERRNO;                                \
   851             (ret) = getc(f);                            \
   851 	    (ret) = getc(f);                            \
   852             if ((ret) < 0) {                            \
   852 	    if ((ret) < 0) {                            \
   853                 if (ferror(f)) {                        \
   853 		if (ferror(f)) {                        \
   854                     if (errno == EINTR) {               \
   854 		    if (errno == EINTR) {               \
   855                         __HANDLE_INTERRUPTS__;          \
   855 			__HANDLE_INTERRUPTS__;          \
   856                         clearerr(f);                    \
   856 			clearerr(f);                    \
   857                         continue;                       \
   857 			continue;                       \
   858                     }                                   \
   858 		    }                                   \
   859                 } else {                                \
   859 		} else {                                \
   860                     (ret) = 0;                          \
   860 		    (ret) = 0;                          \
   861                 }                                       \
   861 		}                                       \
   862                 break;                                  \
   862 		break;                                  \
   863             }                                           \
   863 	    }                                           \
   864             DEBUGBUFFER(buf);                           \
   864 	    DEBUGBUFFER(buf);                           \
   865             (buf)[__offs++] = (ret);                    \
   865 	    (buf)[__offs++] = (ret);                    \
   866         }                                               \
   866 	}                                               \
   867         if (__offs > 0)                                 \
   867 	if (__offs > 0)                                 \
   868             (ret) = __offs;                             \
   868 	    (ret) = __offs;                             \
   869     } else {                                            \
   869     } else {                                            \
   870         int __offs = 0, __cnt;                          \
   870 	int __offs = 0, __cnt;                          \
   871         int fd = fileno(f);                             \
   871 	int fd = fileno(f);                             \
   872                                                         \
   872 							\
   873         while (__offs < (cnt)) {                        \
   873 	while (__offs < (cnt)) {                        \
   874             OBJ rA = __INST(readAhead);                 \
   874 	    OBJ rA = __INST(readAhead);                 \
   875             if (rA != nil) {                            \
   875 	    if (rA != nil) {                            \
   876                 DEBUGBUFFER(buf);                       \
   876 		DEBUGBUFFER(buf);                       \
   877                 (buf)[__offs] = __intVal(rA);           \
   877 		(buf)[__offs] = __intVal(rA);           \
   878                 __INST(readAhead) = nil;                \
   878 		__INST(readAhead) = nil;                \
   879                 __offs++;                               \
   879 		__offs++;                               \
   880             } else {                                    \
   880 	    } else {                                    \
   881                 CLEAR_ERRNO;                            \
   881 		CLEAR_ERRNO;                            \
   882                 __cnt = read(fd, (buf)+__offs, (cnt)-__offs);  \
   882 		__cnt = read(fd, (buf)+__offs, (cnt)-__offs);  \
   883                 DEBUGBUFFER(buf);                       \
   883 		DEBUGBUFFER(buf);                       \
   884                 if (__cnt <= 0) {                       \
   884 		if (__cnt <= 0) {                       \
   885                     if (__cnt < 0 && errno == EINTR) {  \
   885 		    if (__cnt < 0 && errno == EINTR) {  \
   886                         __HANDLE_INTERRUPTS__;          \
   886 			__HANDLE_INTERRUPTS__;          \
   887                         continue;                       \
   887 			continue;                       \
   888                     }                                   \
   888 		    }                                   \
   889                     break;                              \
   889 		    break;                              \
   890                 }                                       \
   890 		}                                       \
   891                 __offs += __cnt;                        \
   891 		__offs += __cnt;                        \
   892             }                                           \
   892 	    }                                           \
   893         }                                               \
   893 	}                                               \
   894         if (__offs > 0)                                 \
   894 	if (__offs > 0)                                 \
   895             (ret) = __offs;                             \
   895 	    (ret) = __offs;                             \
   896    }
   896    }
   897 
   897 
   898 
   898 
   899 /*
   899 /*
   900  * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc...
   900  * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc...
   901  */
   901  */
   902 
   902 
   903 #  if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY))
   903 #  if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY))
   904 #   define SETFLAGS(fd, flags) \
   904 #   define SETFLAGS(fd, flags) \
   905         fcntl(fd, F_SETFL, flags)
   905 	fcntl(fd, F_SETFL, flags)
   906 
   906 
   907 #   if defined(O_NONBLOCK)
   907 #   if defined(O_NONBLOCK)
   908 #    define __STX_NONBLOCK_FLAG O_NONBLOCK
   908 #    define __STX_NONBLOCK_FLAG O_NONBLOCK
   909 #   else
   909 #   else
   910 #    if defined(O_NDELAY)
   910 #    if defined(O_NDELAY)
   913 #     define __STX_NONBLOCK_FLAG FNDELAY
   913 #     define __STX_NONBLOCK_FLAG FNDELAY
   914 #    endif
   914 #    endif
   915 #   endif
   915 #   endif
   916 
   916 
   917 #   define SETNONBLOCKING(fd, oldFlags) \
   917 #   define SETNONBLOCKING(fd, oldFlags) \
   918         { \
   918 	{ \
   919             int flags = fcntl(fd, F_GETFL, 0); \
   919 	    int flags = fcntl(fd, F_GETFL, 0); \
   920             if (flags >= 0) { \
   920 	    if (flags >= 0) { \
   921                 fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \
   921 		fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \
   922             } \
   922 	    } \
   923             oldFlags = flags; \
   923 	    oldFlags = flags; \
   924         }
   924 	}
   925 #  else
   925 #  else
   926 #   define SETFLAGS(fd, flags) /* nothing */
   926 #   define SETFLAGS(fd, flags) /* nothing */
   927 #   define SETNONBLOCKING(fd, oldFlags) /* nothing */
   927 #   define SETNONBLOCKING(fd, oldFlags) /* nothing */
   928 #  endif
   928 #  endif
   929 
   929 
   930 #  define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   930 #  define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   931   {                                                     \
   931   {                                                     \
   932     int __offs = 0, __cnt;                              \
   932     int __offs = 0, __cnt;                              \
   933     int oldFlags;                                       \
   933     int oldFlags;                                       \
   934                                                         \
   934 							\
   935     (ret) = 0;                                          \
   935     (ret) = 0;                                          \
   936     SETNONBLOCKING(fileno(f), oldFlags);                \
   936     SETNONBLOCKING(fileno(f), oldFlags);                \
   937     if (isBuffered) {                                   \
   937     if (isBuffered) {                                   \
   938         while (__offs < (cnt)) {                        \
   938 	while (__offs < (cnt)) {                        \
   939             CLEAR_ERRNO;                                \
   939 	    CLEAR_ERRNO;                                \
   940             (ret) = getc(f);                            \
   940 	    (ret) = getc(f);                            \
   941             if ((ret) < 0) {                            \
   941 	    if ((ret) < 0) {                            \
   942                 if (ferror(f)) {                        \
   942 		if (ferror(f)) {                        \
   943                     if (errno == EINTR) {               \
   943 		    if (errno == EINTR) {               \
   944                         (ret) = 0;                      \
   944 			(ret) = 0;                      \
   945                         clearerr(f);                    \
   945 			clearerr(f);                    \
   946                         break;                          \
   946 			break;                          \
   947                     }                                   \
   947 		    }                                   \
   948                 } else {                                \
   948 		} else {                                \
   949                     (ret) = 0;                          \
   949 		    (ret) = 0;                          \
   950                 }                                       \
   950 		}                                       \
   951                 break;                                  \
   951 		break;                                  \
   952             }                                           \
   952 	    }                                           \
   953             (buf)[__offs++] = (ret);                    \
   953 	    (buf)[__offs++] = (ret);                    \
   954             DEBUGBUFFER(buf);                           \
   954 	    DEBUGBUFFER(buf);                           \
   955         }                                               \
   955 	}                                               \
   956         if (__offs > 0)                                 \
   956 	if (__offs > 0)                                 \
   957             (ret) = __offs;                             \
   957 	    (ret) = __offs;                             \
   958     } else {                                            \
   958     } else {                                            \
   959         int fd = fileno(f);                             \
   959 	int fd = fileno(f);                             \
   960                                                         \
   960 							\
   961         while (__offs < (cnt)) {                        \
   961 	while (__offs < (cnt)) {                        \
   962             OBJ rA = __INST(readAhead);                 \
   962 	    OBJ rA = __INST(readAhead);                 \
   963             if (rA != nil) {                            \
   963 	    if (rA != nil) {                            \
   964                 (buf)[__offs] = __intVal(rA);           \
   964 		(buf)[__offs] = __intVal(rA);           \
   965                 DEBUGBUFFER(buf);                       \
   965 		DEBUGBUFFER(buf);                       \
   966                 __INST(readAhead) = nil;                \
   966 		__INST(readAhead) = nil;                \
   967                 __offs++;                               \
   967 		__offs++;                               \
   968                 continue;                               \
   968 		continue;                               \
   969             }                                           \
   969 	    }                                           \
   970             CLEAR_ERRNO;                                \
   970 	    CLEAR_ERRNO;                                \
   971             __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \
   971 	    __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \
   972             DEBUGBUFFER(buf);                           \
   972 	    DEBUGBUFFER(buf);                           \
   973             if (__cnt > 0) {                            \
   973 	    if (__cnt > 0) {                            \
   974                 __offs += __cnt;                        \
   974 		__offs += __cnt;                        \
   975             }                                           \
   975 	    }                                           \
   976             break;                                      \
   976 	    break;                                      \
   977         }                                               \
   977 	}                                               \
   978         if (__offs > 0)                                 \
   978 	if (__offs > 0)                                 \
   979             (ret) = __offs;                             \
   979 	    (ret) = __offs;                             \
   980     }                                                   \
   980     }                                                   \
   981     SETFLAGS(fileno(f), oldFlags);                      \
   981     SETFLAGS(fileno(f), oldFlags);                      \
   982   }
   982   }
   983 
   983 
   984 # endif /* use STDIO */
   984 # endif /* use STDIO */
   992   {                                                     \
   992   {                                                     \
   993     int __ooffs = obj_offs;                             \
   993     int __ooffs = obj_offs;                             \
   994     int __offs = 0;                                     \
   994     int __offs = 0;                                     \
   995     int __cnt;                                          \
   995     int __cnt;                                          \
   996     char *buf = (char *)(obj);                          \
   996     char *buf = (char *)(obj);                          \
   997                                                         \
   997 							\
   998     (ret) = 0;                                          \
   998     (ret) = 0;                                          \
   999     {                                                   \
   999     {                                                   \
  1000         while (__offs < (cnt)) {                        \
  1000 	while (__offs < (cnt)) {                        \
  1001             OBJ rA = __INST(readAhead);                 \
  1001 	    OBJ rA = __INST(readAhead);                 \
  1002             if (rA != nil) {                            \
  1002 	    if (rA != nil) {                            \
  1003                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1003 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1004                 DEBUGBUFFER(buf);                       \
  1004 		DEBUGBUFFER(buf);                       \
  1005                 __INST(readAhead) = nil;                \
  1005 		__INST(readAhead) = nil;                \
  1006                 __offs++;                               \
  1006 		__offs++;                               \
  1007             } else {                                    \
  1007 	    } else {                                    \
  1008                 CLEAR_ERRNO;                            \
  1008 		CLEAR_ERRNO;                            \
  1009                 __cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1009 		__cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1010                 DEBUGBUFFER(buf);                       \
  1010 		DEBUGBUFFER(buf);                       \
  1011                 if (__cnt <= 0) {                       \
  1011 		if (__cnt <= 0) {                       \
  1012                     if (__cnt < 0 && errno == EINTR) {  \
  1012 		    if (__cnt < 0 && errno == EINTR) {  \
  1013                         __HANDLE_INTERRUPTS__;          \
  1013 			__HANDLE_INTERRUPTS__;          \
  1014                         /* refetch */                   \
  1014 			/* refetch */                   \
  1015                         buf = (char *)(obj);            \
  1015 			buf = (char *)(obj);            \
  1016                         continue;                       \
  1016 			continue;                       \
  1017                     }                                   \
  1017 		    }                                   \
  1018                     break;                              \
  1018 		    break;                              \
  1019                 }                                       \
  1019 		}                                       \
  1020                 __offs += __cnt;                        \
  1020 		__offs += __cnt;                        \
  1021             }                                           \
  1021 	    }                                           \
  1022         }                                               \
  1022 	}                                               \
  1023         if (__offs > 0)                                 \
  1023 	if (__offs > 0)                                 \
  1024             (ret) = __offs;                             \
  1024 	    (ret) = __offs;                             \
  1025     }                                                   \
  1025     }                                                   \
  1026   }
  1026   }
  1027 
  1027 
  1028 # else /* use STDIO */
  1028 # else /* use STDIO */
  1029 
  1029 
  1031   {                                                     \
  1031   {                                                     \
  1032     int __ooffs = obj_offs;                             \
  1032     int __ooffs = obj_offs;                             \
  1033     int __offs = 0;                                     \
  1033     int __offs = 0;                                     \
  1034     int __cnt;                                          \
  1034     int __cnt;                                          \
  1035     char *buf = (char *)(obj);                          \
  1035     char *buf = (char *)(obj);                          \
  1036                                                         \
  1036 							\
  1037     (ret) = 0;                                          \
  1037     (ret) = 0;                                          \
  1038     if (isBuffered) {                                   \
  1038     if (isBuffered) {                                   \
  1039         while (__offs < (cnt)) {                        \
  1039 	while (__offs < (cnt)) {                        \
  1040             CLEAR_ERRNO;                                \
  1040 	    CLEAR_ERRNO;                                \
  1041             (ret) = getc(f);                            \
  1041 	    (ret) = getc(f);                            \
  1042             if ((ret) < 0) {                            \
  1042 	    if ((ret) < 0) {                            \
  1043                 if (ferror(f)) {                        \
  1043 		if (ferror(f)) {                        \
  1044                     if (errno == EINTR) {               \
  1044 		    if (errno == EINTR) {               \
  1045                         __HANDLE_INTERRUPTS__;          \
  1045 			__HANDLE_INTERRUPTS__;          \
  1046                         clearerr(f);                    \
  1046 			clearerr(f);                    \
  1047                         /* refetch */                   \
  1047 			/* refetch */                   \
  1048                         buf = (char *)(obj);            \
  1048 			buf = (char *)(obj);            \
  1049                         DEBUGBUFFER(buf);               \
  1049 			DEBUGBUFFER(buf);               \
  1050                         continue;                       \
  1050 			continue;                       \
  1051                     }                                   \
  1051 		    }                                   \
  1052                 } else {                                \
  1052 		} else {                                \
  1053                     (ret) = 0;                          \
  1053 		    (ret) = 0;                          \
  1054                 }                                       \
  1054 		}                                       \
  1055                 break;                                  \
  1055 		break;                                  \
  1056             }                                           \
  1056 	    }                                           \
  1057             (buf)[__ooffs+__offs] = (ret);              \
  1057 	    (buf)[__ooffs+__offs] = (ret);              \
  1058             DEBUGBUFFER(buf);                           \
  1058 	    DEBUGBUFFER(buf);                           \
  1059             __offs++;                                   \
  1059 	    __offs++;                                   \
  1060         }                                               \
  1060 	}                                               \
  1061         if (__offs > 0)                                 \
  1061 	if (__offs > 0)                                 \
  1062             (ret) = __offs;                             \
  1062 	    (ret) = __offs;                             \
  1063     } else {                                            \
  1063     } else {                                            \
  1064         int fd = fileno(f);                             \
  1064 	int fd = fileno(f);                             \
  1065                                                         \
  1065 							\
  1066         while (__offs < (cnt)) {                        \
  1066 	while (__offs < (cnt)) {                        \
  1067             OBJ rA = __INST(readAhead);                 \
  1067 	    OBJ rA = __INST(readAhead);                 \
  1068             if (rA != nil) {                            \
  1068 	    if (rA != nil) {                            \
  1069                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1069 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1070                 DEBUGBUFFER(buf);                       \
  1070 		DEBUGBUFFER(buf);                       \
  1071                 __INST(readAhead) = nil;                \
  1071 		__INST(readAhead) = nil;                \
  1072                 __offs++;                               \
  1072 		__offs++;                               \
  1073             } else {                                    \
  1073 	    } else {                                    \
  1074                 CLEAR_ERRNO;                            \
  1074 		CLEAR_ERRNO;                            \
  1075                 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1075 		__cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1076                 DEBUGBUFFER(buf);                       \
  1076 		DEBUGBUFFER(buf);                       \
  1077                 if (__cnt <= 0) {                       \
  1077 		if (__cnt <= 0) {                       \
  1078                     if (__cnt < 0 && errno == EINTR) {  \
  1078 		    if (__cnt < 0 && errno == EINTR) {  \
  1079                         __HANDLE_INTERRUPTS__;          \
  1079 			__HANDLE_INTERRUPTS__;          \
  1080                         /* refetch */                   \
  1080 			/* refetch */                   \
  1081                         buf = (char *)(obj);            \
  1081 			buf = (char *)(obj);            \
  1082                         continue;                       \
  1082 			continue;                       \
  1083                     }                                   \
  1083 		    }                                   \
  1084                     break;                              \
  1084 		    break;                              \
  1085                 }                                       \
  1085 		}                                       \
  1086                 __offs += __cnt;                        \
  1086 		__offs += __cnt;                        \
  1087             }                                           \
  1087 	    }                                           \
  1088         }                                               \
  1088 	}                                               \
  1089         if (__offs > 0)                                 \
  1089 	if (__offs > 0)                                 \
  1090             (ret) = __offs;                             \
  1090 	    (ret) = __offs;                             \
  1091     }                                                   \
  1091     }                                                   \
  1092   }
  1092   }
  1093 
  1093 
  1094 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)     \
  1094 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)     \
  1095   {                                                     \
  1095   {                                                     \
  1096     int __ooffs = obj_offs;                             \
  1096     int __ooffs = obj_offs;                             \
  1097     int __offs = 0;                                     \
  1097     int __offs = 0;                                     \
  1098     int __cnt;                                          \
  1098     int __cnt;                                          \
  1099     char *buf = (char *)(obj);                          \
  1099     char *buf = (char *)(obj);                          \
  1100     int oldFlags;                                       \
  1100     int oldFlags;                                       \
  1101                                                         \
  1101 							\
  1102     (ret) = 0;                                          \
  1102     (ret) = 0;                                          \
  1103     SETNONBLOCKING(fileno(f), oldFlags);                \
  1103     SETNONBLOCKING(fileno(f), oldFlags);                \
  1104                                                         \
  1104 							\
  1105     if (isBuffered) {                                   \
  1105     if (isBuffered) {                                   \
  1106         while (__offs < (cnt)) {                        \
  1106 	while (__offs < (cnt)) {                        \
  1107             CLEAR_ERRNO;                                \
  1107 	    CLEAR_ERRNO;                                \
  1108             (ret) = getc(f);                            \
  1108 	    (ret) = getc(f);                            \
  1109             if ((ret) < 0) {                            \
  1109 	    if ((ret) < 0) {                            \
  1110                 if (ferror(f)) {                        \
  1110 		if (ferror(f)) {                        \
  1111                     if (errno == EINTR) {               \
  1111 		    if (errno == EINTR) {               \
  1112                         clearerr(f);                    \
  1112 			clearerr(f);                    \
  1113                         /* refetch */                   \
  1113 			/* refetch */                   \
  1114                         buf = (char *)(obj);            \
  1114 			buf = (char *)(obj);            \
  1115                         (ret) = 0;                      \
  1115 			(ret) = 0;                      \
  1116                         break;                          \
  1116 			break;                          \
  1117                     }                                   \
  1117 		    }                                   \
  1118                 } else {                                \
  1118 		} else {                                \
  1119                     (ret) = 0;                          \
  1119 		    (ret) = 0;                          \
  1120                 }                                       \
  1120 		}                                       \
  1121                 break;                                  \
  1121 		break;                                  \
  1122             }                                           \
  1122 	    }                                           \
  1123             (buf)[__ooffs+__offs] = (ret);              \
  1123 	    (buf)[__ooffs+__offs] = (ret);              \
  1124             DEBUGBUFFER(buf);                           \
  1124 	    DEBUGBUFFER(buf);                           \
  1125             __offs++;                                   \
  1125 	    __offs++;                                   \
  1126         }                                               \
  1126 	}                                               \
  1127         if (__offs > 0)                                 \
  1127 	if (__offs > 0)                                 \
  1128             (ret) = __offs;                             \
  1128 	    (ret) = __offs;                             \
  1129     } else {                                            \
  1129     } else {                                            \
  1130         int fd = fileno(f);                             \
  1130 	int fd = fileno(f);                             \
  1131                                                         \
  1131 							\
  1132         while (__offs < (cnt)) {                        \
  1132 	while (__offs < (cnt)) {                        \
  1133             OBJ rA = __INST(readAhead);                 \
  1133 	    OBJ rA = __INST(readAhead);                 \
  1134             if (rA != nil) {                            \
  1134 	    if (rA != nil) {                            \
  1135                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1135 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1136                 DEBUGBUFFER(buf);                       \
  1136 		DEBUGBUFFER(buf);                       \
  1137                 __INST(readAhead) = nil;                \
  1137 		__INST(readAhead) = nil;                \
  1138                 __offs++;                               \
  1138 		__offs++;                               \
  1139                 continue;                               \
  1139 		continue;                               \
  1140             }                                           \
  1140 	    }                                           \
  1141             CLEAR_ERRNO;                                \
  1141 	    CLEAR_ERRNO;                                \
  1142             __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1142 	    __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1143             DEBUGBUFFER(buf);                           \
  1143 	    DEBUGBUFFER(buf);                           \
  1144             if (__cnt > 0) {                            \
  1144 	    if (__cnt > 0) {                            \
  1145                 __offs += __cnt;                        \
  1145 		__offs += __cnt;                        \
  1146             }                                           \
  1146 	    }                                           \
  1147             break;                                      \
  1147 	    break;                                      \
  1148         }                                               \
  1148 	}                                               \
  1149         if (__offs > 0)                                 \
  1149 	if (__offs > 0)                                 \
  1150             (ret) = __offs;                             \
  1150 	    (ret) = __offs;                             \
  1151     }                                                   \
  1151     }                                                   \
  1152     SETFLAGS(fileno(f), oldFlags);                      \
  1152     SETFLAGS(fileno(f), oldFlags);                      \
  1153   }
  1153   }
  1154 
  1154 
  1155 
  1155 
  1156 # endif /* use STDIO */
  1156 # endif /* use STDIO */
  1157 
  1157 
  1158 # ifdef NO_STDIO
  1158 # ifdef NO_STDIO
  1159 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)          \
  1159 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)          \
  1160         for (;;) {                                      \
  1160 	for (;;) {                                      \
  1161             CLEAR_ERRNO;                                \
  1161 	    CLEAR_ERRNO;                                \
  1162             (ret) = WRITE(f, buf, 1, handleType);       \
  1162 	    (ret) = WRITE(f, buf, 1, handleType);       \
  1163             if ((ret) >= 0) break;                      \
  1163 	    if ((ret) >= 0) break;                      \
  1164             if (errno != EINTR) {                       \
  1164 	    if (errno != EINTR) {                       \
  1165                 break;                                  \
  1165 		break;                                  \
  1166             }                                           \
  1166 	    }                                           \
  1167             __HANDLE_INTERRUPTS__;                      \
  1167 	    __HANDLE_INTERRUPTS__;                      \
  1168         }
  1168 	}
  1169 # else /* use STDIO */
  1169 # else /* use STDIO */
  1170 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)        \
  1170 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)        \
  1171     if (isBuffered) {                                   \
  1171     if (isBuffered) {                                   \
  1172         for (;;) {                                      \
  1172 	for (;;) {                                      \
  1173             CLEAR_ERRNO;                                \
  1173 	    CLEAR_ERRNO;                                \
  1174             ret = putc(*(buf), f);                      \
  1174 	    ret = putc(*(buf), f);                      \
  1175             if ((ret) >= 0) {                           \
  1175 	    if ((ret) >= 0) {                           \
  1176                 (ret) = 1;                              \
  1176 		(ret) = 1;                              \
  1177             } else if (ferror(f)) {                     \
  1177 	    } else if (ferror(f)) {                     \
  1178                 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \
  1178 		/* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \
  1179                 if (errno == EINTR || errno == 0) {     \
  1179 		if (errno == EINTR || errno == 0) {     \
  1180                     __HANDLE_INTERRUPTS__;              \
  1180 		    __HANDLE_INTERRUPTS__;              \
  1181                     clearerr(f);                        \
  1181 		    clearerr(f);                        \
  1182                     continue;                           \
  1182 		    continue;                           \
  1183                 }                                       \
  1183 		}                                       \
  1184             } else                                      \
  1184 	    } else                                      \
  1185                 (ret) = 0;                              \
  1185 		(ret) = 0;                              \
  1186             break;                                      \
  1186 	    break;                                      \
  1187         }                                               \
  1187 	}                                               \
  1188     } else {                                            \
  1188     } else {                                            \
  1189         for (;;) {                                      \
  1189 	for (;;) {                                      \
  1190             CLEAR_ERRNO;                                \
  1190 	    CLEAR_ERRNO;                                \
  1191             (ret) = write(fileno(f), buf, 1);           \
  1191 	    (ret) = write(fileno(f), buf, 1);           \
  1192             if ((ret) >= 0) break;                      \
  1192 	    if ((ret) >= 0) break;                      \
  1193             if (errno != EINTR) {                       \
  1193 	    if (errno != EINTR) {                       \
  1194                 break;                                  \
  1194 		break;                                  \
  1195             }                                           \
  1195 	    }                                           \
  1196             __HANDLE_INTERRUPTS__;                      \
  1196 	    __HANDLE_INTERRUPTS__;                      \
  1197         }                                               \
  1197 	}                                               \
  1198    }
  1198    }
  1199 # endif /* use STDIO */
  1199 # endif /* use STDIO */
  1200 
  1200 
  1201 /*
  1201 /*
  1202  * write_bytes from a c-buffer
  1202  * write_bytes from a c-buffer
  1204  */
  1204  */
  1205 # ifdef NO_STDIO
  1205 # ifdef NO_STDIO
  1206 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1206 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1207     (ret) = 0;                                          \
  1207     (ret) = 0;                                          \
  1208     {                                                   \
  1208     {                                                   \
  1209         int __offs = 0;                                 \
  1209 	int __offs = 0;                                 \
  1210         while (__offs < (cnt)) {                        \
  1210 	while (__offs < (cnt)) {                        \
  1211             CLEAR_ERRNO;                                \
  1211 	    CLEAR_ERRNO;                                \
  1212             ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \
  1212 	    ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \
  1213             if (ret <= 0) {                             \
  1213 	    if (ret <= 0) {                             \
  1214                 if (ret < 0 && errno == EINTR) {        \
  1214 		if (ret < 0 && errno == EINTR) {        \
  1215                     __HANDLE_INTERRUPTS__;              \
  1215 		    __HANDLE_INTERRUPTS__;              \
  1216                     continue;                           \
  1216 		    continue;                           \
  1217                 }                                       \
  1217 		}                                       \
  1218                 break;                                  \
  1218 		break;                                  \
  1219             }                                           \
  1219 	    }                                           \
  1220             __offs += (ret);                            \
  1220 	    __offs += (ret);                            \
  1221         }                                               \
  1221 	}                                               \
  1222         if (__offs > 0)                                 \
  1222 	if (__offs > 0)                                 \
  1223             (ret) = __offs;                             \
  1223 	    (ret) = __offs;                             \
  1224    }
  1224    }
  1225 # else /* use STDIO */
  1225 # else /* use STDIO */
  1226 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1226 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1227     (ret) = 0;                                          \
  1227     (ret) = 0;                                          \
  1228     if (isBuffered) {                                   \
  1228     if (isBuffered) {                                   \
  1229         int __offs = 0;                                 \
  1229 	int __offs = 0;                                 \
  1230         while (__offs < (cnt)) {                        \
  1230 	while (__offs < (cnt)) {                        \
  1231             CLEAR_ERRNO;                                \
  1231 	    CLEAR_ERRNO;                                \
  1232             (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
  1232 	    (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
  1233             if ((ret) <= 0) {                            \
  1233 	    if ((ret) <= 0) {                            \
  1234                 if (ferror(f)) {                        \
  1234 		if (ferror(f)) {                        \
  1235                     if (errno == EINTR) {               \
  1235 		    if (errno == EINTR) {               \
  1236                         __HANDLE_INTERRUPTS__;          \
  1236 			__HANDLE_INTERRUPTS__;          \
  1237                         clearerr(f);                    \
  1237 			clearerr(f);                    \
  1238                         continue;                       \
  1238 			continue;                       \
  1239                     }                                   \
  1239 		    }                                   \
  1240                 } else {                                \
  1240 		} else {                                \
  1241                     (ret) = 0;                          \
  1241 		    (ret) = 0;                          \
  1242                 }                                       \
  1242 		}                                       \
  1243                 break;                                  \
  1243 		break;                                  \
  1244             }                                           \
  1244 	    }                                           \
  1245             __offs += (ret);                            \
  1245 	    __offs += (ret);                            \
  1246         }                                               \
  1246 	}                                               \
  1247         if (__offs > 0)                                 \
  1247 	if (__offs > 0)                                 \
  1248             (ret) = __offs;                             \
  1248 	    (ret) = __offs;                             \
  1249     } else {                                            \
  1249     } else {                                            \
  1250         int __offs = 0;                                 \
  1250 	int __offs = 0;                                 \
  1251         while (__offs < (cnt)) {                        \
  1251 	while (__offs < (cnt)) {                        \
  1252             CLEAR_ERRNO;                                \
  1252 	    CLEAR_ERRNO;                                \
  1253             (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\
  1253 	    (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\
  1254             if ((ret) <= 0) {                           \
  1254 	    if ((ret) <= 0) {                           \
  1255                 if ((ret) < 0) {                        \
  1255 		if ((ret) < 0) {                        \
  1256                     if (errno == EINTR) {               \
  1256 		    if (errno == EINTR) {               \
  1257                         __HANDLE_INTERRUPTS__;          \
  1257 			__HANDLE_INTERRUPTS__;          \
  1258                         continue;                       \
  1258 			continue;                       \
  1259                     }                                   \
  1259 		    }                                   \
  1260                 }                                       \
  1260 		}                                       \
  1261                 break;                                  \
  1261 		break;                                  \
  1262             }                                           \
  1262 	    }                                           \
  1263             __offs += (ret);                            \
  1263 	    __offs += (ret);                            \
  1264         }                                               \
  1264 	}                                               \
  1265         if (__offs > 0)                                 \
  1265 	if (__offs > 0)                                 \
  1266             (ret) = __offs;                             \
  1266 	    (ret) = __offs;                             \
  1267    }
  1267    }
  1268 # endif /* use STDIO */
  1268 # endif /* use STDIO */
  1269 
  1269 
  1270 /*
  1270 /*
  1271  * write_bytes from an object
  1271  * write_bytes from an object
  1275 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1275 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1276   {                                                     \
  1276   {                                                     \
  1277     int __ooffs = obj_offs;                             \
  1277     int __ooffs = obj_offs;                             \
  1278     int __offs = 0;                                     \
  1278     int __offs = 0;                                     \
  1279     char *buf = (char *)(obj);                          \
  1279     char *buf = (char *)(obj);                          \
  1280                                                         \
  1280 							\
  1281     (ret) = 0;                                          \
  1281     (ret) = 0;                                          \
  1282     {                                                   \
  1282     {                                                   \
  1283         while (__offs < (cnt)) {                        \
  1283 	while (__offs < (cnt)) {                        \
  1284             CLEAR_ERRNO;                                \
  1284 	    CLEAR_ERRNO;                                \
  1285             ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1285 	    ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1286             if (ret <= 0) {                             \
  1286 	    if (ret <= 0) {                             \
  1287                 if (ret < 0 && errno == EINTR) {        \
  1287 		if (ret < 0 && errno == EINTR) {        \
  1288                     __HANDLE_INTERRUPTS__;              \
  1288 		    __HANDLE_INTERRUPTS__;              \
  1289                     /* refetch */                       \
  1289 		    /* refetch */                       \
  1290                     buf = (char *)(obj);                \
  1290 		    buf = (char *)(obj);                \
  1291                     continue;                           \
  1291 		    continue;                           \
  1292                 }                                       \
  1292 		}                                       \
  1293                 break;                                  \
  1293 		break;                                  \
  1294             }                                           \
  1294 	    }                                           \
  1295             __offs += (ret);                            \
  1295 	    __offs += (ret);                            \
  1296         }                                               \
  1296 	}                                               \
  1297         if (__offs > 0)                                 \
  1297 	if (__offs > 0)                                 \
  1298             (ret) = __offs;                             \
  1298 	    (ret) = __offs;                             \
  1299     }                                                   \
  1299     }                                                   \
  1300   }
  1300   }
  1301 # else /* use STDIO */
  1301 # else /* use STDIO */
  1302 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1302 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1303   {                                                     \
  1303   {                                                     \
  1304     int __ooffs = obj_offs;                             \
  1304     int __ooffs = obj_offs;                             \
  1305     int __offs = 0;                                     \
  1305     int __offs = 0;                                     \
  1306     char *buf = (char *)(obj);                          \
  1306     char *buf = (char *)(obj);                          \
  1307                                                         \
  1307 							\
  1308     (ret) = 0;                                          \
  1308     (ret) = 0;                                          \
  1309     if (isBuffered) {                                   \
  1309     if (isBuffered) {                                   \
  1310         while (__offs < (cnt)) {                        \
  1310 	while (__offs < (cnt)) {                        \
  1311             CLEAR_ERRNO;                                \
  1311 	    CLEAR_ERRNO;                                \
  1312             (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f);  \
  1312 	    (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f);  \
  1313             if ((ret) <= 0) {                           \
  1313 	    if ((ret) <= 0) {                           \
  1314                 if (ferror(f)) {                        \
  1314 		if (ferror(f)) {                        \
  1315                     if (errno == EINTR) {               \
  1315 		    if (errno == EINTR) {               \
  1316                         __HANDLE_INTERRUPTS__;          \
  1316 			__HANDLE_INTERRUPTS__;          \
  1317                         /* refetch */                   \
  1317 			/* refetch */                   \
  1318                         buf = (char *)(obj);            \
  1318 			buf = (char *)(obj);            \
  1319                         clearerr(f);                    \
  1319 			clearerr(f);                    \
  1320                         continue;                       \
  1320 			continue;                       \
  1321                     }                                   \
  1321 		    }                                   \
  1322                     break;                              \
  1322 		    break;                              \
  1323                 } else {                                \
  1323 		} else {                                \
  1324                     (ret) = 0;                          \
  1324 		    (ret) = 0;                          \
  1325                 }                                       \
  1325 		}                                       \
  1326             }                                           \
  1326 	    }                                           \
  1327             __offs += (ret);                            \
  1327 	    __offs += (ret);                            \
  1328         }                                               \
  1328 	}                                               \
  1329     } else {                                            \
  1329     } else {                                            \
  1330         while (__offs < (cnt)) {                        \
  1330 	while (__offs < (cnt)) {                        \
  1331             CLEAR_ERRNO;                                \
  1331 	    CLEAR_ERRNO;                                \
  1332             (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \
  1332 	    (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \
  1333             if ((ret) <= 0) {                           \
  1333 	    if ((ret) <= 0) {                           \
  1334                 if ((ret) < 0) {                        \
  1334 		if ((ret) < 0) {                        \
  1335                     if (errno == EINTR){                \
  1335 		    if (errno == EINTR){                \
  1336                         __HANDLE_INTERRUPTS__;          \
  1336 			__HANDLE_INTERRUPTS__;          \
  1337                         /* refetch */                   \
  1337 			/* refetch */                   \
  1338                         buf = (char *)(obj);            \
  1338 			buf = (char *)(obj);            \
  1339                         continue;                       \
  1339 			continue;                       \
  1340                     }                                   \
  1340 		    }                                   \
  1341                 }                                       \
  1341 		}                                       \
  1342                 break;                                  \
  1342 		break;                                  \
  1343             }                                           \
  1343 	    }                                           \
  1344             __offs += (ret);                            \
  1344 	    __offs += (ret);                            \
  1345         }                                               \
  1345 	}                                               \
  1346     }                                                   \
  1346     }                                                   \
  1347     if (__offs > 0)                                     \
  1347     if (__offs > 0)                                     \
  1348         (ret) = __offs;                                 \
  1348 	(ret) = __offs;                                 \
  1349   }
  1349   }
  1350 # endif /* use STDIO */
  1350 # endif /* use STDIO */
  1351 #endif /* unix */
  1351 #endif /* unix */
  1352 %}
  1352 %}
  1353 ! !
  1353 ! !
  1355 !ExternalStream class methodsFor:'documentation'!
  1355 !ExternalStream class methodsFor:'documentation'!
  1356 
  1356 
  1357 copyright
  1357 copyright
  1358 "
  1358 "
  1359  COPYRIGHT (c) 1988 by Claus Gittinger
  1359  COPYRIGHT (c) 1988 by Claus Gittinger
  1360               All Rights Reserved
  1360 	      All Rights Reserved
  1361 
  1361 
  1362  This software is furnished under a license and may be used
  1362  This software is furnished under a license and may be used
  1363  only in accordance with the terms of that license and with the
  1363  only in accordance with the terms of that license and with the
  1364  inclusion of the above copyright notice.   This software may not
  1364  inclusion of the above copyright notice.   This software may not
  1365  be provided or otherwise made available to, or used by, any
  1365  be provided or otherwise made available to, or used by, any
  1405       if the contents changed in the meantime.
  1405       if the contents changed in the meantime.
  1406       Therefore, it is a good idea to reopen files and check for these things at restart time.
  1406       Therefore, it is a good idea to reopen files and check for these things at restart time.
  1407 
  1407 
  1408     [Instance variables:]
  1408     [Instance variables:]
  1409 
  1409 
  1410         handleType      <Symbol>        desribes what handle is:
  1410 	handleType      <Symbol>        desribes what handle is:
  1411                                             win32: #fileHandle, #socketHandle,
  1411 					    win32: #fileHandle, #socketHandle,
  1412                                                    #filePointer, #socketFilePointer, #pipeFilePointer
  1412 						   #filePointer, #socketFilePointer, #pipeFilePointer
  1413                                             unix: #filePointer, #socketFilePointer, #pipeFilePointer
  1413 					    unix: #filePointer, #socketFilePointer, #pipeFilePointer
  1414                                         needed for win32, which uses different APIs for the different handles (sigh)
  1414 					needed for win32, which uses different APIs for the different handles (sigh)
  1415         handle          <Integer>       used to be always a filePointer somehow mapped to an integer (FILE* - not the fd);
  1415 	handle          <Integer>       used to be always a filePointer somehow mapped to an integer (FILE* - not the fd);
  1416                                         now, either a filePointer or a handle (win32)
  1416 					now, either a filePointer or a handle (win32)
  1417         mode            <Symbol>        #readwrite, #readonly or #writeonly
  1417 	mode            <Symbol>        #readwrite, #readonly or #writeonly
  1418         buffered        <Boolean>       true, if buffered (i.e. collects characters - does
  1418 	buffered        <Boolean>       true, if buffered (i.e. collects characters - does
  1419                                         not output immediately)
  1419 					not output immediately)
  1420         binary          <Boolean>       true if in binary mode (reads bytes instead of chars)
  1420 	binary          <Boolean>       true if in binary mode (reads bytes instead of chars)
  1421         eolMode         <Symbol>        one of nil, #nl, #cr or #crlf.
  1421 	eolMode         <Symbol>        one of nil, #nl, #cr or #crlf.
  1422                                         determines how lines should be terminated.
  1422 					determines how lines should be terminated.
  1423                                         nil -> newLine (as in Unix);
  1423 					nil -> newLine (as in Unix);
  1424                                         #crlf -> with cr-lf (as in MSDOS)
  1424 					#crlf -> with cr-lf (as in MSDOS)
  1425                                         #cr -> with cr (as in VMS)
  1425 					#cr -> with cr (as in VMS)
  1426         hitEOF          <Boolean>       true, if EOF was reached
  1426 	hitEOF          <Boolean>       true, if EOF was reached
  1427 
  1427 
  1428         lastErrorNumber <Integer>       the value of errno (only valid right after the error -
  1428 	lastErrorNumber <Integer>       the value of errno (only valid right after the error -
  1429                                         updated with next i/o operation)
  1429 					updated with next i/o operation)
  1430 
  1430 
  1431     [Class variables:]
  1431     [Class variables:]
  1432         Lobby           <Registry>      keeps track of used ext-streams (to free up FILE*'s)
  1432 	Lobby           <Registry>      keeps track of used ext-streams (to free up FILE*'s)
  1433 
  1433 
  1434         StreamErrorSignal       <Signal> parent of all stream errors (see Stream class)
  1434 	StreamErrorSignal       <Signal> parent of all stream errors (see Stream class)
  1435         InvalidReadSignal       <Signal> raised on read from writeonly stream
  1435 	InvalidReadSignal       <Signal> raised on read from writeonly stream
  1436         InvalidWriteSignal      <Signal> raised on write to readonly stream
  1436 	InvalidWriteSignal      <Signal> raised on write to readonly stream
  1437         InvalidModeSignal       <Signal> raised on text I/O with binary-stream
  1437 	InvalidModeSignal       <Signal> raised on text I/O with binary-stream
  1438                                          or binary I/O with text-stream
  1438 					 or binary I/O with text-stream
  1439         OpenErrorSignal         <Signal> raised if open fails
  1439 	OpenErrorSignal         <Signal> raised if open fails
  1440         StreamNotOpenSignal     <Signal> raised on I/O with non-open stream
  1440 	StreamNotOpenSignal     <Signal> raised on I/O with non-open stream
  1441 
  1441 
  1442     Additional notes:
  1442     Additional notes:
  1443       This class is implemented using the underlying stdio-c library package, which
  1443       This class is implemented using the underlying stdio-c library package, which
  1444       has both advantages and disadvantages: since it is portable (posix defined), porting
  1444       has both advantages and disadvantages: since it is portable (posix defined), porting
  1445       ST/X to non-Unix machines is simplified. The disadvantage is that the stdio library
  1445       ST/X to non-Unix machines is simplified. The disadvantage is that the stdio library
  1469       fseek whenever we are about to read after write and vice versa.
  1469       fseek whenever we are about to read after write and vice versa.
  1470       Two macros (__READING__ and __WRITING__) have been defined to be used before every
  1470       Two macros (__READING__ and __WRITING__) have been defined to be used before every
  1471       fread/fgetc and fwrite/putc respectively.
  1471       fread/fgetc and fwrite/putc respectively.
  1472 
  1472 
  1473     [author:]
  1473     [author:]
  1474         Claus Gittinger
  1474 	Claus Gittinger
  1475         Stefan Vogel (many, many fixes ...)
  1475 	Stefan Vogel (many, many fixes ...)
  1476 
  1476 
  1477     [see also:]
  1477     [see also:]
  1478         FileStream Socket PipeStream
  1478 	FileStream Socket PipeStream
  1479         Filename OperatingSystem
  1479 	Filename OperatingSystem
  1480 "
  1480 "
  1481 !
  1481 !
  1482 
  1482 
  1483 examples
  1483 examples
  1484 "
  1484 "
  1485     open a file, read the contents and display it in a textView:
  1485     open a file, read the contents and display it in a textView:
  1486                                                                         [exBegin]
  1486 									[exBegin]
  1487         |topView scrollPane textView fileStream text|
  1487 	|topView scrollPane textView fileStream text|
  1488 
  1488 
  1489         topView := StandardSystemView new.
  1489 	topView := StandardSystemView new.
  1490         topView label:'contents of Makefile'.
  1490 	topView label:'contents of Makefile'.
  1491 
  1491 
  1492         scrollPane := HVScrollableView in:topView.
  1492 	scrollPane := HVScrollableView in:topView.
  1493         scrollPane origin:0.0@0.0 corner:1.0@1.0.
  1493 	scrollPane origin:0.0@0.0 corner:1.0@1.0.
  1494 
  1494 
  1495         textView := EditTextView new.
  1495 	textView := EditTextView new.
  1496         scrollPane scrolledView:textView.
  1496 	scrollPane scrolledView:textView.
  1497 
  1497 
  1498         fileStream := 'Makefile' asFilename readStream.
  1498 	fileStream := 'Makefile' asFilename readStream.
  1499         text := fileStream upToEnd.
  1499 	text := fileStream upToEnd.
  1500         fileStream close.
  1500 	fileStream close.
  1501 
  1501 
  1502         textView contents:text.
  1502 	textView contents:text.
  1503 
  1503 
  1504         topView open.
  1504 	topView open.
  1505                                                                         [exEnd]
  1505 									[exEnd]
  1506 
  1506 
  1507 
  1507 
  1508     Notice, all of the above can also be done (simply) as:
  1508     Notice, all of the above can also be done (simply) as:
  1509                                                                         [exBegin]
  1509 									[exBegin]
  1510         EditTextView openOn:'Makefile'
  1510 	EditTextView openOn:'Makefile'
  1511                                                                         [exEnd]
  1511 									[exEnd]
  1512 "
  1512 "
  1513 ! !
  1513 ! !
  1514 
  1514 
  1515 !ExternalStream class methodsFor:'initialization'!
  1515 !ExternalStream class methodsFor:'initialization'!
  1516 
  1516 
  1517 closeFiles
  1517 closeFiles
  1518     "close all files.
  1518     "close all files.
  1519      To be called on exit of Smalltalk."
  1519      To be called on exit of Smalltalk."
  1520 
  1520 
  1521     Lobby do:[:eachFileStream |
  1521     Lobby do:[:eachFileStream |
  1522         (eachFileStream ~~ Stdin 
  1522 	(eachFileStream ~~ Stdin
  1523          and:[eachFileStream ~~ Stdout 
  1523 	 and:[eachFileStream ~~ Stdout
  1524          and:[eachFileStream ~~ Stderr]]) ifTrue:[
  1524 	 and:[eachFileStream ~~ Stderr]]) ifTrue:[
  1525             eachFileStream close
  1525 	    eachFileStream close
  1526         ].
  1526 	].
  1527     ].
  1527     ].
  1528 
  1528 
  1529     "Modified: / 25-04-2018 / 15:23:41 / stefan"
  1529     "Modified: / 25-04-2018 / 15:23:41 / stefan"
  1530 !
  1530 !
  1531 
  1531 
  1532 initDefaultEOLMode
  1532 initDefaultEOLMode
  1533     OperatingSystem isUNIXlike ifTrue:[
  1533     OperatingSystem isUNIXlike ifTrue:[
  1534         "/ unix EOL conventions
  1534 	"/ unix EOL conventions
  1535         DefaultEOLMode := #nl
  1535 	DefaultEOLMode := #nl
  1536     ] ifFalse:[
  1536     ] ifFalse:[
  1537         OperatingSystem isVMSlike ifTrue:[
  1537 	OperatingSystem isVMSlike ifTrue:[
  1538             "/ vms EOL conventions
  1538 	    "/ vms EOL conventions
  1539             DefaultEOLMode := #cr
  1539 	    DefaultEOLMode := #cr
  1540         ] ifFalse:[
  1540 	] ifFalse:[
  1541             "/ msdos EOL conventions
  1541 	    "/ msdos EOL conventions
  1542             "/ msdos uses #crlf.
  1542 	    "/ msdos uses #crlf.
  1543             "/ the following breaks all programs, which do not explicitly
  1543 	    "/ the following breaks all programs, which do not explicitly
  1544             "/ change th eolMode when writing/reading binary files (zip reader)
  1544 	    "/ change th eolMode when writing/reading binary files (zip reader)
  1545             "/ MUST change all classes before doing the following.
  1545 	    "/ MUST change all classes before doing the following.
  1546             "/ Anyway: for backward compatibility (swisscom), it is left in this
  1546 	    "/ Anyway: for backward compatibility (swisscom), it is left in this
  1547             "/ mode (for a while, I hope).
  1547 	    "/ mode (for a while, I hope).
  1548             DefaultEOLMode := #crlf.
  1548 	    DefaultEOLMode := #crlf.
  1549 
  1549 
  1550             "/ DefaultEOLMode := #nl
  1550 	    "/ DefaultEOLMode := #nl
  1551         ]
  1551 	]
  1552     ]
  1552     ]
  1553 !
  1553 !
  1554 
  1554 
  1555 initModeStrings
  1555 initModeStrings
  1556     "initialize modeStrings which are passed down to the underlying
  1556     "initialize modeStrings which are passed down to the underlying
  1557      fopen/fdopen functions."
  1557      fopen/fdopen functions."
  1558 
  1558 
  1559     OperatingSystem isMSDOSlike ifTrue:[
  1559     OperatingSystem isMSDOSlike ifTrue:[
  1560         ReadMode := 'rb'.
  1560 	ReadMode := 'rb'.
  1561         ReadWriteMode := 'rb+'.
  1561 	ReadWriteMode := 'rb+'.
  1562         WriteMode := 'wb'.
  1562 	WriteMode := 'wb'.
  1563         AppendMode := 'ab+'.
  1563 	AppendMode := 'ab+'.
  1564         CreateReadWriteMode := 'wb+'.
  1564 	CreateReadWriteMode := 'wb+'.
  1565     ] ifFalse:[
  1565     ] ifFalse:[
  1566         ReadMode := 'r'.
  1566 	ReadMode := 'r'.
  1567         ReadWriteMode := 'r+'.
  1567 	ReadWriteMode := 'r+'.
  1568         WriteMode := 'w'.
  1568 	WriteMode := 'w'.
  1569         AppendMode := 'a+'.
  1569 	AppendMode := 'a+'.
  1570         CreateReadWriteMode := 'w+'.
  1570 	CreateReadWriteMode := 'w+'.
  1571     ]
  1571     ]
  1572 !
  1572 !
  1573 
  1573 
  1574 initialize
  1574 initialize
  1575     OpenErrorSignal isNil ifTrue:[
  1575     OpenErrorSignal isNil ifTrue:[
  1576         OpenErrorSignal := OpenError.
  1576 	OpenErrorSignal := OpenError.
  1577         OpenErrorSignal notifierString:'open error'.
  1577 	OpenErrorSignal notifierString:'open error'.
  1578 
  1578 
  1579         InvalidReadSignal := InvalidReadError.
  1579 	InvalidReadSignal := InvalidReadError.
  1580         InvalidReadSignal notifierString:'stream does not support reading'.
  1580 	InvalidReadSignal notifierString:'stream does not support reading'.
  1581 
  1581 
  1582         InvalidWriteSignal := InvalidWriteError.
  1582 	InvalidWriteSignal := InvalidWriteError.
  1583         InvalidWriteSignal notifierString:'stream does not support writing'.
  1583 	InvalidWriteSignal notifierString:'stream does not support writing'.
  1584 
  1584 
  1585         InvalidModeSignal := InvalidModeError.
  1585 	InvalidModeSignal := InvalidModeError.
  1586         InvalidModeSignal notifierString:'binary/text mode mismatch'.
  1586 	InvalidModeSignal notifierString:'binary/text mode mismatch'.
  1587 
  1587 
  1588         InvalidOperationSignal := InvalidOperationError.
  1588 	InvalidOperationSignal := InvalidOperationError.
  1589         InvalidOperationSignal notifierString:'unsupported file operation'.
  1589 	InvalidOperationSignal notifierString:'unsupported file operation'.
  1590 
  1590 
  1591         StreamNotOpenSignal := StreamNotOpenError.
  1591 	StreamNotOpenSignal := StreamNotOpenError.
  1592         StreamNotOpenSignal notifierString:'stream is not open'.
  1592 	StreamNotOpenSignal notifierString:'stream is not open'.
  1593 
  1593 
  1594         StreamIOErrorSignal := StreamIOError.
  1594 	StreamIOErrorSignal := StreamIOError.
  1595         StreamIOErrorSignal notifierString:'I/O error'.
  1595 	StreamIOErrorSignal notifierString:'I/O error'.
  1596 
  1596 
  1597         "/ self patchByteOrderOptimizedMethods
  1597 	"/ self patchByteOrderOptimizedMethods
  1598     ].
  1598     ].
  1599 
  1599 
  1600     Lobby isNil ifTrue:[
  1600     Lobby isNil ifTrue:[
  1601         Lobby := Registry new.
  1601 	Lobby := Registry new.
  1602 
  1602 
  1603         "want to get informed when returning from snapshot"
  1603 	"want to get informed when returning from snapshot"
  1604         ObjectMemory addDependent:self
  1604 	ObjectMemory addDependent:self
  1605     ].
  1605     ].
  1606     DefaultEOLMode isNil ifTrue:[
  1606     DefaultEOLMode isNil ifTrue:[
  1607         self initDefaultEOLMode.
  1607 	self initDefaultEOLMode.
  1608     ].
  1608     ].
  1609     ReadMode isNil ifTrue:[
  1609     ReadMode isNil ifTrue:[
  1610         self initModeStrings.
  1610 	self initModeStrings.
  1611     ].
  1611     ].
  1612 
  1612 
  1613     "limit the amount of newspace to be used for non-tenurable executors to 5%"
  1613     "limit the amount of newspace to be used for non-tenurable executors to 5%"
  1614     "/ MaxNonTenurableExecutors := ObjectMemory newSpaceSize // (Socket sizeOfInst:0) // 20.
  1614     "/ MaxNonTenurableExecutors := ObjectMemory newSpaceSize // (Socket sizeOfInst:0) // 20.
  1615     "/ cg: changed because Socket is not in libbasic. Thus, standalone (libbasic only)
  1615     "/ cg: changed because Socket is not in libbasic. Thus, standalone (libbasic only)
  1620 !
  1620 !
  1621 
  1621 
  1622 patchByteOrderOptimizedMethods
  1622 patchByteOrderOptimizedMethods
  1623     "EXPERIMENTAL (not yet done by default):
  1623     "EXPERIMENTAL (not yet done by default):
  1624      change the underlying implementation of
  1624      change the underlying implementation of
  1625         nextPutInt16MSB / nextPutInt16LSB
  1625 	nextPutInt16MSB / nextPutInt16LSB
  1626         nextPutInt32MSB / nextPutInt32LSB
  1626 	nextPutInt32MSB / nextPutInt32LSB
  1627      to the corresponding NATIVE methods."
  1627      to the corresponding NATIVE methods."
  1628 
  1628 
  1629     |native16 native32|
  1629     |native16 native32|
  1630 
  1630 
  1631     native16 := self compiledMethodAt:#nextPutInt16NATIVE:.
  1631     native16 := self compiledMethodAt:#nextPutInt16NATIVE:.
  1632     native32 := self compiledMethodAt:#nextPutInt32NATIVE:.
  1632     native32 := self compiledMethodAt:#nextPutInt32NATIVE:.
  1633 
  1633 
  1634     UninterpretedBytes isBigEndian ifTrue:[
  1634     UninterpretedBytes isBigEndian ifTrue:[
  1635         (self compiledMethodAt:#nextPutInt16MSB:) code:(native16 code).
  1635 	(self compiledMethodAt:#nextPutInt16MSB:) code:(native16 code).
  1636         (self compiledMethodAt:#nextPutInt32MSB:) code:(native32 code).
  1636 	(self compiledMethodAt:#nextPutInt32MSB:) code:(native32 code).
  1637     ] ifFalse:[
  1637     ] ifFalse:[
  1638         (self compiledMethodAt:#nextPutInt16LSB:) code:(native16 code).
  1638 	(self compiledMethodAt:#nextPutInt16LSB:) code:(native16 code).
  1639         (self compiledMethodAt:#nextPutInt32LSB:) code:(native32 code).
  1639 	(self compiledMethodAt:#nextPutInt32LSB:) code:(native32 code).
  1640     ].
  1640     ].
  1641 !
  1641 !
  1642 
  1642 
  1643 reOpenFiles
  1643 reOpenFiles
  1644     "reopen all files (if possible) after a snapShot load.
  1644     "reopen all files (if possible) after a snapShot load.
  1645      This is invoked via the #earlyRestart change notification."
  1645      This is invoked via the #earlyRestart change notification."
  1646 
  1646 
  1647     Lobby do:[:eachFileStream |
  1647     Lobby do:[:eachFileStream |
  1648         eachFileStream reOpen
  1648 	eachFileStream reOpen
  1649     ].
  1649     ].
  1650 !
  1650 !
  1651 
  1651 
  1652 update:something with:aParameter from:changedObject
  1652 update:something with:aParameter from:changedObject
  1653     "have to reopen files when returning from snapshot"
  1653     "have to reopen files when returning from snapshot"
  1654 
  1654 
  1655     something == #earlyRestart ifTrue:[
  1655     something == #earlyRestart ifTrue:[
  1656         self reOpenFiles.
  1656 	self reOpenFiles.
  1657         self initDefaultEOLMode
  1657 	self initDefaultEOLMode
  1658     ]
  1658     ]
  1659 
  1659 
  1660     "Created: 15.6.1996 / 15:19:59 / cg"
  1660     "Created: 15.6.1996 / 15:19:59 / cg"
  1661 ! !
  1661 ! !
  1662 
  1662 
  1690      The modeSymbol-argument is #readonly, #readwrite, ....
  1690      The modeSymbol-argument is #readonly, #readwrite, ....
  1691      This may be used to wrap fd's as returned by user
  1691      This may be used to wrap fd's as returned by user
  1692      primitive code, or to wrap pipe-fds into externalStreams."
  1692      primitive code, or to wrap pipe-fds into externalStreams."
  1693 
  1693 
  1694     ^ self new
  1694     ^ self new
  1695         buffered:buffered;
  1695 	buffered:buffered;
  1696         connectTo:aFileDescriptor withMode:modeSymbol handleType:handleTypeSymbol.
  1696 	connectTo:aFileDescriptor withMode:modeSymbol handleType:handleTypeSymbol.
  1697 
  1697 
  1698     "
  1698     "
  1699      the example below will probably fail (15 is a random FD):
  1699      the example below will probably fail (15 is a random FD):
  1700 
  1700 
  1701      |s|
  1701      |s|
  1760      rs := ExternalStream forReadingFromFileDescriptor:readFd.
  1760      rs := ExternalStream forReadingFromFileDescriptor:readFd.
  1761      ws := ExternalStream forWritingToFileDescriptor:writeFd.
  1761      ws := ExternalStream forWritingToFileDescriptor:writeFd.
  1762 
  1762 
  1763      'read ...'.
  1763      'read ...'.
  1764      [
  1764      [
  1765          1 to:10 do:[:i |
  1765 	 1 to:10 do:[:i |
  1766              Transcript showCR:rs nextLine
  1766 	     Transcript showCR:rs nextLine
  1767          ].
  1767 	 ].
  1768          rs close.
  1768 	 rs close.
  1769      ] forkAt:7.
  1769      ] forkAt:7.
  1770 
  1770 
  1771      'write ...'.
  1771      'write ...'.
  1772      [
  1772      [
  1773          1 to:10 do:[:i |
  1773 	 1 to:10 do:[:i |
  1774              ws nextPutAll:'hello world '; nextPutAll:i printString; cr
  1774 	     ws nextPutAll:'hello world '; nextPutAll:i printString; cr
  1775          ].
  1775 	 ].
  1776          ws close.
  1776 	 ws close.
  1777      ] fork.
  1777      ] fork.
  1778 
  1778 
  1779     "
  1779     "
  1780 
  1780 
  1781     "Created: 29.2.1996 / 18:14:24 / cg"
  1781     "Created: 29.2.1996 / 18:14:24 / cg"
  1874     "answer a collection of open Streams having this class"
  1874     "answer a collection of open Streams having this class"
  1875 
  1875 
  1876     |openStreams|
  1876     |openStreams|
  1877 
  1877 
  1878     openStreams := OrderedCollection new.
  1878     openStreams := OrderedCollection new.
  1879     Lobby keysDo:[:eachStream| 
  1879     Lobby keysDo:[:eachStream|
  1880                     (eachStream isKindOf:self) ifTrue:[
  1880 		    (eachStream isKindOf:self) ifTrue:[
  1881                         openStreams add:eachStream
  1881 			openStreams add:eachStream
  1882                     ]
  1882 		    ]
  1883                 ].
  1883 		].
  1884 
  1884 
  1885     ^ openStreams
  1885     ^ openStreams
  1886 
  1886 
  1887     "
  1887     "
  1888         self openStreams
  1888 	self openStreams
  1889         Socket openStreams
  1889 	Socket openStreams
  1890         NonPositionableExternalStream openStreams
  1890 	NonPositionableExternalStream openStreams
  1891     "
  1891     "
  1892 
  1892 
  1893     "Created: / 24-04-2018 / 09:23:33 / stefan"
  1893     "Created: / 24-04-2018 / 09:23:33 / stefan"
  1894 ! !
  1894 ! !
  1895 
  1895 
  1907      When nil, a somewhat conservative compromise is used."
  1907      When nil, a somewhat conservative compromise is used."
  1908 
  1908 
  1909     DefaultCopyBufferSize notNil ifTrue:[^ DefaultCopyBufferSize].
  1909     DefaultCopyBufferSize notNil ifTrue:[^ DefaultCopyBufferSize].
  1910 
  1910 
  1911     OperatingSystem isMSDOSlike ifTrue:[
  1911     OperatingSystem isMSDOSlike ifTrue:[
  1912         OperatingSystem isWin7Like ifTrue:[
  1912 	OperatingSystem isWin7Like ifTrue:[
  1913             ^ 64*1024
  1913 	    ^ 64*1024
  1914         ] ifFalse:[
  1914 	] ifFalse:[
  1915             "/ mhmh - NT hangs, when copying bigger blocks to a network drive - why ?
  1915 	    "/ mhmh - NT hangs, when copying bigger blocks to a network drive - why ?
  1916             ^ 1 * 1024.
  1916 	    ^ 1 * 1024.
  1917         ].
  1917 	].
  1918     ].
  1918     ].
  1919     ^ 32 * 1024.
  1919     ^ 32 * 1024.
  1920 !
  1920 !
  1921 
  1921 
  1922 defaultCopyBufferSize:anInteger
  1922 defaultCopyBufferSize:anInteger
  1965 reportOn:anErrorSymbolOrNumber
  1965 reportOn:anErrorSymbolOrNumber
  1966     "an error occurred.
  1966     "an error occurred.
  1967      Report it via an Exception"
  1967      Report it via an Exception"
  1968 
  1968 
  1969     anErrorSymbolOrNumber isInteger ifTrue:[
  1969     anErrorSymbolOrNumber isInteger ifTrue:[
  1970         StreamError
  1970 	StreamError
  1971             raiseRequestWith:anErrorSymbolOrNumber
  1971 	    raiseRequestWith:anErrorSymbolOrNumber
  1972             errorString:(' - os error:' , (OperatingSystem errorTextForNumber:anErrorSymbolOrNumber))
  1972 	    errorString:(' - os error:' , (OperatingSystem errorTextForNumber:anErrorSymbolOrNumber))
  1973     ].
  1973     ].
  1974     (self respondsTo:anErrorSymbolOrNumber) ifTrue:[
  1974     (self respondsTo:anErrorSymbolOrNumber) ifTrue:[
  1975         self perform:anErrorSymbolOrNumber
  1975 	self perform:anErrorSymbolOrNumber
  1976     ] ifFalse:[
  1976     ] ifFalse:[
  1977         StreamError
  1977 	StreamError
  1978             raiseRequestWith:anErrorSymbolOrNumber
  1978 	    raiseRequestWith:anErrorSymbolOrNumber
  1979             errorString:(' - ' , anErrorSymbolOrNumber printString)
  1979 	    errorString:(' - ' , anErrorSymbolOrNumber printString)
  1980     ].
  1980     ].
  1981     ^ false
  1981     ^ false
  1982 ! !
  1982 ! !
  1983 
  1983 
  1984 !ExternalStream class methodsFor:'finalization'!
  1984 !ExternalStream class methodsFor:'finalization'!
  2097      is returned."
  2097      is returned."
  2098 
  2098 
  2099     |text|
  2099     |text|
  2100 
  2100 
  2101     binary ifTrue:[
  2101     binary ifTrue:[
  2102         ^ self upToEnd.
  2102 	^ self upToEnd.
  2103     ].
  2103     ].
  2104 
  2104 
  2105     "/ text mode
  2105     "/ text mode
  2106     text := StringCollection new.
  2106     text := StringCollection new.
  2107     [self atEnd] whileFalse:[
  2107     [self atEnd] whileFalse:[
  2108         |line|
  2108 	|line|
  2109 
  2109 
  2110         line := self nextLine.
  2110 	line := self nextLine.
  2111         line isNil ifTrue:[
  2111 	line isNil ifTrue:[
  2112             ^ text
  2112 	    ^ text
  2113         ].
  2113 	].
  2114         text add:line
  2114 	text add:line
  2115     ].
  2115     ].
  2116     ^ text
  2116     ^ text
  2117 !
  2117 !
  2118 
  2118 
  2119 contentsAsString
  2119 contentsAsString
  2120     "to compensate for the bad naming, use this to make things explicit.
  2120     "to compensate for the bad naming, use this to make things explicit.
  2121      See also #contents, which returns the lines as stringCollection for textFiles."
  2121      See also #contents, which returns the lines as stringCollection for textFiles."
  2122 
  2122 
  2123     binary ifTrue:[
  2123     binary ifTrue:[
  2124         ^ [
  2124 	^ [
  2125             binary := false.
  2125 	    binary := false.
  2126             self contentsOfEntireFile.
  2126 	    self contentsOfEntireFile.
  2127         ] ensure:[
  2127 	] ensure:[
  2128             binary := true.
  2128 	    binary := true.
  2129         ].
  2129 	].
  2130     ].
  2130     ].
  2131 
  2131 
  2132     ^ self contentsOfEntireFile.
  2132     ^ self contentsOfEntireFile.
  2133 
  2133 
  2134     "Modified: / 09-05-2018 / 19:37:36 / stefan"
  2134     "Modified: / 09-05-2018 / 19:37:36 / stefan"
  2147 contentsSpecies
  2147 contentsSpecies
  2148     "return the kind of object to be returned by sub-collection builders
  2148     "return the kind of object to be returned by sub-collection builders
  2149      (such as upTo)"
  2149      (such as upTo)"
  2150 
  2150 
  2151     binary ifTrue:[
  2151     binary ifTrue:[
  2152         ^ ByteArray
  2152 	^ ByteArray
  2153     ].
  2153     ].
  2154     ^ String
  2154     ^ String
  2155 !
  2155 !
  2156 
  2156 
  2157 eolMode
  2157 eolMode
  2158     "return how end-of-line (EOL) is to be marked.
  2158     "return how end-of-line (EOL) is to be marked.
  2159      Returns one one of:
  2159      Returns one one of:
  2160         #crlf         -> add a CR-NL, as in MSDOS
  2160 	#crlf         -> add a CR-NL, as in MSDOS
  2161         #cr           -> add a CR, as in VMS
  2161 	#cr           -> add a CR, as in VMS
  2162         #nl           -> add a NL, as in Unix
  2162 	#nl           -> add a NL, as in Unix
  2163         #eot          -> add an EOT (= 0x04, as used in some modems/protocols)
  2163 	#eot          -> add an EOT (= 0x04, as used in some modems/protocols)
  2164         #etx          -> add an ETX (= 0x03, as used in some modems/protocols)
  2164 	#etx          -> add an ETX (= 0x03, as used in some modems/protocols)
  2165         #nl           -> add a NL, as in Unix
  2165 	#nl           -> add a NL, as in Unix
  2166         nil           -> transparent
  2166 	nil           -> transparent
  2167     "
  2167     "
  2168 
  2168 
  2169     ^ eolMode
  2169     ^ eolMode
  2170 
  2170 
  2171     "Modified (comment): / 06-12-2016 / 14:26:24 / cg"
  2171     "Modified (comment): / 06-12-2016 / 14:26:24 / cg"
  2172 !
  2172 !
  2173 
  2173 
  2174 eolMode:aSymbolOrNil
  2174 eolMode:aSymbolOrNil
  2175     "specify how end-of-line (EOL) is to be marked.
  2175     "specify how end-of-line (EOL) is to be marked.
  2176      The argument may be one of:
  2176      The argument may be one of:
  2177         #crlf         -> add a CR-NL, as in MSDOS
  2177 	#crlf         -> add a CR-NL, as in MSDOS
  2178         #cr           -> add a CR, as in VMS
  2178 	#cr           -> add a CR, as in VMS
  2179         #nl           -> add a NL, as in Unix
  2179 	#nl           -> add a NL, as in Unix
  2180         #eot          -> add an EOT (= 0x04, as used in some modems/protocols)
  2180 	#eot          -> add an EOT (= 0x04, as used in some modems/protocols)
  2181         #etx          -> add an ETX (= 0x03, as used in some modems/protocols)
  2181 	#etx          -> add an ETX (= 0x03, as used in some modems/protocols)
  2182         anyOther      -> like #nl
  2182 	anyOther      -> like #nl
  2183     "
  2183     "
  2184 
  2184 
  2185     aSymbolOrNil == #crnl ifTrue:[
  2185     aSymbolOrNil == #crnl ifTrue:[
  2186         eolMode := #crlf
  2186 	eolMode := #crlf
  2187     ] ifFalse:[
  2187     ] ifFalse:[
  2188         aSymbolOrNil == #lf ifTrue:[
  2188 	aSymbolOrNil == #lf ifTrue:[
  2189             eolMode := #nl
  2189 	    eolMode := #nl
  2190         ] ifFalse:[
  2190 	] ifFalse:[
  2191             eolMode := aSymbolOrNil
  2191 	    eolMode := aSymbolOrNil
  2192         ]
  2192 	]
  2193     ].
  2193     ].
  2194 
  2194 
  2195     "Modified (comment): / 06-12-2016 / 14:26:37 / cg"
  2195     "Modified (comment): / 06-12-2016 / 14:26:37 / cg"
  2196 !
  2196 !
  2197 
  2197 
  2205 %{
  2205 %{
  2206     OBJ _handle  = __INST(handle);
  2206     OBJ _handle  = __INST(handle);
  2207 
  2207 
  2208     fileClosed = false;
  2208     fileClosed = false;
  2209     if (_handle != nil) {
  2209     if (_handle != nil) {
  2210         if ((__INST(handleType) == @symbol(fileHandle))
  2210 	if ((__INST(handleType) == @symbol(fileHandle))
  2211          || (__INST(handleType) == @symbol(socketHandle))) {
  2211 	 || (__INST(handleType) == @symbol(socketHandle))) {
  2212             RETURN (_handle);
  2212 	    RETURN (_handle);
  2213         }
  2213 	}
  2214 
  2214 
  2215         if ((__INST(handleType) == nil)
  2215 	if ((__INST(handleType) == nil)
  2216          || (__INST(handleType) == @symbol(filePointer))
  2216 	 || (__INST(handleType) == @symbol(filePointer))
  2217          || (__INST(handleType) == @symbol(socketFilePointer))
  2217 	 || (__INST(handleType) == @symbol(socketFilePointer))
  2218          || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2218 	 || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2219             FILE *file = __FILEVal(_handle);
  2219 	    FILE *file = __FILEVal(_handle);
  2220             if (file != NULL) {
  2220 	    if (file != NULL) {
  2221                 int fileNo = fileno(file);
  2221 		int fileNo = fileno(file);
  2222 
  2222 
  2223                 if (fileNo >= 0) {
  2223 		if (fileNo >= 0) {
  2224                     RETURN ( __MKINT(fileNo));
  2224 		    RETURN ( __MKINT(fileNo));
  2225                 }
  2225 		}
  2226                 fileClosed = true;
  2226 		fileClosed = true;
  2227             }
  2227 	    }
  2228         }
  2228 	}
  2229     }
  2229     }
  2230 %}.
  2230 %}.
  2231     handle isNil ifTrue:[^ self errorNotOpen].
  2231     handle isNil ifTrue:[^ self errorNotOpen].
  2232     fileClosed ifTrue:[handle := nil. ^ self errorNotOpen].
  2232     fileClosed ifTrue:[handle := nil. ^ self errorNotOpen].
  2233     ^ self fileDescriptorOfFile:handle
  2233     ^ self fileDescriptorOfFile:handle
  2257 
  2257 
  2258 %{
  2258 %{
  2259     OBJ _handle  = __INST(handle);
  2259     OBJ _handle  = __INST(handle);
  2260 
  2260 
  2261     if (_handle != nil) {
  2261     if (_handle != nil) {
  2262         if ((__INST(handleType) == @symbol(fileHandle))
  2262 	if ((__INST(handleType) == @symbol(fileHandle))
  2263          || (__INST(handleType) == @symbol(socketHandle))) {
  2263 	 || (__INST(handleType) == @symbol(socketHandle))) {
  2264             RETURN (_handle);
  2264 	    RETURN (_handle);
  2265         }
  2265 	}
  2266         if (__INST(handleType) == @symbol(pipeFilePointer)) {
  2266 	if (__INST(handleType) == @symbol(pipeFilePointer)) {
  2267             RETURN (__MKINT(fileno(__FILEVal(_handle))));
  2267 	    RETURN (__MKINT(fileno(__FILEVal(_handle))));
  2268         }
  2268 	}
  2269         if ((__INST(handleType) == nil)
  2269 	if ((__INST(handleType) == nil)
  2270          || (__INST(handleType) == @symbol(filePointer))
  2270 	 || (__INST(handleType) == @symbol(filePointer))
  2271          || (__INST(handleType) == @symbol(socketFilePointer))
  2271 	 || (__INST(handleType) == @symbol(socketFilePointer))
  2272          || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2272 	 || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2273 #ifdef __win32__
  2273 #ifdef __win32__
  2274             RETURN(__MKEXTERNALADDRESS(_get_osfhandle(fileno(__FILEVal(_handle)))));
  2274 	    RETURN(__MKEXTERNALADDRESS(_get_osfhandle(fileno(__FILEVal(_handle)))));
  2275 #else
  2275 #else
  2276             FILE *file = __FILEVal(_handle);
  2276 	    FILE *file = __FILEVal(_handle);
  2277             if (file != NULL) {
  2277 	    if (file != NULL) {
  2278                 int fileNo = fileno(file);
  2278 		int fileNo = fileno(file);
  2279                 if (fileNo >= 0) {
  2279 		if (fileNo >= 0) {
  2280                     RETURN (__MKINT(fileNo));
  2280 		    RETURN (__MKINT(fileNo));
  2281                 }
  2281 		}
  2282             }
  2282 	    }
  2283 #endif
  2283 #endif
  2284         }
  2284 	}
  2285     }
  2285     }
  2286 %}.
  2286 %}.
  2287     ^ handle
  2287     ^ handle
  2288 
  2288 
  2289     "Modified: / 07-04-2017 / 16:34:40 / cg"
  2289     "Modified: / 07-04-2017 / 16:34:40 / cg"
  2296      (what you really get is a corresponding integer).
  2296      (what you really get is a corresponding integer).
  2297      You cannot do much with the returned value
  2297      You cannot do much with the returned value
  2298      - except passing it to a primitive, for example."
  2298      - except passing it to a primitive, for example."
  2299 
  2299 
  2300     (handleType isNil or:[handleType == #filePointer]) ifTrue:[
  2300     (handleType isNil or:[handleType == #filePointer]) ifTrue:[
  2301         ^ handle
  2301 	^ handle
  2302     ].
  2302     ].
  2303     ^ self error:'not a FILE*'
  2303     ^ self error:'not a FILE*'
  2304 !
  2304 !
  2305 
  2305 
  2306 handle
  2306 handle
  2353     "turn on or off CRLF sending (instead of LF only) - default is off.
  2353     "turn on or off CRLF sending (instead of LF only) - default is off.
  2354      This method is provided for backward compatibility - see #eolMode:
  2354      This method is provided for backward compatibility - see #eolMode:
  2355      which offers another choice."
  2355      which offers another choice."
  2356 
  2356 
  2357     aBoolean ifTrue:[
  2357     aBoolean ifTrue:[
  2358         eolMode := #crlf
  2358 	eolMode := #crlf
  2359     ] ifFalse:[
  2359     ] ifFalse:[
  2360         eolMode := #nl
  2360 	eolMode := #nl
  2361     ].
  2361     ].
  2362 !
  2362 !
  2363 
  2363 
  2364 writeonly
  2364 writeonly
  2365     "set access mode to writeonly"
  2365     "set access mode to writeonly"
  2381 close
  2381 close
  2382     "Close the stream.
  2382     "Close the stream.
  2383      No error if the stream is not open."
  2383      No error if the stream is not open."
  2384 
  2384 
  2385     self isOpen ifTrue:[
  2385     self isOpen ifTrue:[
  2386         self unregisterForFinalization.
  2386 	self unregisterForFinalization.
  2387         self isOpen ifTrue:[
  2387 	self isOpen ifTrue:[
  2388             self closeFile.
  2388 	    self closeFile.
  2389         ].
  2389 	].
  2390     ].
  2390     ].
  2391 !
  2391 !
  2392 
  2392 
  2393 shutDown
  2393 shutDown
  2394     "close the stream - added for protocol compatibility with Socket.
  2394     "close the stream - added for protocol compatibility with Socket.
  2408     |copy|
  2408     |copy|
  2409 
  2409 
  2410     copy := super copy.
  2410     copy := super copy.
  2411     copy dupFd.
  2411     copy dupFd.
  2412     self isPositionable ifTrue:[
  2412     self isPositionable ifTrue:[
  2413         copy position:position.
  2413 	copy position:position.
  2414     ].
  2414     ].
  2415     copy registerForFinalization.
  2415     copy registerForFinalization.
  2416     ^ copy
  2416     ^ copy
  2417 
  2417 
  2418     "
  2418     "
  2456     "{ Pragma: +optSpace }"
  2456     "{ Pragma: +optSpace }"
  2457 
  2457 
  2458     "report an error, that the stream is already opened"
  2458     "report an error, that the stream is already opened"
  2459 
  2459 
  2460     ^ OpenError
  2460     ^ OpenError
  2461         raiseRequestWith:self
  2461 	raiseRequestWith:self
  2462         errorString:' - stream is already open'
  2462 	errorString:' - stream is already open'
  2463 
  2463 
  2464     "
  2464     "
  2465       self new errorAlreadyOpen
  2465       self new errorAlreadyOpen
  2466     "
  2466     "
  2467 
  2467 
  2472     "{ Pragma: +optSpace }"
  2472     "{ Pragma: +optSpace }"
  2473 
  2473 
  2474     "report an error, that the stream is in binary mode"
  2474     "report an error, that the stream is in binary mode"
  2475 
  2475 
  2476     ^ InvalidModeError
  2476     ^ InvalidModeError
  2477         raiseRequestWith:self
  2477 	raiseRequestWith:self
  2478         errorString:(self class name , ' is in binary mode')
  2478 	errorString:(self class name , ' is in binary mode')
  2479         "/ in:thisContext sender
  2479 	"/ in:thisContext sender
  2480 
  2480 
  2481     "Modified: / 8.5.1999 / 20:12:43 / cg"
  2481     "Modified: / 8.5.1999 / 20:12:43 / cg"
  2482 !
  2482 !
  2483 
  2483 
  2484 errorNotBinary
  2484 errorNotBinary
  2485     "{ Pragma: +optSpace }"
  2485     "{ Pragma: +optSpace }"
  2486 
  2486 
  2487     "report an error, that the stream is not in binary mode"
  2487     "report an error, that the stream is not in binary mode"
  2488 
  2488 
  2489     ^ InvalidModeError
  2489     ^ InvalidModeError
  2490         raiseRequestWith:self
  2490 	raiseRequestWith:self
  2491         errorString:(self class name , ' is not in binary mode')
  2491 	errorString:(self class name , ' is not in binary mode')
  2492         "/ in:thisContext sender
  2492 	"/ in:thisContext sender
  2493 
  2493 
  2494     "Modified: / 8.5.1999 / 20:12:40 / cg"
  2494     "Modified: / 8.5.1999 / 20:12:40 / cg"
  2495 !
  2495 !
  2496 
  2496 
  2497 errorNotBuffered
  2497 errorNotBuffered
  2498     "{ Pragma: +optSpace }"
  2498     "{ Pragma: +optSpace }"
  2499 
  2499 
  2500     "report an error, that the stream is not in buffered mode"
  2500     "report an error, that the stream is not in buffered mode"
  2501 
  2501 
  2502     ^ StreamError
  2502     ^ StreamError
  2503         raiseRequestWith:self
  2503 	raiseRequestWith:self
  2504         errorString:(self class name , ' is unbuffered - operation not allowed')
  2504 	errorString:(self class name , ' is unbuffered - operation not allowed')
  2505         "/ in:thisContext sender
  2505 	"/ in:thisContext sender
  2506 
  2506 
  2507     "Modified: / 8.5.1999 / 20:12:36 / cg"
  2507     "Modified: / 8.5.1999 / 20:12:36 / cg"
  2508 !
  2508 !
  2509 
  2509 
  2510 errorReadOnly
  2510 errorReadOnly
  2561      which is no longer available and has been mounted soft)"
  2561      which is no longer available and has been mounted soft)"
  2562 
  2562 
  2563     "{ Pragma: +optSpace }"
  2563     "{ Pragma: +optSpace }"
  2564 
  2564 
  2565     ^ StreamIOError newException
  2565     ^ StreamIOError newException
  2566         errorCode:errorNumber;
  2566 	errorCode:errorNumber;
  2567         osErrorHolder:(OperatingSystem errorHolderForNumber:errorNumber);
  2567 	osErrorHolder:(OperatingSystem errorHolderForNumber:errorNumber);
  2568         parameter:self;
  2568 	parameter:self;
  2569         raiseRequest
  2569 	raiseRequest
  2570 
  2570 
  2571     "Modified: / 8.5.1999 / 20:12:16 / cg"
  2571     "Modified: / 8.5.1999 / 20:12:16 / cg"
  2572 !
  2572 !
  2573 
  2573 
  2574 lastErrorNumber
  2574 lastErrorNumber
  2579 
  2579 
  2580 lastErrorString
  2580 lastErrorString
  2581     "return a message string describing the last error"
  2581     "return a message string describing the last error"
  2582 
  2582 
  2583     (lastErrorNumber isNil or:[lastErrorNumber == 0]) ifTrue:[
  2583     (lastErrorNumber isNil or:[lastErrorNumber == 0]) ifTrue:[
  2584         ^ 'I/O error'
  2584 	^ 'I/O error'
  2585     ].
  2585     ].
  2586     ^ OperatingSystem errorTextForNumber:lastErrorNumber
  2586     ^ OperatingSystem errorTextForNumber:lastErrorNumber
  2587 !
  2587 !
  2588 
  2588 
  2589 lastErrorSymbol
  2589 lastErrorSymbol
  2608     |exClass errorHolder|
  2608     |exClass errorHolder|
  2609 
  2609 
  2610     errorHolder := OperatingSystem errorHolderForNumber:errorNumber.
  2610     errorHolder := OperatingSystem errorHolderForNumber:errorNumber.
  2611 
  2611 
  2612     exClass := (errorHolder errorCategory == #nonexistentSignal)
  2612     exClass := (errorHolder errorCategory == #nonexistentSignal)
  2613         ifTrue:[ FileDoesNotExistException ]
  2613 	ifTrue:[ FileDoesNotExistException ]
  2614         ifFalse:[ OpenError ].
  2614 	ifFalse:[ OpenError ].
  2615 
  2615 
  2616     ^ exClass newException
  2616     ^ exClass newException
  2617         errorCode:errorNumber;
  2617 	errorCode:errorNumber;
  2618         osErrorHolder:errorHolder;
  2618 	osErrorHolder:errorHolder;
  2619         "/ cg: initialized lazily - see OpenError>>#description
  2619 	"/ cg: initialized lazily - see OpenError>>#description
  2620         "/ errorString:(' : ' , errorHolder errorString);
  2620 	"/ errorString:(' : ' , errorHolder errorString);
  2621         parameter:self;
  2621 	parameter:self;
  2622         raiseRequest
  2622 	raiseRequest
  2623         "/ in:thisContext sender
  2623 	"/ in:thisContext sender
  2624 
  2624 
  2625     "Modified: / 09-09-2011 / 07:22:49 / cg"
  2625     "Modified: / 09-09-2011 / 07:22:49 / cg"
  2626 !
  2626 !
  2627 
  2627 
  2628 readError
  2628 readError
  2637     "report an error, that some read error occurred"
  2637     "report an error, that some read error occurred"
  2638 
  2638 
  2639     "{ Pragma: +optSpace }"
  2639     "{ Pragma: +optSpace }"
  2640 
  2640 
  2641     ^ ReadError newException
  2641     ^ ReadError newException
  2642         errorCode:errorNumber;
  2642 	errorCode:errorNumber;
  2643         osErrorHolder:(OperatingSystem errorHolderForNumber:errorNumber);
  2643 	osErrorHolder:(OperatingSystem errorHolderForNumber:errorNumber);
  2644         parameter:self;
  2644 	parameter:self;
  2645         raiseRequest
  2645 	raiseRequest
  2646 !
  2646 !
  2647 
  2647 
  2648 writeError
  2648 writeError
  2649     "report an error, that some write error occurred"
  2649     "report an error, that some write error occurred"
  2650 
  2650 
  2657     "report an error, that some write error occurred"
  2657     "report an error, that some write error occurred"
  2658 
  2658 
  2659     "{ Pragma: +optSpace }"
  2659     "{ Pragma: +optSpace }"
  2660 
  2660 
  2661     ^ WriteError newException
  2661     ^ WriteError newException
  2662         errorCode:errorNumber;
  2662 	errorCode:errorNumber;
  2663         osErrorHolder:(OperatingSystem errorHolderForNumber:errorNumber);
  2663 	osErrorHolder:(OperatingSystem errorHolderForNumber:errorNumber);
  2664         parameter:self;
  2664 	parameter:self;
  2665         raiseRequest
  2665 	raiseRequest
  2666 ! !
  2666 ! !
  2667 
  2667 
  2668 !ExternalStream methodsFor:'finalization'!
  2668 !ExternalStream methodsFor:'finalization'!
  2669 
  2669 
  2670 beExecutor
  2670 beExecutor
  2680     "return a copy for finalization-registration;
  2680     "return a copy for finalization-registration;
  2681      since all we need at finalization time is the fileDescriptor,
  2681      since all we need at finalization time is the fileDescriptor,
  2682      a cheaper copy is possible."
  2682      a cheaper copy is possible."
  2683 
  2683 
  2684     ^ self class basicNew
  2684     ^ self class basicNew
  2685                     beExecutor;
  2685 		    beExecutor;
  2686                     setAccessor:handleType to:handle;
  2686 		    setAccessor:handleType to:handle;
  2687                     yourself.
  2687 		    yourself.
  2688 
  2688 
  2689     "Modified: / 23-04-2018 / 18:34:38 / stefan"
  2689     "Modified: / 23-04-2018 / 18:34:38 / stefan"
  2690 !
  2690 !
  2691 
  2691 
  2692 finalize
  2692 finalize
  2701 
  2701 
  2702 registerForFinalization
  2702 registerForFinalization
  2703 
  2703 
  2704     "keep myself in newSpace, so it will be finalized early"
  2704     "keep myself in newSpace, so it will be finalized early"
  2705     Lobby size < MaxNonTenurableExecutors ifTrue:[
  2705     Lobby size < MaxNonTenurableExecutors ifTrue:[
  2706         ObjectMemory preventTenureOf:self.
  2706 	ObjectMemory preventTenureOf:self.
  2707     ].
  2707     ].
  2708     Lobby register:self.
  2708     Lobby register:self.
  2709 !
  2709 !
  2710 
  2710 
  2711 unregisterForFinalization
  2711 unregisterForFinalization
  2755     if ((__INST(handleType) == nil)
  2755     if ((__INST(handleType) == nil)
  2756      || (__INST(handleType) == @symbol(filePointer))
  2756      || (__INST(handleType) == @symbol(filePointer))
  2757      || (__INST(handleType) == @symbol(socketFilePointer))
  2757      || (__INST(handleType) == @symbol(socketFilePointer))
  2758      || (__INST(handleType) == @symbol(socketHandle))
  2758      || (__INST(handleType) == @symbol(socketHandle))
  2759      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2759      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2760         if (((fp = __INST(handle)) != nil)
  2760 	if (((fp = __INST(handle)) != nil)
  2761             && (__INST(mode) != @symbol(writeonly))
  2761 	    && (__INST(mode) != @symbol(writeonly))
  2762             && (__INST(binary) != true)
  2762 	    && (__INST(binary) != true)
  2763         ) {
  2763 	) {
  2764             f = __FILEVal(fp);
  2764 	    f = __FILEVal(fp);
  2765             buffer[0] = '\0';
  2765 	    buffer[0] = '\0';
  2766 
  2766 
  2767             _buffered = (__INST(buffered) == true);
  2767 	    _buffered = (__INST(buffered) == true);
  2768             if (_buffered) {
  2768 	    if (_buffered) {
  2769                 __READING__(f);
  2769 		__READING__(f);
  2770             }
  2770 	    }
  2771 
  2771 
  2772             rslt = nextPtr = buffer;
  2772 	    rslt = nextPtr = buffer;
  2773             limit = buffer + sizeof(buffer) - 2;
  2773 	    limit = buffer + sizeof(buffer) - 2;
  2774 
  2774 
  2775             for (;;) {
  2775 	    for (;;) {
  2776                 __READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType));
  2776 		__READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType));
  2777                 if (ret <= 0) {
  2777 		if (ret <= 0) {
  2778                     if (nextPtr == buffer)
  2778 		    if (nextPtr == buffer)
  2779                         rslt = NULL;
  2779 			rslt = NULL;
  2780                     if (ret == 0) {
  2780 		    if (ret == 0) {
  2781                         __INST(hitEOF) = true;
  2781 			__INST(hitEOF) = true;
  2782                         break;
  2782 			break;
  2783                     } else {
  2783 		    } else {
  2784                         error = __mkSmallInteger(__threadErrno);
  2784 			error = __mkSmallInteger(__threadErrno);
  2785                         goto err;
  2785 			goto err;
  2786                     }
  2786 		    }
  2787                 }
  2787 		}
  2788 
  2788 
  2789                 if (*nextPtr == '\n') {
  2789 		if (*nextPtr == '\n') {
  2790                     cutOff = 1;
  2790 		    cutOff = 1;
  2791                     *nextPtr = '\0';
  2791 		    *nextPtr = '\0';
  2792                     break;
  2792 		    break;
  2793                 }
  2793 		}
  2794                 if (*nextPtr == '\r') {
  2794 		if (*nextPtr == '\r') {
  2795                     char peekChar;
  2795 		    char peekChar;
  2796 
  2796 
  2797                     /*
  2797 		    /*
  2798                      * peek ahead for a newLine ...
  2798 		     * peek ahead for a newLine ...
  2799                      */
  2799 		     */
  2800                     __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType));
  2800 		    __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType));
  2801                     if (ret <= 0) {
  2801 		    if (ret <= 0) {
  2802                         cutOff = 1;
  2802 			cutOff = 1;
  2803                         *nextPtr = '\0';
  2803 			*nextPtr = '\0';
  2804                         if (ret == 0) {
  2804 			if (ret == 0) {
  2805                             __INST(hitEOF) = true;
  2805 			    __INST(hitEOF) = true;
  2806                             break;
  2806 			    break;
  2807                         }
  2807 			}
  2808                         error = __mkSmallInteger(__threadErrno);
  2808 			error = __mkSmallInteger(__threadErrno);
  2809                         goto err;
  2809 			goto err;
  2810                     }
  2810 		    }
  2811 
  2811 
  2812                     if (peekChar == '\n') {
  2812 		    if (peekChar == '\n') {
  2813                         cutOff = 2;
  2813 			cutOff = 2;
  2814                         *nextPtr = '\0';
  2814 			*nextPtr = '\0';
  2815                         break;
  2815 			break;
  2816                     }
  2816 		    }
  2817 
  2817 
  2818                     __UNGETC__(peekChar, f, _buffered);
  2818 		    __UNGETC__(peekChar, f, _buffered);
  2819 
  2819 
  2820                     cutOff = 1;
  2820 		    cutOff = 1;
  2821                     *nextPtr = '\0';
  2821 		    *nextPtr = '\0';
  2822                     break;
  2822 		    break;
  2823                 }
  2823 		}
  2824 
  2824 
  2825                 nextPtr++;
  2825 		nextPtr++;
  2826                 if (nextPtr >= limit) {
  2826 		if (nextPtr >= limit) {
  2827                     *nextPtr = '\0';
  2827 		    *nextPtr = '\0';
  2828                     lineTooLong = 1;
  2828 		    lineTooLong = 1;
  2829                     // signalled below anyway; so no need to print on stderr
  2829 		    break;
  2830 #if 0
  2830 		}
  2831                     if (@global(InfoPrinting) == true) {
  2831 	    }
  2832                         fprintf(stderr, "ExtStream [warning]: line truncated in nextLine\n");
  2832 
  2833                     }
  2833 	    if (rslt != NULL) {
  2834 #endif
  2834 		len = nextPtr-buffer;
  2835                     break;
  2835 
  2836                 }
  2836 		if (__isSmallInteger(__INST(position))) {
  2837             }
  2837 		    INT np = __intVal(__INST(position)) + len + cutOff;
  2838 
  2838 		    OBJ t;
  2839             if (rslt != NULL) {
  2839 
  2840                 len = nextPtr-buffer;
  2840 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  2841 
  2841 		} else {
  2842                 if (__isSmallInteger(__INST(position))) {
  2842 		    __INST(position) = nil; /* i.e. do not know */
  2843                     INT np = __intVal(__INST(position)) + len + cutOff;
  2843 		}
  2844                     OBJ t;
  2844 		/* remove any EOL character */
  2845 
  2845 		if (len != 0) {
  2846                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  2846 		    if (buffer[len-1] == '\n') {
  2847                 } else {
  2847 			buffer[--len] = '\0';
  2848                     __INST(position) = nil; /* i.e. do not know */
  2848 		    }
  2849                 }
  2849 		    if ((len != 0) && (buffer[len-1] == '\r')) {
  2850                 /* remove any EOL character */
  2850 			buffer[--len] = '\0';
  2851                 if (len != 0) {
  2851 		    }
  2852                     if (buffer[len-1] == '\n') {
  2852 		}
  2853                         buffer[--len] = '\0';
  2853 		line = __MKSTRING_L(buffer, len);
  2854                     }
  2854 		if (! lineTooLong) {
  2855                     if ((len != 0) && (buffer[len-1] == '\r')) {
  2855 		    RETURN ( line );
  2856                         buffer[--len] = '\0';
  2856 		}
  2857                     }
  2857 	    }
  2858                 }
  2858 	}
  2859                 line = __MKSTRING_L(buffer, len);
       
  2860                 if (! lineTooLong) {
       
  2861                     RETURN ( line );
       
  2862                 }
       
  2863             }
       
  2864         }
       
  2865     }
  2859     }
  2866 err: ;
  2860 err: ;
  2867 %}.
  2861 %}.
  2868     line notNil ifTrue:[
  2862     line notNil ifTrue:[
  2869         "/ the line as read is longer than 32k characters (boy - what a line)
  2863 	"/ the line as read is longer than 32k characters (boy - what a line)
  2870         "/ The exception could be handled by reading more and returning the
  2864 	"/ The exception raised below can be handled to ask the user
  2871         "/ concatenation in your exception handler (the receiver and the partial
  2865 	"/ and to read more and return the concatenation from the exception handler
  2872         "/ line are passed as parameter)
  2866 	"/ (the receiver and the partial line are passed as parameter)
  2873 
  2867 	"/ If unhandled, we do exactly that: read the rest and return the concatenation
  2874         LineTooLongErrorSignal isHandled ifTrue:[
  2868 	"/ i.e. the full line - whatever its size is.
  2875             ^ LineTooLongErrorSignal
  2869 
  2876                 raiseRequestWith:(Array with:self with:line)
  2870 	LineTooLongErrorSignal isHandled ifTrue:[
  2877                      errorString:('line too long read error')
  2871 	    ^ LineTooLongErrorSignal
  2878         ].
  2872 		raiseRequestWith:(Array with:self with:line)
  2879         'ExternalStream [warning]: line truncated in nextLine' infoPrintCR.
  2873 		     errorString:('line too long read error')
  2880         ^ line , self nextLine
  2874 	].
       
  2875 	'ExternalStream [info]: very long line in nextLine' infoPrintCR.
       
  2876 	^ line , self nextLine
  2881     ].
  2877     ].
  2882 
  2878 
  2883     hitEOF ifTrue:[^ self pastEndRead].
  2879     hitEOF ifTrue:[^ self pastEndRead].
  2884     error notNil ifTrue:[
  2880     error notNil ifTrue:[
  2885         lastErrorNumber := error.
  2881 	lastErrorNumber := error.
  2886         ^ self readError:error
  2882 	^ self readError:error
  2887     ].
  2883     ].
  2888     handle isNil ifTrue:[^ self errorNotOpen].
  2884     handle isNil ifTrue:[^ self errorNotOpen].
  2889     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  2885     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  2890     binary ifTrue:[^ self errorBinary].
  2886     binary ifTrue:[^ self errorBinary].
  2891     ^ super nextLine
  2887     ^ super nextLine
  2903     if ((__INST(handleType) == nil)
  2899     if ((__INST(handleType) == nil)
  2904      || (__INST(handleType) == @symbol(filePointer))
  2900      || (__INST(handleType) == @symbol(filePointer))
  2905      || (__INST(handleType) == @symbol(socketFilePointer))
  2901      || (__INST(handleType) == @symbol(socketFilePointer))
  2906      || (__INST(handleType) == @symbol(socketHandle))
  2902      || (__INST(handleType) == @symbol(socketHandle))
  2907      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2903      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2908         if (((fp = __INST(handle)) != nil)
  2904 	if (((fp = __INST(handle)) != nil)
  2909             && (__INST(mode) != @symbol(readonly))
  2905 	    && (__INST(mode) != @symbol(readonly))
  2910             && (__INST(binary) != true)
  2906 	    && (__INST(binary) != true)
  2911             && __isStringLike(aString)
  2907 	    && __isStringLike(aString)
  2912         ) {
  2908 	) {
  2913             int _buffered = (__INST(buffered) == true);
  2909 	    int _buffered = (__INST(buffered) == true);
  2914             int len = __stringSize(aString);
  2910 	    int len = __stringSize(aString);
  2915             int cnt, len1;
  2911 	    int cnt, len1;
  2916             FILEPOINTER f = __FILEVal(fp);
  2912 	    FILEPOINTER f = __FILEVal(fp);
  2917             char *cp;
  2913 	    char *cp;
  2918             int o_offs;
  2914 	    int o_offs;
  2919 
  2915 
  2920             if (_buffered) {
  2916 	    if (_buffered) {
  2921                 __WRITING__(f)
  2917 		__WRITING__(f)
  2922             }
  2918 	    }
  2923 #ifdef __win32__
  2919 #ifdef __win32__
  2924             if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  2920 	    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  2925                 cnt = __win32_fwrite(__stringVal(aString), 1, len, f);
  2921 		cnt = __win32_fwrite(__stringVal(aString), 1, len, f);
  2926             } else
  2922 	    } else
  2927 #endif
  2923 #endif
  2928             {
  2924 	    {
  2929                 o_offs = (char *)__stringVal(aString)-(char *)aString;
  2925 		o_offs = (char *)__stringVal(aString)-(char *)aString;
  2930                 __WRITEBYTES_OBJ__(cnt, f, aString, o_offs, len, _buffered, __INST(handleType));
  2926 		__WRITEBYTES_OBJ__(cnt, f, aString, o_offs, len, _buffered, __INST(handleType));
  2931             }
  2927 	    }
  2932             if (cnt == len) {
  2928 	    if (cnt == len) {
  2933                 OBJ mode = __INST(eolMode);
  2929 		OBJ mode = __INST(eolMode);
  2934 
  2930 
  2935                 len1 = len;
  2931 		len1 = len;
  2936 
  2932 
  2937                 if (mode == @symbol(cr)) {
  2933 		if (mode == @symbol(cr)) {
  2938                     cp = "\r"; len = 1;
  2934 		    cp = "\r"; len = 1;
  2939                 } else if (mode == @symbol(crlf)) {
  2935 		} else if (mode == @symbol(crlf)) {
  2940                     cp = "\r\n"; len = 2;
  2936 		    cp = "\r\n"; len = 2;
  2941                 } else if (mode == @symbol(eot)) {
  2937 		} else if (mode == @symbol(eot)) {
  2942                     cp = "\004"; len = 1;
  2938 		    cp = "\004"; len = 1;
  2943                 } else if (mode == @symbol(etx)) {
  2939 		} else if (mode == @symbol(etx)) {
  2944                     cp = "\003"; len = 1;
  2940 		    cp = "\003"; len = 1;
  2945                 } else {
  2941 		} else {
  2946                     cp = "\n"; len = 1;
  2942 		    cp = "\n"; len = 1;
  2947                 }
  2943 		}
  2948 #ifdef __win32__
  2944 #ifdef __win32__
  2949                 if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  2945 		if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  2950                     cnt = __win32_fwrite(cp, 1, len, f);
  2946 		    cnt = __win32_fwrite(cp, 1, len, f);
  2951                 } else
  2947 		} else
  2952 #endif
  2948 #endif
  2953                 {
  2949 		{
  2954                     __WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType));
  2950 		    __WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType));
  2955                 }
  2951 		}
  2956                 if (cnt > 0) {
  2952 		if (cnt > 0) {
  2957                     if (__isSmallInteger(__INST(position))) {
  2953 		    if (__isSmallInteger(__INST(position))) {
  2958                         INT np = __intVal(__INST(position)) + len1 + cnt;
  2954 			INT np = __intVal(__INST(position)) + len1 + cnt;
  2959                         OBJ t;
  2955 			OBJ t;
  2960 
  2956 
  2961                         t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  2957 			t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  2962                     } else {
  2958 		    } else {
  2963                         __INST(position) = nil; /* i.e. do not know */
  2959 			__INST(position) = nil; /* i.e. do not know */
  2964                     }
  2960 		    }
  2965                     RETURN ( self );
  2961 		    RETURN ( self );
  2966                 }
  2962 		}
  2967             }
  2963 	    }
  2968             error = __mkSmallInteger(__threadErrno);
  2964 	    error = __mkSmallInteger(__threadErrno);
  2969         }
  2965 	}
  2970     }
  2966     }
  2971 %}.
  2967 %}.
  2972     error notNil ifTrue:[
  2968     error notNil ifTrue:[
  2973         lastErrorNumber := error.
  2969 	lastErrorNumber := error.
  2974         self writeError:error.
  2970 	self writeError:error.
  2975         ^ self
  2971 	^ self
  2976     ].
  2972     ].
  2977     super nextPutLine:aString.
  2973     super nextPutLine:aString.
  2978 !
  2974 !
  2979 
  2975 
  2980 nextPutLinesFrom:aStream upToLineStartingWith:aStringOrNil
  2976 nextPutLinesFrom:aStream upToLineStartingWith:aStringOrNil
  2985      If aStringOrNil is nil or not matched, copy proceeds to the end."
  2981      If aStringOrNil is nil or not matched, copy proceeds to the end."
  2986 
  2982 
  2987     |line|
  2983     |line|
  2988 
  2984 
  2989     [aStream atEnd] whileFalse:[
  2985     [aStream atEnd] whileFalse:[
  2990         line := aStream nextLine.
  2986 	line := aStream nextLine.
  2991         line isNil ifTrue:[
  2987 	line isNil ifTrue:[
  2992             ^ self.
  2988 	    ^ self.
  2993         ].
  2989 	].
  2994         self nextPutLine:line.
  2990 	self nextPutLine:line.
  2995         (aStringOrNil notNil and:[line startsWith:aStringOrNil]) ifTrue:[
  2991 	(aStringOrNil notNil and:[line startsWith:aStringOrNil]) ifTrue:[
  2996             ^ self
  2992 	    ^ self
  2997         ]
  2993 	]
  2998     ].
  2994     ].
  2999 !
  2995 !
  3000 
  2996 
  3001 peekForLineStartingWith:aString
  2997 peekForLineStartingWith:aString
  3002     "read ahead for next line starting with aString;
  2998     "read ahead for next line starting with aString;
  3012     binary ifTrue:[^ self errorBinary].
  3008     binary ifTrue:[^ self errorBinary].
  3013     buffered ifFalse:[^ self errorNotBuffered].
  3009     buffered ifFalse:[^ self errorNotBuffered].
  3014 
  3010 
  3015     firstPos := self position.
  3011     firstPos := self position.
  3016     [self atEnd] whileFalse:[
  3012     [self atEnd] whileFalse:[
  3017         lastPos := self position.
  3013 	lastPos := self position.
  3018         line := self nextLine.
  3014 	line := self nextLine.
  3019         line isNil ifTrue:[
  3015 	line isNil ifTrue:[
  3020             self position:firstPos.
  3016 	    self position:firstPos.
  3021             ^ nil
  3017 	    ^ nil
  3022         ].
  3018 	].
  3023         (line startsWith:aString) ifTrue:[
  3019 	(line startsWith:aString) ifTrue:[
  3024             self position:lastPos.
  3020 	    self position:lastPos.
  3025             ^ line
  3021 	    ^ line
  3026         ]
  3022 	]
  3027     ].
  3023     ].
  3028     self position:firstPos.
  3024     self position:firstPos.
  3029     ^ nil
  3025     ^ nil
  3030 !
  3026 !
  3031 
  3027 
  3041     handle isNil ifTrue:[^ self errorNotOpen].
  3037     handle isNil ifTrue:[^ self errorNotOpen].
  3042     binary ifTrue:[^ self errorBinary].
  3038     binary ifTrue:[^ self errorBinary].
  3043 
  3039 
  3044     startPos := self position.
  3040     startPos := self position.
  3045     [self atEnd] whileFalse:[
  3041     [self atEnd] whileFalse:[
  3046         linePos := self position.
  3042 	linePos := self position.
  3047         line := self nextLine.
  3043 	line := self nextLine.
  3048         line notNil ifTrue:[
  3044 	line notNil ifTrue:[
  3049             index := 1.
  3045 	    index := 1.
  3050             aCollectionOfStrings do:[:prefix |
  3046 	    aCollectionOfStrings do:[:prefix |
  3051                 (line startsWith:prefix) ifTrue:[
  3047 		(line startsWith:prefix) ifTrue:[
  3052                     self position:linePos.
  3048 		    self position:linePos.
  3053                     ^ index
  3049 		    ^ index
  3054                 ].
  3050 		].
  3055                 index := index + 1
  3051 		index := index + 1
  3056             ]
  3052 	    ]
  3057         ]
  3053 	]
  3058     ].
  3054     ].
  3059     self position:startPos.
  3055     self position:startPos.
  3060     ^ nil
  3056     ^ nil
  3061 ! !
  3057 ! !
  3062 
  3058 
  3065 async:aBoolean
  3061 async:aBoolean
  3066     "set/clear the async attribute - if set, the availability of data on
  3062     "set/clear the async attribute - if set, the availability of data on
  3067      the receiver will trigger an ioInterrupt.
  3063      the receiver will trigger an ioInterrupt.
  3068      If cleared (which is the default) no special notification is made.
  3064      If cleared (which is the default) no special notification is made.
  3069      Notice:
  3065      Notice:
  3070         not every OS supports this
  3066 	not every OS supports this
  3071         - check with OS>>supportsIOInterrupts before using"
  3067 	- check with OS>>supportsIOInterrupts before using"
  3072 
  3068 
  3073     |fd|
  3069     |fd|
  3074 
  3070 
  3075     OperatingSystem supportsIOInterrupts ifFalse:[
  3071     OperatingSystem supportsIOInterrupts ifFalse:[
  3076         ^ self errorUnsupportedOperation
  3072 	^ self errorUnsupportedOperation
  3077     ].
  3073     ].
  3078 
  3074 
  3079     fd := self fileDescriptor.
  3075     fd := self fileDescriptor.
  3080     "self fileDescriptor may set handle to nil"
  3076     "self fileDescriptor may set handle to nil"
  3081     handle isNil ifTrue:[^ self errorNotOpen].
  3077     handle isNil ifTrue:[^ self errorNotOpen].
  3082 
  3078 
  3083     aBoolean ifTrue:[
  3079     aBoolean ifTrue:[
  3084         ^ OperatingSystem enableIOInterruptsOn:fd
  3080 	^ OperatingSystem enableIOInterruptsOn:fd
  3085     ].
  3081     ].
  3086     ^ OperatingSystem disableIOInterruptsOn:fd
  3082     ^ OperatingSystem disableIOInterruptsOn:fd
  3087 
  3083 
  3088     "Modified: 11.1.1997 / 17:50:21 / cg"
  3084     "Modified: 11.1.1997 / 17:50:21 / cg"
  3089 !
  3085 !
  3175     unsigned int ioNum;
  3171     unsigned int ioNum;
  3176     INT ioArg;
  3172     INT ioArg;
  3177     OBJ fp = __INST(handle);
  3173     OBJ fp = __INST(handle);
  3178 
  3174 
  3179     if (fp == nil)
  3175     if (fp == nil)
  3180         goto out;
  3176 	goto out;
  3181 
  3177 
  3182     if (!__isInteger(ioctlNumber)
  3178     if (!__isInteger(ioctlNumber)
  3183          || (!__isInteger(arg)
  3179 	 || (!__isInteger(arg)
  3184              && (arg != nil)
  3180 	     && (arg != nil)
  3185              && !__isBytes(arg)
  3181 	     && !__isBytes(arg)
  3186              && !__isExternalBytesLike(arg)
  3182 	     && !__isExternalBytesLike(arg)
  3187              && !__isExternalAddress(arg))) {
  3183 	     && !__isExternalAddress(arg))) {
  3188         error = @symbol(badArgument);
  3184 	error = @symbol(badArgument);
  3189         goto out;
  3185 	goto out;
  3190     }
  3186     }
  3191 
  3187 
  3192     if (__INST(handleType) == @symbol(socketHandle)) {
  3188     if (__INST(handleType) == @symbol(socketHandle)) {
  3193         fd = (int)((SOCKET)(__FILEVal(fp)));
  3189 	fd = (int)((SOCKET)(__FILEVal(fp)));
  3194     } else
  3190     } else
  3195         if ((__INST(handleType) == nil)
  3191 	if ((__INST(handleType) == nil)
  3196          || (__INST(handleType) == @symbol(filePointer))
  3192 	 || (__INST(handleType) == @symbol(filePointer))
  3197          || (__INST(handleType) == @symbol(socketFilePointer))
  3193 	 || (__INST(handleType) == @symbol(socketFilePointer))
  3198          || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3194 	 || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3199         fd = fileno(__FILEVal(fp));
  3195 	fd = fileno(__FILEVal(fp));
  3200     } else {
  3196     } else {
  3201         error = @symbol(badHandleType);
  3197 	error = @symbol(badHandleType);
  3202         goto out;
  3198 	goto out;
  3203     }
  3199     }
  3204 
  3200 
  3205     ioNum = __unsignedLongIntVal(ioctlNumber);
  3201     ioNum = __unsignedLongIntVal(ioctlNumber);
  3206 
  3202 
  3207     __BEGIN_INTERRUPTABLE__
  3203     __BEGIN_INTERRUPTABLE__
  3208     do {
  3204     do {
  3209         __threadErrno = 0;
  3205 	__threadErrno = 0;
  3210         if (arg == nil) {
  3206 	if (arg == nil) {
  3211             ioArg = 0;
  3207 	    ioArg = 0;
  3212         } else if (__isSmallInteger(arg)) {
  3208 	} else if (__isSmallInteger(arg)) {
  3213             ioArg = __intVal(arg);
  3209 	    ioArg = __intVal(arg);
  3214         } else if (__isInteger(arg)) {
  3210 	} else if (__isInteger(arg)) {
  3215             ioArg = __unsignedLongIntVal(arg);
  3211 	    ioArg = __unsignedLongIntVal(arg);
  3216         } else if (__isExternalBytesLike(arg)) {
  3212 	} else if (__isExternalBytesLike(arg)) {
  3217             ioArg = (INT)(__externalBytesAddress(arg));
  3213 	    ioArg = (INT)(__externalBytesAddress(arg));
  3218         } else if (__isExternalAddress(arg)) {
  3214 	} else if (__isExternalAddress(arg)) {
  3219             ioArg = (INT)(__externalAddressVal(arg));
  3215 	    ioArg = (INT)(__externalAddressVal(arg));
  3220         } else {
  3216 	} else {
  3221             ioArg = (INT)(__ByteArrayInstPtr(arg)->ba_element);
  3217 	    ioArg = (INT)(__ByteArrayInstPtr(arg)->ba_element);
  3222         }
  3218 	}
  3223         ret = ioctl(fd, ioNum, ioArg);
  3219 	ret = ioctl(fd, ioNum, ioArg);
  3224     } while (ret < 0 && __threadErrno == EINTR);
  3220     } while (ret < 0 && __threadErrno == EINTR);
  3225     __END_INTERRUPTABLE__
  3221     __END_INTERRUPTABLE__
  3226 
  3222 
  3227     if (ret >= 0) {
  3223     if (ret >= 0) {
  3228         RETURN ( __mkSmallInteger(ret) );
  3224 	RETURN ( __mkSmallInteger(ret) );
  3229     }
  3225     }
  3230     error = __mkSmallInteger(__threadErrno);
  3226     error = __mkSmallInteger(__threadErrno);
  3231 #endif
  3227 #endif
  3232 
  3228 
  3233 out:;
  3229 out:;
  3234 %}.
  3230 %}.
  3235     error notNil ifTrue:[
  3231     error notNil ifTrue:[
  3236         lastErrorNumber := error.
  3232 	lastErrorNumber := error.
  3237         ^ self ioError:error.
  3233 	^ self ioError:error.
  3238     ].
  3234     ].
  3239     handle isNil ifTrue:[^ self errorNotOpen].
  3235     handle isNil ifTrue:[^ self errorNotOpen].
  3240 
  3236 
  3241     "/ the system does not support ioctl (MSDOS or VMS)
  3237     "/ the system does not support ioctl (MSDOS or VMS)
  3242     ^ self errorUnsupportedOperation
  3238     ^ self errorUnsupportedOperation
  3266     int fd;
  3262     int fd;
  3267     int ret;
  3263     int ret;
  3268     OBJ fp = __INST(handle);
  3264     OBJ fp = __INST(handle);
  3269 
  3265 
  3270     if (fp == nil)
  3266     if (fp == nil)
  3271         goto out;
  3267 	goto out;
  3272 
  3268 
  3273     if (__INST(handleType) == @symbol(socketHandle)) {
  3269     if (__INST(handleType) == @symbol(socketHandle)) {
  3274         // syncing a socket to disk ?
  3270 	// syncing a socket to disk ?
  3275         error = @symbol(badHandleType);
  3271 	error = @symbol(badHandleType);
  3276         goto out;
  3272 	goto out;
  3277         // fd = __FILEVal(fp);
  3273 	// fd = __FILEVal(fp);
  3278     } else
  3274     } else
  3279         if ((__INST(handleType) == nil)
  3275 	if ((__INST(handleType) == nil)
  3280                || (__INST(handleType) == @symbol(filePointer))
  3276 	       || (__INST(handleType) == @symbol(filePointer))
  3281                || (__INST(handleType) == @symbol(socketFilePointer))
  3277 	       || (__INST(handleType) == @symbol(socketFilePointer))
  3282                || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3278 	       || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3283         fd = fileno(__FILEVal(fp));
  3279 	fd = fileno(__FILEVal(fp));
  3284     } else {
  3280     } else {
  3285         error = @symbol(badHandleType);
  3281 	error = @symbol(badHandleType);
  3286         goto out;
  3282 	goto out;
  3287     }
  3283     }
  3288 
  3284 
  3289 #ifdef __win32__
  3285 #ifdef __win32__
  3290      __threadErrno = 0;
  3286      __threadErrno = 0;
  3291      ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fd));
  3287      ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fd));
  3292      if (ret) {
  3288      if (ret) {
  3293          RETURN (self);
  3289 	 RETURN (self);
  3294      }
  3290      }
  3295 #else
  3291 #else
  3296      __BEGIN_INTERRUPTABLE__
  3292      __BEGIN_INTERRUPTABLE__
  3297      do {
  3293      do {
  3298          ret = fsync(fd);
  3294 	 ret = fsync(fd);
  3299      } while ((ret < 0) && (__threadErrno == EINTR));
  3295      } while ((ret < 0) && (__threadErrno == EINTR));
  3300      __END_INTERRUPTABLE__
  3296      __END_INTERRUPTABLE__
  3301 
  3297 
  3302      if (ret >= 0) {
  3298      if (ret >= 0) {
  3303          RETURN (self);
  3299 	 RETURN (self);
  3304      }
  3300      }
  3305 #endif /* ! __win32__ */
  3301 #endif /* ! __win32__ */
  3306      error = __mkSmallInteger(__threadErrno);
  3302      error = __mkSmallInteger(__threadErrno);
  3307 #endif /* ! __openVMS__ */
  3303 #endif /* ! __openVMS__ */
  3308 out:;
  3304 out:;
  3309 %}.
  3305 %}.
  3310     error notNil ifTrue:[
  3306     error notNil ifTrue:[
  3311         lastErrorNumber := error.
  3307 	lastErrorNumber := error.
  3312         self ioError:error.
  3308 	self ioError:error.
  3313         ^ self.
  3309 	^ self.
  3314     ].
  3310     ].
  3315     handle isNil ifTrue:[self errorNotOpen].
  3311     handle isNil ifTrue:[self errorNotOpen].
  3316 
  3312 
  3317     "
  3313     "
  3318         |f|
  3314 	|f|
  3319         f := 'x' asFilename writeStream.
  3315 	f := 'x' asFilename writeStream.
  3320         f nextPutAll:'hallo'; sync; syncData; close
  3316 	f nextPutAll:'hallo'; sync; syncData; close
  3321     "
  3317     "
  3322 !
  3318 !
  3323 
  3319 
  3324 syncData
  3320 syncData
  3325     "make sure, that the OS writes cached data to the disk.
  3321     "make sure, that the OS writes cached data to the disk.
  3335     int fd;
  3331     int fd;
  3336     int ret;
  3332     int ret;
  3337     OBJ fp = __INST(handle);
  3333     OBJ fp = __INST(handle);
  3338 
  3334 
  3339     if (fp == nil)
  3335     if (fp == nil)
  3340         goto out;
  3336 	goto out;
  3341 
  3337 
  3342     if (__INST(handleType) == @symbol(socketHandle)) {
  3338     if (__INST(handleType) == @symbol(socketHandle)) {
  3343         // syncing a socket to disk ?
  3339 	// syncing a socket to disk ?
  3344         error = @symbol(badHandleType);
  3340 	error = @symbol(badHandleType);
  3345         goto out;
  3341 	goto out;
  3346         // fd = __FILEVal(fp);
  3342 	// fd = __FILEVal(fp);
  3347     } else
  3343     } else
  3348         if ((__INST(handleType) == nil)
  3344 	if ((__INST(handleType) == nil)
  3349                || (__INST(handleType) == @symbol(filePointer))
  3345 	       || (__INST(handleType) == @symbol(filePointer))
  3350                || (__INST(handleType) == @symbol(socketFilePointer))
  3346 	       || (__INST(handleType) == @symbol(socketFilePointer))
  3351                || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3347 	       || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3352         fd = fileno(__FILEVal(fp));
  3348 	fd = fileno(__FILEVal(fp));
  3353     } else {
  3349     } else {
  3354         error = @symbol(badHandleType);
  3350 	error = @symbol(badHandleType);
  3355         goto out;
  3351 	goto out;
  3356     }
  3352     }
  3357 
  3353 
  3358 #ifdef __win32__
  3354 #ifdef __win32__
  3359      __threadErrno = 0;
  3355      __threadErrno = 0;
  3360      ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fd));
  3356      ret = __STX_API_NOINT_CALL1( "FlushFileBuffers", FlushFileBuffers, _get_osfhandle(fd));
  3361      if (ret) {
  3357      if (ret) {
  3362          RETURN (self);
  3358 	 RETURN (self);
  3363      }
  3359      }
  3364 #else
  3360 #else
  3365      __BEGIN_INTERRUPTABLE__
  3361      __BEGIN_INTERRUPTABLE__
  3366      do {
  3362      do {
  3367          ret = fdatasync(fd);
  3363 	 ret = fdatasync(fd);
  3368      } while ((ret < 0) && (__threadErrno == EINTR));
  3364      } while ((ret < 0) && (__threadErrno == EINTR));
  3369      __END_INTERRUPTABLE__
  3365      __END_INTERRUPTABLE__
  3370 
  3366 
  3371      if (ret >= 0) {
  3367      if (ret >= 0) {
  3372          RETURN (self);
  3368 	 RETURN (self);
  3373      }
  3369      }
  3374 #endif /* ! __win32__ */
  3370 #endif /* ! __win32__ */
  3375      error = __mkSmallInteger(__threadErrno);
  3371      error = __mkSmallInteger(__threadErrno);
  3376 #endif /* ! __openVMS__ */
  3372 #endif /* ! __openVMS__ */
  3377 out:;
  3373 out:;
  3378 %}.
  3374 %}.
  3379 
  3375 
  3380     error notNil ifTrue:[
  3376     error notNil ifTrue:[
  3381         lastErrorNumber := error.
  3377 	lastErrorNumber := error.
  3382         self ioError:error.
  3378 	self ioError:error.
  3383         ^ self.
  3379 	^ self.
  3384     ].
  3380     ].
  3385     handle isNil ifTrue:[^ self errorNotOpen].
  3381     handle isNil ifTrue:[^ self errorNotOpen].
  3386 
  3382 
  3387     "if notdef HAS_DATASYNC, fall back"
  3383     "if notdef HAS_DATASYNC, fall back"
  3388     self sync.
  3384     self sync.
  3389 
  3385 
  3390     "
  3386     "
  3391         |f|
  3387 	|f|
  3392         f := 'x' asFilename writeStream.
  3388 	f := 'x' asFilename writeStream.
  3393         f nextPutAll:'hallo'; sync; syncData; close
  3389 	f nextPutAll:'hallo'; sync; syncData; close
  3394     "
  3390     "
  3395 !
  3391 !
  3396 
  3392 
  3397 tcgetattr
  3393 tcgetattr
  3398     "unix only:
  3394     "unix only:
  3421     OBJ fp = __INST(handle);
  3417     OBJ fp = __INST(handle);
  3422     struct termios t;
  3418     struct termios t;
  3423     int sz;
  3419     int sz;
  3424 
  3420 
  3425     if (fp == nil)
  3421     if (fp == nil)
  3426         goto out;
  3422 	goto out;
  3427 
  3423 
  3428     if (__INST(handleType) == @symbol(socketHandle)) {
  3424     if (__INST(handleType) == @symbol(socketHandle)) {
  3429         // cg: termina attributes of a socket?
  3425 	// cg: termina attributes of a socket?
  3430         error = @symbol(badHandleType);
  3426 	error = @symbol(badHandleType);
  3431         goto out;
  3427 	goto out;
  3432         // fd = __FILEVal(fp);
  3428 	// fd = __FILEVal(fp);
  3433     } else
  3429     } else
  3434         if ((__INST(handleType) == nil)
  3430 	if ((__INST(handleType) == nil)
  3435          || (__INST(handleType) == @symbol(filePointer))
  3431 	 || (__INST(handleType) == @symbol(filePointer))
  3436          || (__INST(handleType) == @symbol(socketFilePointer))
  3432 	 || (__INST(handleType) == @symbol(socketFilePointer))
  3437          || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3433 	 || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3438         fd = fileno(__FILEVal(fp));
  3434 	fd = fileno(__FILEVal(fp));
  3439     } else {
  3435     } else {
  3440         error = @symbol(badHandleType);
  3436 	error = @symbol(badHandleType);
  3441         goto out;
  3437 	goto out;
  3442     }
  3438     }
  3443 
  3439 
  3444     __BEGIN_INTERRUPTABLE__
  3440     __BEGIN_INTERRUPTABLE__
  3445     do {
  3441     do {
  3446         __threadErrno = 0;
  3442 	__threadErrno = 0;
  3447         _ret = tcgetattr(fd, &t);
  3443 	_ret = tcgetattr(fd, &t);
  3448     } while (_ret < 0 && __threadErrno == EINTR);
  3444     } while (_ret < 0 && __threadErrno == EINTR);
  3449     __END_INTERRUPTABLE__
  3445     __END_INTERRUPTABLE__
  3450 
  3446 
  3451     if (_ret < 0) {
  3447     if (_ret < 0) {
  3452         error = __mkSmallInteger(__threadErrno);
  3448 	error = __mkSmallInteger(__threadErrno);
  3453     }
  3449     }
  3454     ignbrk = t.c_iflag & IGNBRK ? true : false;
  3450     ignbrk = t.c_iflag & IGNBRK ? true : false;
  3455     brkint = t.c_iflag & BRKINT ? true : false;
  3451     brkint = t.c_iflag & BRKINT ? true : false;
  3456     ignpar = t.c_iflag & IGNPAR ? true : false;
  3452     ignpar = t.c_iflag & IGNPAR ? true : false;
  3457     parmrk = t.c_iflag & PARMRK ? true : false;
  3453     parmrk = t.c_iflag & PARMRK ? true : false;
  3483     onocr = t.c_oflag & ONOCR ? true : false;
  3479     onocr = t.c_oflag & ONOCR ? true : false;
  3484     onlret = t.c_oflag & ONLRET ? true : false;
  3480     onlret = t.c_oflag & ONLRET ? true : false;
  3485 
  3481 
  3486     sz = t.c_cflag & CSIZE;
  3482     sz = t.c_cflag & CSIZE;
  3487     switch (sz) {
  3483     switch (sz) {
  3488         case CS5:
  3484 	case CS5:
  3489             csize = @symbol(cs5);
  3485 	    csize = @symbol(cs5);
  3490             break;
  3486 	    break;
  3491         case CS6:
  3487 	case CS6:
  3492             csize = @symbol(cs6);
  3488 	    csize = @symbol(cs6);
  3493             break;
  3489 	    break;
  3494         case CS7:
  3490 	case CS7:
  3495             csize = @symbol(cs7);
  3491 	    csize = @symbol(cs7);
  3496             break;
  3492 	    break;
  3497         case CS8:
  3493 	case CS8:
  3498             csize = @symbol(cs8);
  3494 	    csize = @symbol(cs8);
  3499             break;
  3495 	    break;
  3500     }
  3496     }
  3501     cstopb = t.c_cflag & CSTOPB ? true : false;
  3497     cstopb = t.c_cflag & CSTOPB ? true : false;
  3502     cread = t.c_cflag & CREAD ? true : false;
  3498     cread = t.c_cflag & CREAD ? true : false;
  3503     parenb = t.c_cflag & PARENB ? true : false;
  3499     parenb = t.c_cflag & PARENB ? true : false;
  3504     parodd = t.c_cflag & PARODD ? true : false;
  3500     parodd = t.c_cflag & PARODD ? true : false;
  3530 #endif
  3526 #endif
  3531 
  3527 
  3532 out:;
  3528 out:;
  3533 %}.
  3529 %}.
  3534     error notNil ifTrue:[
  3530     error notNil ifTrue:[
  3535         error == #unsupportedOperation ifTrue:[
  3531 	error == #unsupportedOperation ifTrue:[
  3536             "/ the system does not support tcgetattr
  3532 	    "/ the system does not support tcgetattr
  3537             ^ self errorUnsupportedOperation
  3533 	    ^ self errorUnsupportedOperation
  3538         ].
  3534 	].
  3539         lastErrorNumber := error.
  3535 	lastErrorNumber := error.
  3540         ^ self ioError:error.
  3536 	^ self ioError:error.
  3541     ].
  3537     ].
  3542     handle isNil ifTrue:[^ self errorNotOpen].
  3538     handle isNil ifTrue:[^ self errorNotOpen].
  3543 
  3539 
  3544     "/ construct a dictionary...
  3540     "/ construct a dictionary...
  3545     ret := Dictionary new.
  3541     ret := Dictionary new.
  3599 
  3595 
  3600     |readCount|
  3596     |readCount|
  3601 
  3597 
  3602     readCount := self nextBytes:count into:aCollection startingAt:start.
  3598     readCount := self nextBytes:count into:aCollection startingAt:start.
  3603     readCount = count ifTrue:[
  3599     readCount = count ifTrue:[
  3604         ^ aCollection.
  3600 	^ aCollection.
  3605     ].
  3601     ].
  3606     ^ aCollection copyFrom:1 to:start+readCount-1.
  3602     ^ aCollection copyFrom:1 to:start+readCount-1.
  3607 !
  3603 !
  3608 
  3604 
  3609 nextAvailable:count
  3605 nextAvailable:count
  3615     |buffer n|
  3611     |buffer n|
  3616 
  3612 
  3617     buffer := self contentsSpecies uninitializedNew:count.
  3613     buffer := self contentsSpecies uninitializedNew:count.
  3618     n := self nextAvailableBytes:count into:buffer startingAt:1.
  3614     n := self nextAvailableBytes:count into:buffer startingAt:1.
  3619     n == 0 ifTrue:[
  3615     n == 0 ifTrue:[
  3620         binary ifTrue:[
  3616 	binary ifTrue:[
  3621             ^ #[]
  3617 	    ^ #[]
  3622         ].
  3618 	].
  3623         ^ ''
  3619 	^ ''
  3624     ].
  3620     ].
  3625 
  3621 
  3626     n ~~ count ifTrue:[
  3622     n ~~ count ifTrue:[
  3627         ^ buffer copyTo:n
  3623 	^ buffer copyTo:n
  3628     ].
  3624     ].
  3629     ^ buffer.
  3625     ^ buffer.
  3630 
  3626 
  3631     "
  3627     "
  3632      (ReadStream on:#(1 2 3 4 5)) nextAvailable:3
  3628      (ReadStream on:#(1 2 3 4 5)) nextAvailable:3
  3680     if ((__INST(handleType) == nil)
  3676     if ((__INST(handleType) == nil)
  3681      || (__INST(handleType) == @symbol(filePointer))
  3677      || (__INST(handleType) == @symbol(filePointer))
  3682      || (__INST(handleType) == @symbol(socketFilePointer))
  3678      || (__INST(handleType) == @symbol(socketFilePointer))
  3683      || (__INST(handleType) == @symbol(socketHandle))
  3679      || (__INST(handleType) == @symbol(socketHandle))
  3684      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3680      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3685         if (((fp = __INST(handle)) != nil)
  3681 	if (((fp = __INST(handle)) != nil)
  3686             && (__INST(mode) != @symbol(writeonly))
  3682 	    && (__INST(mode) != @symbol(writeonly))
  3687             && __bothSmallInteger(count, start)
  3683 	    && __bothSmallInteger(count, start)
  3688         ) {
  3684 	) {
  3689             f = __FILEVal(fp);
  3685 	    f = __FILEVal(fp);
  3690 
  3686 
  3691             cnt = __intVal(count);
  3687 	    cnt = __intVal(count);
  3692             offs = __intVal(start) - 1;
  3688 	    offs = __intVal(start) - 1;
  3693 
  3689 
  3694             if (__isExternalBytesLike(anObject)) {
  3690 	    if (__isExternalBytesLike(anObject)) {
  3695                 OBJ sz;
  3691 		OBJ sz;
  3696 
  3692 
  3697                 nInstBytes = 0;
  3693 		nInstBytes = 0;
  3698                 extPtr = (char *)(__externalBytesAddress(anObject));
  3694 		extPtr = (char *)(__externalBytesAddress(anObject));
  3699                 if (extPtr == NULL) goto bad;
  3695 		if (extPtr == NULL) goto bad;
  3700                 sz = __externalBytesSize(anObject);
  3696 		sz = __externalBytesSize(anObject);
  3701                 if (__isSmallInteger(sz)) {
  3697 		if (__isSmallInteger(sz)) {
  3702                     objSize = __intVal(sz);
  3698 		    objSize = __intVal(sz);
  3703                 } else {
  3699 		} else {
  3704                     objSize = 0; /* unknown */
  3700 		    objSize = 0; /* unknown */
  3705                 }
  3701 		}
  3706             } else {
  3702 	    } else {
  3707                 OBJ oClass = __Class(anObject);
  3703 		OBJ oClass = __Class(anObject);
  3708                 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3704 		int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3709 
  3705 
  3710                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3706 		nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3711 
  3707 
  3712                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3708 		switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3713                     case BYTEARRAY:
  3709 		    case BYTEARRAY:
  3714                     case WORDARRAY:
  3710 		    case WORDARRAY:
  3715                     case LONGARRAY:
  3711 		    case LONGARRAY:
  3716                     case SWORDARRAY:
  3712 		    case SWORDARRAY:
  3717                     case SLONGARRAY:
  3713 		    case SLONGARRAY:
  3718                     case FLOATARRAY:
  3714 		    case FLOATARRAY:
  3719                         break;
  3715 			break;
  3720                     case DOUBLEARRAY:
  3716 		    case DOUBLEARRAY:
  3721 #ifdef __NEED_DOUBLE_ALIGN
  3717 #ifdef __NEED_DOUBLE_ALIGN
  3722                         nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3718 			nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3723 #endif
  3719 #endif
  3724                         break;
  3720 			break;
  3725                     case LONGLONGARRAY:
  3721 		    case LONGLONGARRAY:
  3726                     case SLONGLONGARRAY:
  3722 		    case SLONGLONGARRAY:
  3727 #ifdef __NEED_LONGLONG_ALIGN
  3723 #ifdef __NEED_LONGLONG_ALIGN
  3728                         nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3724 			nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3729 #endif
  3725 #endif
  3730                         break;
  3726 			break;
  3731                     default:
  3727 		    default:
  3732                         goto bad;
  3728 			goto bad;
  3733                 }
  3729 		}
  3734                 extPtr = (char *)0;
  3730 		extPtr = (char *)0;
  3735                 objSize = __Size(anObject) - nInstBytes;
  3731 		objSize = __Size(anObject) - nInstBytes;
  3736             }
  3732 	    }
  3737 
  3733 
  3738             if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3734 	    if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3739                 _buffered = (__INST(buffered) == true);
  3735 		_buffered = (__INST(buffered) == true);
  3740                 if (_buffered) {
  3736 		if (_buffered) {
  3741                     __READING__(f);
  3737 		    __READING__(f);
  3742                 }
  3738 		}
  3743 
  3739 
  3744                 if (extPtr) {
  3740 		if (extPtr) {
  3745                     __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3741 		    __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3746                 } else {
  3742 		} else {
  3747                     /*
  3743 		    /*
  3748                      * on interrupt, anObject may be moved to another location.
  3744 		     * on interrupt, anObject may be moved to another location.
  3749                      * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  3745 		     * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  3750                      * to get a new address.
  3746 		     * to get a new address.
  3751                      */
  3747 		     */
  3752                     offs += nInstBytes;
  3748 		    offs += nInstBytes;
  3753                     __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3749 		    __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3754                 }
  3750 		}
  3755                 /* 0 is NOT an EOF condition here ... */
  3751 		/* 0 is NOT an EOF condition here ... */
  3756                 if (ret >= 0) {
  3752 		if (ret >= 0) {
  3757                     if (__isSmallInteger(__INST(position))) {
  3753 		    if (__isSmallInteger(__INST(position))) {
  3758                         INT np = __intVal(__INST(position)) + ret;
  3754 			INT np = __intVal(__INST(position)) + ret;
  3759                         OBJ t;
  3755 			OBJ t;
  3760 
  3756 
  3761                         t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3757 			t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3762                     } else {
  3758 		    } else {
  3763                         __INST(position) = nil; /* i.e. do not know */
  3759 			__INST(position) = nil; /* i.e. do not know */
  3764                     }
  3760 		    }
  3765                     RETURN (__mkSmallInteger(ret));
  3761 		    RETURN (__mkSmallInteger(ret));
  3766                 }
  3762 		}
  3767                 __INST(position) = nil;
  3763 		__INST(position) = nil;
  3768                 error = __mkSmallInteger(__threadErrno);
  3764 		error = __mkSmallInteger(__threadErrno);
  3769             }
  3765 	    }
  3770         }
  3766 	}
  3771     }
  3767     }
  3772 bad: ;
  3768 bad: ;
  3773 %}.
  3769 %}.
  3774     hitEOF ifTrue:[^ 0].
  3770     hitEOF ifTrue:[^ 0].
  3775     error notNil ifTrue:[
  3771     error notNil ifTrue:[
  3776         lastErrorNumber := error.
  3772 	lastErrorNumber := error.
  3777         ^ self readError:error
  3773 	^ self readError:error
  3778     ].
  3774     ].
  3779     handle isNil ifTrue:[^ self errorNotOpen].
  3775     handle isNil ifTrue:[^ self errorNotOpen].
  3780     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  3776     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  3781     "
  3777     "
  3782      count not integer or arg not bit-like (String, ByteArray etc)
  3778      count not integer or arg not bit-like (String, ByteArray etc)
  3793 %{
  3789 %{
  3794 #ifdef __SCHTEAM__
  3790 #ifdef __SCHTEAM__
  3795     STObject handle = self.instVarAt(I_handle);
  3791     STObject handle = self.instVarAt(I_handle);
  3796 
  3792 
  3797     if (handle != STObject.Nil) {
  3793     if (handle != STObject.Nil) {
  3798         STObject next;
  3794 	STObject next;
  3799 
  3795 
  3800         next = handle.nextByte();
  3796 	next = handle.nextByte();
  3801         if (next != STObject.EOF) {
  3797 	if (next != STObject.EOF) {
  3802             self.instVarAt_put(I_position, STObject.Nil);
  3798 	    self.instVarAt_put(I_position, STObject.Nil);
  3803             return __c__._RETURN( next );
  3799 	    return __c__._RETURN( next );
  3804         }
  3800 	}
  3805         self.instVarAt_put(I_hitEOF, STObject.True);
  3801 	self.instVarAt_put(I_hitEOF, STObject.True);
  3806     }
  3802     }
  3807 #else
  3803 #else
  3808     FILEPOINTER f;
  3804     FILEPOINTER f;
  3809     unsigned char byte;
  3805     unsigned char byte;
  3810     int ret, _buffered;
  3806     int ret, _buffered;
  3814     if ((__INST(handleType) == nil)
  3810     if ((__INST(handleType) == nil)
  3815      || (__INST(handleType) == @symbol(filePointer))
  3811      || (__INST(handleType) == @symbol(filePointer))
  3816      || (__INST(handleType) == @symbol(socketFilePointer))
  3812      || (__INST(handleType) == @symbol(socketFilePointer))
  3817      || (__INST(handleType) == @symbol(socketHandle))
  3813      || (__INST(handleType) == @symbol(socketHandle))
  3818      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3814      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3819         if (((fp = __INST(handle)) != nil)
  3815 	if (((fp = __INST(handle)) != nil)
  3820          && (__INST(mode) != @symbol(writeonly))) {
  3816 	 && (__INST(mode) != @symbol(writeonly))) {
  3821             f = __FILEVal(fp);
  3817 	    f = __FILEVal(fp);
  3822 
  3818 
  3823             _buffered = (__INST(buffered) == true);
  3819 	    _buffered = (__INST(buffered) == true);
  3824             if (_buffered) {
  3820 	    if (_buffered) {
  3825                 __READING__(f)
  3821 		__READING__(f)
  3826             }
  3822 	    }
  3827             __READBYTE__(ret, f, &byte, _buffered, __INST(handleType));
  3823 	    __READBYTE__(ret, f, &byte, _buffered, __INST(handleType));
  3828             if (ret > 0) {
  3824 	    if (ret > 0) {
  3829                 if (__isSmallInteger(__INST(position))) {
  3825 		if (__isSmallInteger(__INST(position))) {
  3830                     INT np = __intVal(__INST(position)) + 1;
  3826 		    INT np = __intVal(__INST(position)) + 1;
  3831                     OBJ t;
  3827 		    OBJ t;
  3832 
  3828 
  3833                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3829 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3834                 } else {
  3830 		} else {
  3835                     __INST(position) = nil; /* i.e. do not know */
  3831 		    __INST(position) = nil; /* i.e. do not know */
  3836                 }
  3832 		}
  3837                 RETURN (__mkSmallInteger(byte));
  3833 		RETURN (__mkSmallInteger(byte));
  3838             }
  3834 	    }
  3839 
  3835 
  3840             if (ret == 0) {
  3836 	    if (ret == 0) {
  3841                 __INST(hitEOF) = true;
  3837 		__INST(hitEOF) = true;
  3842             } else /* ret < 0 */ {
  3838 	    } else /* ret < 0 */ {
  3843                 __INST(position) = nil;
  3839 		__INST(position) = nil;
  3844                 error = __mkSmallInteger(__threadErrno);
  3840 		error = __mkSmallInteger(__threadErrno);
  3845             }
  3841 	    }
  3846         }
  3842 	}
  3847     }
  3843     }
  3848 #endif /* not SCHTEAM */
  3844 #endif /* not SCHTEAM */
  3849 %}.
  3845 %}.
  3850     hitEOF ifTrue:[^ self pastEndRead].
  3846     hitEOF ifTrue:[^ self pastEndRead].
  3851     error notNil ifTrue:[
  3847     error notNil ifTrue:[
  3852         lastErrorNumber := error.
  3848 	lastErrorNumber := error.
  3853         ^ self readError:error
  3849 	^ self readError:error
  3854     ].
  3850     ].
  3855     handle isNil ifTrue:[^ self errorNotOpen].
  3851     handle isNil ifTrue:[^ self errorNotOpen].
  3856     ^ self errorWriteOnly
  3852     ^ self errorWriteOnly
  3857 !
  3853 !
  3858 
  3854 
  3893     if ((__INST(handleType) == nil)
  3889     if ((__INST(handleType) == nil)
  3894      || (__INST(handleType) == @symbol(filePointer))
  3890      || (__INST(handleType) == @symbol(filePointer))
  3895      || (__INST(handleType) == @symbol(socketFilePointer))
  3891      || (__INST(handleType) == @symbol(socketFilePointer))
  3896      || (__INST(handleType) == @symbol(socketHandle))
  3892      || (__INST(handleType) == @symbol(socketHandle))
  3897      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3893      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3898         if (((fp = __INST(handle)) != nil)
  3894 	if (((fp = __INST(handle)) != nil)
  3899             && (__INST(mode) != @symbol(writeonly))
  3895 	    && (__INST(mode) != @symbol(writeonly))
  3900             && __bothSmallInteger(count, start)
  3896 	    && __bothSmallInteger(count, start)
  3901         ) {
  3897 	) {
  3902             f = __FILEVal(fp);
  3898 	    f = __FILEVal(fp);
  3903 
  3899 
  3904             cnt = __intVal(count);
  3900 	    cnt = __intVal(count);
  3905             offs = __intVal(start) - 1;
  3901 	    offs = __intVal(start) - 1;
  3906 
  3902 
  3907             if (__isExternalBytesLike(anObject)) {
  3903 	    if (__isExternalBytesLike(anObject)) {
  3908                 OBJ sz;
  3904 		OBJ sz;
  3909 
  3905 
  3910                 nInstBytes = 0;
  3906 		nInstBytes = 0;
  3911                 extPtr = (char *)(__externalBytesAddress(anObject));
  3907 		extPtr = (char *)(__externalBytesAddress(anObject));
  3912                 if (extPtr == NULL) goto bad;
  3908 		if (extPtr == NULL) goto bad;
  3913                 sz = __externalBytesSize(anObject);
  3909 		sz = __externalBytesSize(anObject);
  3914                 if (__isSmallInteger(sz)) {
  3910 		if (__isSmallInteger(sz)) {
  3915                     objSize = __intVal(sz);
  3911 		    objSize = __intVal(sz);
  3916                 } else {
  3912 		} else {
  3917                     objSize = 0; /* unknown */
  3913 		    objSize = 0; /* unknown */
  3918                 }
  3914 		}
  3919             } else {
  3915 	    } else {
  3920                 OBJ oClass = __Class(anObject);
  3916 		OBJ oClass = __Class(anObject);
  3921                 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3917 		int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3922 
  3918 
  3923                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3919 		nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3924                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3920 		switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3925                     case BYTEARRAY:
  3921 		    case BYTEARRAY:
  3926                     case WORDARRAY:
  3922 		    case WORDARRAY:
  3927                     case LONGARRAY:
  3923 		    case LONGARRAY:
  3928                     case SWORDARRAY:
  3924 		    case SWORDARRAY:
  3929                     case SLONGARRAY:
  3925 		    case SLONGARRAY:
  3930                     case FLOATARRAY:
  3926 		    case FLOATARRAY:
  3931                         break;
  3927 			break;
  3932                     case DOUBLEARRAY:
  3928 		    case DOUBLEARRAY:
  3933 #ifdef __NEED_DOUBLE_ALIGN
  3929 #ifdef __NEED_DOUBLE_ALIGN
  3934                         nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3930 			nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3935 #endif
  3931 #endif
  3936                         break;
  3932 			break;
  3937                     case LONGLONGARRAY:
  3933 		    case LONGLONGARRAY:
  3938                     case SLONGLONGARRAY:
  3934 		    case SLONGLONGARRAY:
  3939 #ifdef __NEED_LONGLONG_ALIGN
  3935 #ifdef __NEED_LONGLONG_ALIGN
  3940                         nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3936 			nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3941 #endif
  3937 #endif
  3942                         break;
  3938 			break;
  3943                     default:
  3939 		    default:
  3944                         goto bad;
  3940 			goto bad;
  3945                 }
  3941 		}
  3946                 extPtr = (char *)0;
  3942 		extPtr = (char *)0;
  3947                 objSize = __Size(anObject) - nInstBytes;
  3943 		objSize = __Size(anObject) - nInstBytes;
  3948             }
  3944 	    }
  3949             if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3945 	    if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3950                 _buffered = (__INST(buffered) == true);
  3946 		_buffered = (__INST(buffered) == true);
  3951                 if (_buffered) {
  3947 		if (_buffered) {
  3952                     __READING__(f);
  3948 		    __READING__(f);
  3953                 }
  3949 		}
  3954 
  3950 
  3955                 if (extPtr) {
  3951 		if (extPtr) {
  3956                     __READBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3952 		    __READBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3957                 } else {
  3953 		} else {
  3958                     /*
  3954 		    /*
  3959                      * on interrupt, anObject may be moved to another location.
  3955 		     * on interrupt, anObject may be moved to another location.
  3960                      * So we pass anObject, and the offset to the __READBYTES_OBJ__ macro.
  3956 		     * So we pass anObject, and the offset to the __READBYTES_OBJ__ macro.
  3961                      */
  3957 		     */
  3962                     offs += nInstBytes;
  3958 		    offs += nInstBytes;
  3963                     __READBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3959 		    __READBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3964                 }
  3960 		}
  3965 
  3961 
  3966                 if (ret > 0) {
  3962 		if (ret > 0) {
  3967                     if (__isSmallInteger(__INST(position))) {
  3963 		    if (__isSmallInteger(__INST(position))) {
  3968                         INT np = __intVal(__INST(position)) + ret;
  3964 			INT np = __intVal(__INST(position)) + ret;
  3969                         OBJ t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3965 			OBJ t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3970                     } else {
  3966 		    } else {
  3971                         __INST(position) = nil; /* i.e. do not know */
  3967 			__INST(position) = nil; /* i.e. do not know */
  3972                     }
  3968 		    }
  3973                     RETURN (__mkSmallInteger(ret));
  3969 		    RETURN (__mkSmallInteger(ret));
  3974                 }
  3970 		}
  3975                 if (ret == 0) {
  3971 		if (ret == 0) {
  3976                     __INST(hitEOF) = true;
  3972 		    __INST(hitEOF) = true;
  3977                 } else /* ret < 0 */ {
  3973 		} else /* ret < 0 */ {
  3978                     __INST(position) = nil;
  3974 		    __INST(position) = nil;
  3979                     error = __mkSmallInteger(__threadErrno);
  3975 		    error = __mkSmallInteger(__threadErrno);
  3980                 }
  3976 		}
  3981             }
  3977 	    }
  3982         }
  3978 	}
  3983     }
  3979     }
  3984 bad: ;
  3980 bad: ;
  3985 %}.
  3981 %}.
  3986     hitEOF ifTrue:[^ 0].
  3982     hitEOF ifTrue:[^ 0].
  3987     error notNil ifTrue:[
  3983     error notNil ifTrue:[
  3988         lastErrorNumber := error.
  3984 	lastErrorNumber := error.
  3989         ^ self readError:error
  3985 	^ self readError:error
  3990     ].
  3986     ].
  3991     handle isNil ifTrue:[^ self errorNotOpen].
  3987     handle isNil ifTrue:[^ self errorNotOpen].
  3992     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  3988     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  3993     "
  3989     "
  3994      count not integer or arg not bit-like (String, ByteArray etc)
  3990      count not integer or arg not bit-like (String, ByteArray etc)
  4011     if ((__INST(handleType) == nil)
  4007     if ((__INST(handleType) == nil)
  4012      || (__INST(handleType) == @symbol(filePointer))
  4008      || (__INST(handleType) == @symbol(filePointer))
  4013      || (__INST(handleType) == @symbol(socketFilePointer))
  4009      || (__INST(handleType) == @symbol(socketFilePointer))
  4014      || (__INST(handleType) == @symbol(socketHandle))
  4010      || (__INST(handleType) == @symbol(socketHandle))
  4015      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4011      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4016         if (((fp = __INST(handle)) != nil)
  4012 	if (((fp = __INST(handle)) != nil)
  4017             && (__INST(mode) != @symbol(writeonly))
  4013 	    && (__INST(mode) != @symbol(writeonly))
  4018         ) {
  4014 	) {
  4019             FILEPOINTER f;
  4015 	    FILEPOINTER f;
  4020             int ret, _buffered;
  4016 	    int ret, _buffered;
  4021             short value;
  4017 	    short value;
  4022             union {
  4018 	    union {
  4023                 unsigned char buffer[2];
  4019 		unsigned char buffer[2];
  4024                 short shortVal;
  4020 		short shortVal;
  4025             } u;
  4021 	    } u;
  4026 
  4022 
  4027             f = __FILEVal(fp);
  4023 	    f = __FILEVal(fp);
  4028             _buffered = (__INST(buffered) == true);
  4024 	    _buffered = (__INST(buffered) == true);
  4029             if (_buffered) {
  4025 	    if (_buffered) {
  4030                 __READING__(f)
  4026 		__READING__(f)
  4031             }
  4027 	    }
  4032             __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType));
  4028 	    __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType));
  4033 
  4029 
  4034             if (ret == 2) {
  4030 	    if (ret == 2) {
  4035                 if (__isSmallInteger(__INST(position))) {
  4031 		if (__isSmallInteger(__INST(position))) {
  4036                     INT np = __intVal(__INST(position)) + 2;
  4032 		    INT np = __intVal(__INST(position)) + 2;
  4037                     OBJ t;
  4033 		    OBJ t;
  4038 
  4034 
  4039                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4035 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4040                 } else {
  4036 		} else {
  4041                     __INST(position) = nil; /* i.e. do not know */
  4037 		    __INST(position) = nil; /* i.e. do not know */
  4042                 }
  4038 		}
  4043                 if (msbFlag == true) {
  4039 		if (msbFlag == true) {
  4044 #if defined(__MSBFIRST__)
  4040 #if defined(__MSBFIRST__)
  4045                     value = u.shortVal;
  4041 		    value = u.shortVal;
  4046 #else
  4042 #else
  4047                     value = ((u.buffer[0] & 0xFF) << 8) | (u.buffer[1] & 0xFF);
  4043 		    value = ((u.buffer[0] & 0xFF) << 8) | (u.buffer[1] & 0xFF);
  4048 #endif
  4044 #endif
  4049                 } else {
  4045 		} else {
  4050 #if defined(__LSBFIRST__)
  4046 #if defined(__LSBFIRST__)
  4051                     value = u.shortVal;
  4047 		    value = u.shortVal;
  4052 #else
  4048 #else
  4053                     value = ((u.buffer[1] & 0xFF) << 8) | (u.buffer[0] & 0xFF);
  4049 		    value = ((u.buffer[1] & 0xFF) << 8) | (u.buffer[0] & 0xFF);
  4054 #endif
  4050 #endif
  4055                 }
  4051 		}
  4056                 RETURN (__mkSmallInteger(value));
  4052 		RETURN (__mkSmallInteger(value));
  4057             }
  4053 	    }
  4058 
  4054 
  4059             if (ret < 0) {
  4055 	    if (ret < 0) {
  4060                 __INST(position) = nil; /* i.e. do not know */
  4056 		__INST(position) = nil; /* i.e. do not know */
  4061                 error = __mkSmallInteger(__threadErrno);
  4057 		error = __mkSmallInteger(__threadErrno);
  4062             } else /* ret == 0 */ {
  4058 	    } else /* ret == 0 */ {
  4063                 __INST(hitEOF) = true;
  4059 		__INST(hitEOF) = true;
  4064             }
  4060 	    }
  4065         }
  4061 	}
  4066     }
  4062     }
  4067 %}.
  4063 %}.
  4068     hitEOF ifTrue:[^ self pastEndRead].
  4064     hitEOF ifTrue:[^ self pastEndRead].
  4069     handle isNil ifTrue:[^ self errorNotOpen].
  4065     handle isNil ifTrue:[^ self errorNotOpen].
  4070     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4066     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4088     if ((__INST(handleType) == nil)
  4084     if ((__INST(handleType) == nil)
  4089      || (__INST(handleType) == @symbol(filePointer))
  4085      || (__INST(handleType) == @symbol(filePointer))
  4090      || (__INST(handleType) == @symbol(socketFilePointer))
  4086      || (__INST(handleType) == @symbol(socketFilePointer))
  4091      || (__INST(handleType) == @symbol(socketHandle))
  4087      || (__INST(handleType) == @symbol(socketHandle))
  4092      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4088      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4093         if (((fp = __INST(handle)) != nil)
  4089 	if (((fp = __INST(handle)) != nil)
  4094             && (__INST(mode) != @symbol(writeonly))
  4090 	    && (__INST(mode) != @symbol(writeonly))
  4095         ) {
  4091 	) {
  4096             FILEPOINTER f;
  4092 	    FILEPOINTER f;
  4097             int ret, _buffered;
  4093 	    int ret, _buffered;
  4098             int value;
  4094 	    int value;
  4099             union {
  4095 	    union {
  4100                 unsigned char buffer[4];
  4096 		unsigned char buffer[4];
  4101                 int intVal;
  4097 		int intVal;
  4102             } u;
  4098 	    } u;
  4103 
  4099 
  4104             f = __FILEVal(fp);
  4100 	    f = __FILEVal(fp);
  4105             _buffered = (__INST(buffered) == true);
  4101 	    _buffered = (__INST(buffered) == true);
  4106             if (_buffered) {
  4102 	    if (_buffered) {
  4107                 __READING__(f)
  4103 		__READING__(f)
  4108             }
  4104 	    }
  4109             __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType));
  4105 	    __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType));
  4110 
  4106 
  4111             if (ret == 4) {
  4107 	    if (ret == 4) {
  4112                 if (__isSmallInteger(__INST(position))) {
  4108 		if (__isSmallInteger(__INST(position))) {
  4113                     INT np = __intVal(__INST(position)) + 4;
  4109 		    INT np = __intVal(__INST(position)) + 4;
  4114                     OBJ t;
  4110 		    OBJ t;
  4115 
  4111 
  4116                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4112 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4117                 } else {
  4113 		} else {
  4118                     __INST(position) = nil; /* i.e. do not know */
  4114 		    __INST(position) = nil; /* i.e. do not know */
  4119                 }
  4115 		}
  4120                 if (msbFlag == true) {
  4116 		if (msbFlag == true) {
  4121 #if defined(__MSBFIRST__)
  4117 #if defined(__MSBFIRST__)
  4122                     value = u.intVal;
  4118 		    value = u.intVal;
  4123 #else
  4119 #else
  4124                     value = (u.buffer[0] & 0xFF);
  4120 		    value = (u.buffer[0] & 0xFF);
  4125                     value = (value << 8) | (u.buffer[1] & 0xFF);
  4121 		    value = (value << 8) | (u.buffer[1] & 0xFF);
  4126                     value = (value << 8) | (u.buffer[2] & 0xFF);
  4122 		    value = (value << 8) | (u.buffer[2] & 0xFF);
  4127                     value = (value << 8) | (u.buffer[3] & 0xFF);
  4123 		    value = (value << 8) | (u.buffer[3] & 0xFF);
  4128 #endif
  4124 #endif
  4129                 } else {
  4125 		} else {
  4130 #if defined(__LSBFIRST__)
  4126 #if defined(__LSBFIRST__)
  4131                     value = u.intVal;
  4127 		    value = u.intVal;
  4132 #else
  4128 #else
  4133                     value = (u.buffer[3] & 0xFF);
  4129 		    value = (u.buffer[3] & 0xFF);
  4134                     value = (value << 8) | (u.buffer[2] & 0xFF);
  4130 		    value = (value << 8) | (u.buffer[2] & 0xFF);
  4135                     value = (value << 8) | (u.buffer[1] & 0xFF);
  4131 		    value = (value << 8) | (u.buffer[1] & 0xFF);
  4136                     value = (value << 8) | (u.buffer[0] & 0xFF);
  4132 		    value = (value << 8) | (u.buffer[0] & 0xFF);
  4137 #endif
  4133 #endif
  4138                 }
  4134 		}
  4139 #if __POINTER_SIZE__ == 8
  4135 #if __POINTER_SIZE__ == 8
  4140                 RETURN ( __mkSmallInteger(value));
  4136 		RETURN ( __mkSmallInteger(value));
  4141 #else
  4137 #else
  4142                 RETURN ( __MKINT(value) );
  4138 		RETURN ( __MKINT(value) );
  4143 #endif
  4139 #endif
  4144             }
  4140 	    }
  4145 
  4141 
  4146             if (ret < 0) {
  4142 	    if (ret < 0) {
  4147                 __INST(position) = nil;
  4143 		__INST(position) = nil;
  4148                 error = __mkSmallInteger(__threadErrno);
  4144 		error = __mkSmallInteger(__threadErrno);
  4149             } else /* ret == 0 */ {
  4145 	    } else /* ret == 0 */ {
  4150                 __INST(hitEOF) = true;
  4146 		__INST(hitEOF) = true;
  4151             }
  4147 	    }
  4152         }
  4148 	}
  4153     }
  4149     }
  4154 %}.
  4150 %}.
  4155     hitEOF ifTrue:[^ self pastEndRead].
  4151     hitEOF ifTrue:[^ self pastEndRead].
  4156     handle isNil ifTrue:[^ self errorNotOpen].
  4152     handle isNil ifTrue:[^ self errorNotOpen].
  4157     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4153     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4174     if ((__INST(handleType) == nil)
  4170     if ((__INST(handleType) == nil)
  4175      || (__INST(handleType) == @symbol(filePointer))
  4171      || (__INST(handleType) == @symbol(filePointer))
  4176      || (__INST(handleType) == @symbol(socketFilePointer))
  4172      || (__INST(handleType) == @symbol(socketFilePointer))
  4177      || (__INST(handleType) == @symbol(socketHandle))
  4173      || (__INST(handleType) == @symbol(socketHandle))
  4178      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4174      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4179         if (((fp = __INST(handle)) != nil)
  4175 	if (((fp = __INST(handle)) != nil)
  4180             && (__INST(mode) != @symbol(writeonly))
  4176 	    && (__INST(mode) != @symbol(writeonly))
  4181         ) {
  4177 	) {
  4182             FILEPOINTER f;
  4178 	    FILEPOINTER f;
  4183             int ret, _buffered;
  4179 	    int ret, _buffered;
  4184             unsigned int value;
  4180 	    unsigned int value;
  4185             union {
  4181 	    union {
  4186                 unsigned char buffer[2];
  4182 		unsigned char buffer[2];
  4187                 unsigned short shortVal;
  4183 		unsigned short shortVal;
  4188             } u;
  4184 	    } u;
  4189 
  4185 
  4190             f = __FILEVal(fp);
  4186 	    f = __FILEVal(fp);
  4191             _buffered = (__INST(buffered) == true);
  4187 	    _buffered = (__INST(buffered) == true);
  4192             if (_buffered) {
  4188 	    if (_buffered) {
  4193                 __READING__(f)
  4189 		__READING__(f)
  4194             }
  4190 	    }
  4195             __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType));
  4191 	    __READBYTES__(ret, f, u.buffer, 2, _buffered, __INST(handleType));
  4196 
  4192 
  4197             if (ret == 2) {
  4193 	    if (ret == 2) {
  4198                 if (__isSmallInteger(__INST(position))) {
  4194 		if (__isSmallInteger(__INST(position))) {
  4199                     INT np = __intVal(__INST(position)) + 2;
  4195 		    INT np = __intVal(__INST(position)) + 2;
  4200                     OBJ t;
  4196 		    OBJ t;
  4201 
  4197 
  4202                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4198 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4203                 } else {
  4199 		} else {
  4204                     __INST(position) = nil; /* i.e. do not know */
  4200 		    __INST(position) = nil; /* i.e. do not know */
  4205                 }
  4201 		}
  4206                 if (msbFlag == true) {
  4202 		if (msbFlag == true) {
  4207 #if defined(__MSBFIRST__)
  4203 #if defined(__MSBFIRST__)
  4208                     value = u.shortVal;
  4204 		    value = u.shortVal;
  4209 #else
  4205 #else
  4210                     value = (u.buffer[0] << 8) | u.buffer[1];
  4206 		    value = (u.buffer[0] << 8) | u.buffer[1];
  4211 #endif
  4207 #endif
  4212                 } else {
  4208 		} else {
  4213 #if defined(__LSBFIRST__)
  4209 #if defined(__LSBFIRST__)
  4214                     value = u.shortVal;
  4210 		    value = u.shortVal;
  4215 #else
  4211 #else
  4216                     value = (u.buffer[1] << 8) | u.buffer[0];
  4212 		    value = (u.buffer[1] << 8) | u.buffer[0];
  4217 #endif
  4213 #endif
  4218                 }
  4214 		}
  4219                 RETURN (__mkSmallInteger(value));
  4215 		RETURN (__mkSmallInteger(value));
  4220             }
  4216 	    }
  4221 
  4217 
  4222             if (ret < 0) {
  4218 	    if (ret < 0) {
  4223                 __INST(position) = nil; /* i.e. do not know */
  4219 		__INST(position) = nil; /* i.e. do not know */
  4224                 error = __mkSmallInteger(__threadErrno);
  4220 		error = __mkSmallInteger(__threadErrno);
  4225             } else /* ret == 0 */ {
  4221 	    } else /* ret == 0 */ {
  4226                 __INST(hitEOF) = true;
  4222 		__INST(hitEOF) = true;
  4227             }
  4223 	    }
  4228         }
  4224 	}
  4229     }
  4225     }
  4230 %}.
  4226 %}.
  4231     hitEOF ifTrue:[^ self pastEndRead].
  4227     hitEOF ifTrue:[^ self pastEndRead].
  4232     handle isNil ifTrue:[^ self errorNotOpen].
  4228     handle isNil ifTrue:[^ self errorNotOpen].
  4233     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4229     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4251     if ((__INST(handleType) == nil)
  4247     if ((__INST(handleType) == nil)
  4252      || (__INST(handleType) == @symbol(filePointer))
  4248      || (__INST(handleType) == @symbol(filePointer))
  4253      || (__INST(handleType) == @symbol(socketFilePointer))
  4249      || (__INST(handleType) == @symbol(socketFilePointer))
  4254      || (__INST(handleType) == @symbol(socketHandle))
  4250      || (__INST(handleType) == @symbol(socketHandle))
  4255      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4251      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4256         if (((fp = __INST(handle)) != nil)
  4252 	if (((fp = __INST(handle)) != nil)
  4257             && (__INST(mode) != @symbol(writeonly))
  4253 	    && (__INST(mode) != @symbol(writeonly))
  4258         ) {
  4254 	) {
  4259             FILEPOINTER f;
  4255 	    FILEPOINTER f;
  4260             int ret, _buffered;
  4256 	    int ret, _buffered;
  4261             unsigned INT value;
  4257 	    unsigned INT value;
  4262             union {
  4258 	    union {
  4263                 unsigned char buffer[4];
  4259 		unsigned char buffer[4];
  4264                 unsigned int intVal;
  4260 		unsigned int intVal;
  4265             } u;
  4261 	    } u;
  4266 
  4262 
  4267             f = __FILEVal(fp);
  4263 	    f = __FILEVal(fp);
  4268             _buffered = (__INST(buffered) == true);
  4264 	    _buffered = (__INST(buffered) == true);
  4269             if (_buffered) {
  4265 	    if (_buffered) {
  4270                 __READING__(f)
  4266 		__READING__(f)
  4271             }
  4267 	    }
  4272             __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType));
  4268 	    __READBYTES__(ret, f, u.buffer, 4, _buffered, __INST(handleType));
  4273 
  4269 
  4274             if (ret == 4) {
  4270 	    if (ret == 4) {
  4275                 if (__isSmallInteger(__INST(position))) {
  4271 		if (__isSmallInteger(__INST(position))) {
  4276                     INT np = __intVal(__INST(position)) + 4;
  4272 		    INT np = __intVal(__INST(position)) + 4;
  4277                     OBJ t;
  4273 		    OBJ t;
  4278 
  4274 
  4279                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4275 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4280                 } else {
  4276 		} else {
  4281                     __INST(position) = nil; /* i.e. do not know */
  4277 		    __INST(position) = nil; /* i.e. do not know */
  4282                 }
  4278 		}
  4283                 if (msbFlag == true) {
  4279 		if (msbFlag == true) {
  4284 #if defined(__MSBFIRST__)
  4280 #if defined(__MSBFIRST__)
  4285                     value = u.intVal;
  4281 		    value = u.intVal;
  4286 #else
  4282 #else
  4287                     value = u.buffer[0];
  4283 		    value = u.buffer[0];
  4288                     value = (value << 8) | u.buffer[1];
  4284 		    value = (value << 8) | u.buffer[1];
  4289                     value = (value << 8) | u.buffer[2];
  4285 		    value = (value << 8) | u.buffer[2];
  4290                     value = (value << 8) | u.buffer[3];
  4286 		    value = (value << 8) | u.buffer[3];
  4291 #endif
  4287 #endif
  4292                 } else {
  4288 		} else {
  4293 #if defined(__LSBFIRST__)
  4289 #if defined(__LSBFIRST__)
  4294                     value = u.intVal;
  4290 		    value = u.intVal;
  4295 #else
  4291 #else
  4296                     value = u.buffer[3];
  4292 		    value = u.buffer[3];
  4297                     value = (value << 8) | u.buffer[2];
  4293 		    value = (value << 8) | u.buffer[2];
  4298                     value = (value << 8) | u.buffer[1];
  4294 		    value = (value << 8) | u.buffer[1];
  4299                     value = (value << 8) | u.buffer[0];
  4295 		    value = (value << 8) | u.buffer[0];
  4300 #endif
  4296 #endif
  4301                 }
  4297 		}
  4302 #if __POINTER_SIZE__ == 8
  4298 #if __POINTER_SIZE__ == 8
  4303                 value &= 0xFFFFFFFF;
  4299 		value &= 0xFFFFFFFF;
  4304                 RETURN (__mkSmallInteger(value));
  4300 		RETURN (__mkSmallInteger(value));
  4305 #else
  4301 #else
  4306                 if (value <= _MAX_INT) {
  4302 		if (value <= _MAX_INT) {
  4307                     RETURN (__mkSmallInteger(value));
  4303 		    RETURN (__mkSmallInteger(value));
  4308                 }
  4304 		}
  4309                 RETURN (__MKULARGEINT(value) );
  4305 		RETURN (__MKULARGEINT(value) );
  4310 #endif
  4306 #endif
  4311             }
  4307 	    }
  4312 
  4308 
  4313             if (ret < 0) {
  4309 	    if (ret < 0) {
  4314                 __INST(position) = nil; /* i.e. do not know */
  4310 		__INST(position) = nil; /* i.e. do not know */
  4315                 error = __mkSmallInteger(__threadErrno);
  4311 		error = __mkSmallInteger(__threadErrno);
  4316             } else /* ret == 0 */ {
  4312 	    } else /* ret == 0 */ {
  4317                 __INST(hitEOF) = true;
  4313 		__INST(hitEOF) = true;
  4318             }
  4314 	    }
  4319         }
  4315 	}
  4320     }
  4316     }
  4321 %}.
  4317 %}.
  4322     hitEOF ifTrue:[^ self pastEndRead].
  4318     hitEOF ifTrue:[^ self pastEndRead].
  4323     handle isNil ifTrue:[^ self errorNotOpen].
  4319     handle isNil ifTrue:[^ self errorNotOpen].
  4324     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4320     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  4327 !
  4323 !
  4328 
  4324 
  4329 nextWord
  4325 nextWord
  4330     <resource: #obsolete>
  4326     <resource: #obsolete>
  4331     "in text-mode:
  4327     "in text-mode:
  4332          read the alphaNumeric next word (i.e. up to non letter-or-digit).
  4328 	 read the alphaNumeric next word (i.e. up to non letter-or-digit).
  4333          return a string containing those characters.
  4329 	 return a string containing those characters.
  4334      in binary-mode:
  4330      in binary-mode:
  4335          read two bytes (msb-first) and return the value as a 16-bit
  4331 	 read two bytes (msb-first) and return the value as a 16-bit
  4336          unsigned Integer (for compatibility with other smalltalks)"
  4332 	 unsigned Integer (for compatibility with other smalltalks)"
  4337 
  4333 
  4338     binary ifTrue:[
  4334     binary ifTrue:[
  4339         self obsoleteMethodWarning:'use #nextUnsignedInt16MSB:true'.
  4335 	self obsoleteMethodWarning:'use #nextUnsignedInt16MSB:true'.
  4340         ^ self nextUnsignedInt16MSB:true
  4336 	^ self nextUnsignedInt16MSB:true
  4341     ].
  4337     ].
  4342     self obsoleteMethodWarning:'use #nextAlphaNumericWord'.
  4338     self obsoleteMethodWarning:'use #nextAlphaNumericWord'.
  4343     ^ self nextAlphaNumericWord
  4339     ^ self nextAlphaNumericWord
  4344 ! !
  4340 ! !
  4345 
  4341 
  4358     if ((__INST(handleType) == nil)
  4354     if ((__INST(handleType) == nil)
  4359      || (__INST(handleType) == @symbol(filePointer))
  4355      || (__INST(handleType) == @symbol(filePointer))
  4360      || (__INST(handleType) == @symbol(socketFilePointer))
  4356      || (__INST(handleType) == @symbol(socketFilePointer))
  4361      || (__INST(handleType) == @symbol(socketHandle))
  4357      || (__INST(handleType) == @symbol(socketHandle))
  4362      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4358      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4363         if (((fp = __INST(handle)) != nil)
  4359 	if (((fp = __INST(handle)) != nil)
  4364          && (__INST(mode) != @symbol(readonly))
  4360 	 && (__INST(mode) != @symbol(readonly))
  4365          && __isSmallInteger(aByteValue)
  4361 	 && __isSmallInteger(aByteValue)
  4366 
  4362 
  4367         ) {
  4363 	) {
  4368             int _buffered = (__INST(buffered) == true);
  4364 	    int _buffered = (__INST(buffered) == true);
  4369             FILEPOINTER f = __FILEVal(fp);
  4365 	    FILEPOINTER f = __FILEVal(fp);
  4370             char c = __intVal(aByteValue);
  4366 	    char c = __intVal(aByteValue);
  4371             int cnt;
  4367 	    int cnt;
  4372 
  4368 
  4373             if (_buffered) {
  4369 	    if (_buffered) {
  4374                 __WRITING__(f)
  4370 		__WRITING__(f)
  4375             }
  4371 	    }
  4376 #ifdef __win32__
  4372 #ifdef __win32__
  4377             if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  4373 	    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  4378                 cnt = __win32_fwrite(&c, 1, 1, f);
  4374 		cnt = __win32_fwrite(&c, 1, 1, f);
  4379             } else
  4375 	    } else
  4380 #endif
  4376 #endif
  4381             {
  4377 	    {
  4382                 __WRITEBYTE__(cnt, f, &c, _buffered, __INST(handleType));
  4378 		__WRITEBYTE__(cnt, f, &c, _buffered, __INST(handleType));
  4383             }
  4379 	    }
  4384             if (cnt == 1) {
  4380 	    if (cnt == 1) {
  4385                 if (__isSmallInteger(__INST(position))) {
  4381 		if (__isSmallInteger(__INST(position))) {
  4386                     INT np = __intVal(__INST(position)) + 1;
  4382 		    INT np = __intVal(__INST(position)) + 1;
  4387                     OBJ t;
  4383 		    OBJ t;
  4388 
  4384 
  4389                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4385 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4390                 } else {
  4386 		} else {
  4391                     __INST(position) = nil; /* i.e. do not know */
  4387 		    __INST(position) = nil; /* i.e. do not know */
  4392                 }
  4388 		}
  4393                 RETURN (self);
  4389 		RETURN (self);
  4394             }
  4390 	    }
  4395             if (cnt < 0) {
  4391 	    if (cnt < 0) {
  4396                 __INST(position) = nil; /* i.e. do not know */
  4392 		__INST(position) = nil; /* i.e. do not know */
  4397             }
  4393 	    }
  4398             error = __mkSmallInteger(__threadErrno);
  4394 	    error = __mkSmallInteger(__threadErrno);
  4399         }
  4395 	}
  4400     }
  4396     }
  4401 %}.
  4397 %}.
  4402     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4398     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4403     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4399     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4404     lastErrorNumber := error.
  4400     lastErrorNumber := error.
  4415 
  4411 
  4416     |error|
  4412     |error|
  4417 %{
  4413 %{
  4418     int num;
  4414     int num;
  4419     union {
  4415     union {
  4420         char bytes[2];
  4416 	char bytes[2];
  4421         short shortVal;
  4417 	short shortVal;
  4422     } u;
  4418     } u;
  4423     OBJ fp;
  4419     OBJ fp;
  4424 
  4420 
  4425     __INST(lastErrorNumber) = nil;
  4421     __INST(lastErrorNumber) = nil;
  4426     if ((__INST(handleType) == nil)
  4422     if ((__INST(handleType) == nil)
  4427      || (__INST(handleType) == @symbol(filePointer))
  4423      || (__INST(handleType) == @symbol(filePointer))
  4428      || (__INST(handleType) == @symbol(socketFilePointer))
  4424      || (__INST(handleType) == @symbol(socketFilePointer))
  4429      || (__INST(handleType) == @symbol(socketHandle))
  4425      || (__INST(handleType) == @symbol(socketHandle))
  4430      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4426      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4431         if (((fp = __INST(handle)) != nil)
  4427 	if (((fp = __INST(handle)) != nil)
  4432          && (__INST(mode) != @symbol(readonly))
  4428 	 && (__INST(mode) != @symbol(readonly))
  4433         ) {
  4429 	) {
  4434             FILEPOINTER f = __FILEVal(fp);
  4430 	    FILEPOINTER f = __FILEVal(fp);
  4435             int _buffered = (__INST(buffered) == true);
  4431 	    int _buffered = (__INST(buffered) == true);
  4436             int cnt;
  4432 	    int cnt;
  4437 
  4433 
  4438             if (__isSmallInteger(anIntegerOrCharacter)) {
  4434 	    if (__isSmallInteger(anIntegerOrCharacter)) {
  4439                 num = __intVal(anIntegerOrCharacter);
  4435 		num = __intVal(anIntegerOrCharacter);
  4440             } else if (__isCharacter(anIntegerOrCharacter)) {
  4436 	    } else if (__isCharacter(anIntegerOrCharacter)) {
  4441                 num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4437 		num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4442             } else
  4438 	    } else
  4443                 goto out;
  4439 		goto out;
  4444 
  4440 
  4445             if (msbFlag == true) {
  4441 	    if (msbFlag == true) {
  4446 #if defined(__MSBFIRST__)
  4442 #if defined(__MSBFIRST__)
  4447                 u.shortVal = num;
  4443 		u.shortVal = num;
  4448 #else
  4444 #else
  4449                 u.bytes[0] = (num >> 8) & 0xFF;
  4445 		u.bytes[0] = (num >> 8) & 0xFF;
  4450                 u.bytes[1] = num & 0xFF;
  4446 		u.bytes[1] = num & 0xFF;
  4451 #endif
  4447 #endif
  4452             } else {
  4448 	    } else {
  4453 #if defined(__LSBFIRST__)
  4449 #if defined(__LSBFIRST__)
  4454                 u.shortVal = num;
  4450 		u.shortVal = num;
  4455 #else
  4451 #else
  4456                 u.bytes[1] = (num >> 8) & 0xFF;
  4452 		u.bytes[1] = (num >> 8) & 0xFF;
  4457                 u.bytes[0] = num & 0xFF;
  4453 		u.bytes[0] = num & 0xFF;
  4458 #endif
  4454 #endif
  4459             }
  4455 	    }
  4460 
  4456 
  4461             if (_buffered) {
  4457 	    if (_buffered) {
  4462                 __WRITING__(f)
  4458 		__WRITING__(f)
  4463             }
  4459 	    }
  4464             __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4460 	    __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4465 
  4461 
  4466             if (cnt == 2) {
  4462 	    if (cnt == 2) {
  4467                 if (__isSmallInteger(__INST(position))) {
  4463 		if (__isSmallInteger(__INST(position))) {
  4468                     INT np = __intVal(__INST(position)) + 2;
  4464 		    INT np = __intVal(__INST(position)) + 2;
  4469                     OBJ t;
  4465 		    OBJ t;
  4470 
  4466 
  4471                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4467 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4472                 } else {
  4468 		} else {
  4473                     __INST(position) = nil; /* i.e. do not know */
  4469 		    __INST(position) = nil; /* i.e. do not know */
  4474                 }
  4470 		}
  4475                 RETURN ( self );
  4471 		RETURN ( self );
  4476             }
  4472 	    }
  4477             __INST(position) = nil; /* i.e. do not know */
  4473 	    __INST(position) = nil; /* i.e. do not know */
  4478             error = __mkSmallInteger(__threadErrno);
  4474 	    error = __mkSmallInteger(__threadErrno);
  4479         }
  4475 	}
  4480     }
  4476     }
  4481 out:;
  4477 out:;
  4482 %}.
  4478 %}.
  4483     error notNil ifTrue:[
  4479     error notNil ifTrue:[
  4484         lastErrorNumber := error.
  4480 	lastErrorNumber := error.
  4485         self writeError:error.
  4481 	self writeError:error.
  4486         ^ self
  4482 	^ self
  4487     ].
  4483     ].
  4488     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4484     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4489     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4485     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4490     self argumentMustBeInteger
  4486     self argumentMustBeInteger
  4491 
  4487 
  4515 
  4511 
  4516     |error|
  4512     |error|
  4517 %{
  4513 %{
  4518     int num;
  4514     int num;
  4519     union {
  4515     union {
  4520         char bytes[2];
  4516 	char bytes[2];
  4521         short shortVal;
  4517 	short shortVal;
  4522     } u;
  4518     } u;
  4523     OBJ fp;
  4519     OBJ fp;
  4524 
  4520 
  4525     __INST(lastErrorNumber) = nil;
  4521     __INST(lastErrorNumber) = nil;
  4526     if ((__INST(handleType) == nil)
  4522     if ((__INST(handleType) == nil)
  4527      || (__INST(handleType) == @symbol(filePointer))
  4523      || (__INST(handleType) == @symbol(filePointer))
  4528      || (__INST(handleType) == @symbol(socketFilePointer))
  4524      || (__INST(handleType) == @symbol(socketFilePointer))
  4529      || (__INST(handleType) == @symbol(socketHandle))
  4525      || (__INST(handleType) == @symbol(socketHandle))
  4530      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4526      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4531         if (((fp = __INST(handle)) != nil)
  4527 	if (((fp = __INST(handle)) != nil)
  4532          && (__INST(mode) != @symbol(readonly))
  4528 	 && (__INST(mode) != @symbol(readonly))
  4533         ) {
  4529 	) {
  4534             FILEPOINTER f = __FILEVal(fp);
  4530 	    FILEPOINTER f = __FILEVal(fp);
  4535             int _buffered = (__INST(buffered) == true);
  4531 	    int _buffered = (__INST(buffered) == true);
  4536             int cnt;
  4532 	    int cnt;
  4537 
  4533 
  4538             if (__isSmallInteger(anIntegerOrCharacter)) {
  4534 	    if (__isSmallInteger(anIntegerOrCharacter)) {
  4539                 num = __intVal(anIntegerOrCharacter);
  4535 		num = __intVal(anIntegerOrCharacter);
  4540             } else if (__isCharacter(anIntegerOrCharacter)) {
  4536 	    } else if (__isCharacter(anIntegerOrCharacter)) {
  4541                 num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4537 		num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4542             } else
  4538 	    } else
  4543                 goto out;
  4539 		goto out;
  4544 
  4540 
  4545             u.shortVal = num;
  4541 	    u.shortVal = num;
  4546 
  4542 
  4547             if (_buffered) {
  4543 	    if (_buffered) {
  4548                 __WRITING__(f)
  4544 		__WRITING__(f)
  4549             }
  4545 	    }
  4550             __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4546 	    __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4551 
  4547 
  4552             if (cnt == 2) {
  4548 	    if (cnt == 2) {
  4553                 if (__isSmallInteger(__INST(position))) {
  4549 		if (__isSmallInteger(__INST(position))) {
  4554                     INT np = __intVal(__INST(position)) + 2;
  4550 		    INT np = __intVal(__INST(position)) + 2;
  4555                     OBJ t;
  4551 		    OBJ t;
  4556 
  4552 
  4557                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4553 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4558                 } else {
  4554 		} else {
  4559                     __INST(position) = nil; /* i.e. do not know */
  4555 		    __INST(position) = nil; /* i.e. do not know */
  4560                 }
  4556 		}
  4561                 RETURN ( self );
  4557 		RETURN ( self );
  4562             }
  4558 	    }
  4563             __INST(position) = nil; /* i.e. do not know */
  4559 	    __INST(position) = nil; /* i.e. do not know */
  4564             error = __mkSmallInteger(__threadErrno);
  4560 	    error = __mkSmallInteger(__threadErrno);
  4565         }
  4561 	}
  4566     }
  4562     }
  4567 out:;
  4563 out:;
  4568 %}.
  4564 %}.
  4569     self nextPutInt16:anIntegerOrCharacter MSB:(UninterpretedBytes isBigEndian).
  4565     self nextPutInt16:anIntegerOrCharacter MSB:(UninterpretedBytes isBigEndian).
  4570 
  4566 
  4582     |error|
  4578     |error|
  4583 
  4579 
  4584 %{
  4580 %{
  4585     int num;
  4581     int num;
  4586     union {
  4582     union {
  4587         char bytes[4];
  4583 	char bytes[4];
  4588         int intVal;
  4584 	int intVal;
  4589     } u;
  4585     } u;
  4590     OBJ fp;
  4586     OBJ fp;
  4591 
  4587 
  4592     __INST(lastErrorNumber) = nil;
  4588     __INST(lastErrorNumber) = nil;
  4593     if (__isSmallInteger(aNumber)) {
  4589     if (__isSmallInteger(aNumber)) {
  4594         num = __intVal(aNumber);
  4590 	num = __intVal(aNumber);
  4595     } else {
  4591     } else {
  4596 #if __POINTER_SIZE__ == 8
  4592 #if __POINTER_SIZE__ == 8
  4597         // always more than 4-bytes
  4593 	// always more than 4-bytes
  4598         goto badArg;
  4594 	goto badArg;
  4599 #else
  4595 #else
  4600         num = __longIntVal(aNumber);
  4596 	num = __longIntVal(aNumber);
  4601         if (num == 0) {
  4597 	if (num == 0) {
  4602             num = __signedLongIntVal(aNumber);
  4598 	    num = __signedLongIntVal(aNumber);
  4603             if (num == 0) {
  4599 	    if (num == 0) {
  4604                 /* bad arg or out-of-range integer
  4600 		/* bad arg or out-of-range integer
  4605                  * (handled by the fallBack code)
  4601 		 * (handled by the fallBack code)
  4606                  */
  4602 		 */
  4607                 goto badArg;
  4603 		goto badArg;
  4608             }
  4604 	    }
  4609         }
  4605 	}
  4610 #endif
  4606 #endif
  4611     }
  4607     }
  4612 
  4608 
  4613     if ((__INST(handleType) == nil)
  4609     if ((__INST(handleType) == nil)
  4614      || (__INST(handleType) == @symbol(filePointer))
  4610      || (__INST(handleType) == @symbol(filePointer))
  4615      || (__INST(handleType) == @symbol(socketFilePointer))
  4611      || (__INST(handleType) == @symbol(socketFilePointer))
  4616      || (__INST(handleType) == @symbol(socketHandle))
  4612      || (__INST(handleType) == @symbol(socketHandle))
  4617      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4613      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4618         if (((fp = __INST(handle)) != nil)
  4614 	if (((fp = __INST(handle)) != nil)
  4619          && (__INST(mode) != @symbol(readonly))
  4615 	 && (__INST(mode) != @symbol(readonly))
  4620         ) {
  4616 	) {
  4621             int _buffered = (__INST(buffered) == true);
  4617 	    int _buffered = (__INST(buffered) == true);
  4622             FILEPOINTER f = __FILEVal(fp);
  4618 	    FILEPOINTER f = __FILEVal(fp);
  4623             int cnt;
  4619 	    int cnt;
  4624 
  4620 
  4625             if (msbFlag == true) {
  4621 	    if (msbFlag == true) {
  4626 #if defined(__MSBFIRST__)
  4622 #if defined(__MSBFIRST__)
  4627                 u.intVal = num;
  4623 		u.intVal = num;
  4628 #else
  4624 #else
  4629                 u.bytes[0] = (num >> 24) & 0xFF;
  4625 		u.bytes[0] = (num >> 24) & 0xFF;
  4630                 u.bytes[1] = (num >> 16) & 0xFF;
  4626 		u.bytes[1] = (num >> 16) & 0xFF;
  4631                 u.bytes[2] = (num >> 8) & 0xFF;
  4627 		u.bytes[2] = (num >> 8) & 0xFF;
  4632                 u.bytes[3] = num & 0xFF;
  4628 		u.bytes[3] = num & 0xFF;
  4633 #endif
  4629 #endif
  4634             } else {
  4630 	    } else {
  4635 #if defined(__LSBFIRST__)
  4631 #if defined(__LSBFIRST__)
  4636                 u.intVal = num;
  4632 		u.intVal = num;
  4637 #else
  4633 #else
  4638                 u.bytes[3] = (num >> 24) & 0xFF;
  4634 		u.bytes[3] = (num >> 24) & 0xFF;
  4639                 u.bytes[2] = (num >> 16) & 0xFF;
  4635 		u.bytes[2] = (num >> 16) & 0xFF;
  4640                 u.bytes[1] = (num >> 8) & 0xFF;
  4636 		u.bytes[1] = (num >> 8) & 0xFF;
  4641                 u.bytes[0] = num & 0xFF;
  4637 		u.bytes[0] = num & 0xFF;
  4642 #endif
  4638 #endif
  4643             }
  4639 	    }
  4644 
  4640 
  4645             if (_buffered) {
  4641 	    if (_buffered) {
  4646                 __WRITING__(f)
  4642 		__WRITING__(f)
  4647             }
  4643 	    }
  4648             __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
  4644 	    __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
  4649 
  4645 
  4650             if (cnt == 4) {
  4646 	    if (cnt == 4) {
  4651                 if (__isSmallInteger(__INST(position))) {
  4647 		if (__isSmallInteger(__INST(position))) {
  4652                     INT np = __intVal(__INST(position)) + 4;
  4648 		    INT np = __intVal(__INST(position)) + 4;
  4653                     OBJ t;
  4649 		    OBJ t;
  4654 
  4650 
  4655                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4651 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4656                 } else {
  4652 		} else {
  4657                     __INST(position) = nil; /* i.e. do not know */
  4653 		    __INST(position) = nil; /* i.e. do not know */
  4658                 }
  4654 		}
  4659                 RETURN ( self );
  4655 		RETURN ( self );
  4660             }
  4656 	    }
  4661             __INST(position) = nil; /* i.e. do not know */
  4657 	    __INST(position) = nil; /* i.e. do not know */
  4662             error = __mkSmallInteger(__threadErrno);
  4658 	    error = __mkSmallInteger(__threadErrno);
  4663         }
  4659 	}
  4664     }
  4660     }
  4665 badArg: ;
  4661 badArg: ;
  4666 %}.
  4662 %}.
  4667     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4663     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4668     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4664     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4669     error notNil ifTrue:[
  4665     error notNil ifTrue:[
  4670         lastErrorNumber := error.
  4666 	lastErrorNumber := error.
  4671         self writeError:error.
  4667 	self writeError:error.
  4672         ^ self
  4668 	^ self
  4673     ].
  4669     ].
  4674 
  4670 
  4675     aNumber isInteger ifTrue:[
  4671     aNumber isInteger ifTrue:[
  4676         ^ super nextPutInt32:aNumber MSB:msbFlag
  4672 	^ super nextPutInt32:aNumber MSB:msbFlag
  4677     ].
  4673     ].
  4678     self argumentMustBeInteger
  4674     self argumentMustBeInteger
  4679 
  4675 
  4680     "Modified: / 19-09-2017 / 16:32:50 / stefan"
  4676     "Modified: / 19-09-2017 / 16:32:50 / stefan"
  4681 !
  4677 !
  4699      This is the CPU-specific byte order (LSB on x86, MSB on sparc, VAX and possibly on ARM).
  4695      This is the CPU-specific byte order (LSB on x86, MSB on sparc, VAX and possibly on ARM).
  4700      Notice that integers in the range 16r-80000000 to +16rFFFFFFFF can be written
  4696      Notice that integers in the range 16r-80000000 to +16rFFFFFFFF can be written
  4701      (i.e. both signed and unsigned int32 values can be written.
  4697      (i.e. both signed and unsigned int32 values can be written.
  4702      Works in both binary and text modes.
  4698      Works in both binary and text modes.
  4703      Notice: this message should not be sent explicitly by ANY program.
  4699      Notice: this message should not be sent explicitly by ANY program.
  4704              the following implementation replaces the code of either nextPutInt32MSB or LSB
  4700 	     the following implementation replaces the code of either nextPutInt32MSB or LSB
  4705              dynamically (see #initialize on the class side)"
  4701 	     dynamically (see #initialize on the class side)"
  4706 
  4702 
  4707     |error|
  4703     |error|
  4708 
  4704 
  4709 %{
  4705 %{
  4710     int num;
  4706     int num;
  4711     union {
  4707     union {
  4712         char bytes[4];
  4708 	char bytes[4];
  4713         int intVal;
  4709 	int intVal;
  4714     } u;
  4710     } u;
  4715     OBJ fp;
  4711     OBJ fp;
  4716 
  4712 
  4717     __INST(lastErrorNumber) = nil;
  4713     __INST(lastErrorNumber) = nil;
  4718     if (__isSmallInteger(anInteger)) {
  4714     if (__isSmallInteger(anInteger)) {
  4719         num = __intVal(anInteger);
  4715 	num = __intVal(anInteger);
  4720     } else {
  4716     } else {
  4721 #if __POINTER_SIZE__ == 8
  4717 #if __POINTER_SIZE__ == 8
  4722         // always more than 4-bytes
  4718 	// always more than 4-bytes
  4723         goto badArg;
  4719 	goto badArg;
  4724 #else
  4720 #else
  4725         num = __longIntVal(anInteger);
  4721 	num = __longIntVal(anInteger);
  4726         if (num == 0) {
  4722 	if (num == 0) {
  4727             num = __signedLongIntVal(anInteger);
  4723 	    num = __signedLongIntVal(anInteger);
  4728             if (num == 0) {
  4724 	    if (num == 0) {
  4729                 /* bad arg or out-of-range integer
  4725 		/* bad arg or out-of-range integer
  4730                  * (handled by the fallBack code)
  4726 		 * (handled by the fallBack code)
  4731                  */
  4727 		 */
  4732                 goto badArg;
  4728 		goto badArg;
  4733             }
  4729 	    }
  4734         }
  4730 	}
  4735 #endif
  4731 #endif
  4736     }
  4732     }
  4737 
  4733 
  4738     if ((__INST(handleType) == nil)
  4734     if ((__INST(handleType) == nil)
  4739      || (__INST(handleType) == @symbol(filePointer))
  4735      || (__INST(handleType) == @symbol(filePointer))
  4740      || (__INST(handleType) == @symbol(socketFilePointer))
  4736      || (__INST(handleType) == @symbol(socketFilePointer))
  4741      || (__INST(handleType) == @symbol(socketHandle))
  4737      || (__INST(handleType) == @symbol(socketHandle))
  4742      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4738      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4743         if (((fp = __INST(handle)) != nil)
  4739 	if (((fp = __INST(handle)) != nil)
  4744          && (__INST(mode) != @symbol(readonly))
  4740 	 && (__INST(mode) != @symbol(readonly))
  4745         ) {
  4741 	) {
  4746             int _buffered = (__INST(buffered) == true);
  4742 	    int _buffered = (__INST(buffered) == true);
  4747             FILEPOINTER f = __FILEVal(fp);
  4743 	    FILEPOINTER f = __FILEVal(fp);
  4748             int cnt;
  4744 	    int cnt;
  4749 
  4745 
  4750             u.intVal = num;
  4746 	    u.intVal = num;
  4751             if (_buffered) {
  4747 	    if (_buffered) {
  4752                 __WRITING__(f)
  4748 		__WRITING__(f)
  4753             }
  4749 	    }
  4754             __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
  4750 	    __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
  4755 
  4751 
  4756             if (cnt == 4) {
  4752 	    if (cnt == 4) {
  4757                 if (__isSmallInteger(__INST(position))) {
  4753 		if (__isSmallInteger(__INST(position))) {
  4758                     INT np = __intVal(__INST(position)) + 4;
  4754 		    INT np = __intVal(__INST(position)) + 4;
  4759                     OBJ t;
  4755 		    OBJ t;
  4760 
  4756 
  4761                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4757 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4762                 } else {
  4758 		} else {
  4763                     __INST(position) = nil; /* i.e. do not know */
  4759 		    __INST(position) = nil; /* i.e. do not know */
  4764                 }
  4760 		}
  4765                 RETURN ( self );
  4761 		RETURN ( self );
  4766             }
  4762 	    }
  4767             __INST(position) = nil; /* i.e. do not know */
  4763 	    __INST(position) = nil; /* i.e. do not know */
  4768             error = __mkSmallInteger(__threadErrno);
  4764 	    error = __mkSmallInteger(__threadErrno);
  4769         }
  4765 	}
  4770     }
  4766     }
  4771 badArg: ;
  4767 badArg: ;
  4772 %}.
  4768 %}.
  4773     self nextPutInt32:anInteger MSB:(UninterpretedBytes isBigEndian)
  4769     self nextPutInt32:anInteger MSB:(UninterpretedBytes isBigEndian)
  4774 
  4770 
  4780      UTF-16 can encode only characters with code points between 0 to 16r10FFFF."
  4776      UTF-16 can encode only characters with code points between 0 to 16r10FFFF."
  4781 
  4777 
  4782     self nextPutUtf16Bytes:aCharacter MSB:true
  4778     self nextPutUtf16Bytes:aCharacter MSB:true
  4783 
  4779 
  4784     "
  4780     "
  4785         (FileStream newTemporary
  4781 	(FileStream newTemporary
  4786             nextPutUtf16:$B;
  4782 	    nextPutUtf16:$B;
  4787             nextPutUtf16:$Ă„;
  4783 	    nextPutUtf16:$Ă„;
  4788             nextPutUtf16:(Character codePoint:16r10CCCC);
  4784 	    nextPutUtf16:(Character codePoint:16r10CCCC);
  4789             reset;
  4785 	    reset;
  4790             binary;
  4786 	    binary;
  4791             contents)
  4787 	    contents)
  4792     "
  4788     "
  4793 !
  4789 !
  4794 
  4790 
  4795 nextPutUtf16:aCharacter MSB:msbFlag
  4791 nextPutUtf16:aCharacter MSB:msbFlag
  4796     "append my UTF-16 MSB representation to the argument, aStream.
  4792     "append my UTF-16 MSB representation to the argument, aStream.
  4811 
  4807 
  4812 !ExternalStream methodsFor:'printing & storing'!
  4808 !ExternalStream methodsFor:'printing & storing'!
  4813 
  4809 
  4814 printOn:aStream
  4810 printOn:aStream
  4815     aStream
  4811     aStream
  4816         nextPutAll:self className;
  4812 	nextPutAll:self className;
  4817         nextPut:$(.
  4813 	nextPut:$(.
  4818     handleType printOn:aStream.
  4814     handleType printOn:aStream.
  4819     aStream nextPutAll:':('.
  4815     aStream nextPutAll:':('.
  4820     handle printOn:aStream.
  4816     handle printOn:aStream.
  4821     aStream nextPutAll:'))'
  4817     aStream nextPutAll:'))'
  4822 ! !
  4818 ! !
  4832      Don't send this message, send #close instead"
  4828      Don't send this message, send #close instead"
  4833 
  4829 
  4834     |fp error|
  4830     |fp error|
  4835 
  4831 
  4836     handle isNil ifTrue:[
  4832     handle isNil ifTrue:[
  4837         ^ self.
  4833 	^ self.
  4838     ].
  4834     ].
  4839     fp := handle.
  4835     fp := handle.
  4840     "/ (didWrite==true and:[binary ~~ true and:[eolMode = #crlf]]) ifTrue: [ self breakPoint:#sr ].
  4836     "/ (didWrite==true and:[binary ~~ true and:[eolMode = #crlf]]) ifTrue: [ self breakPoint:#sr ].
  4841 
  4837 
  4842 %{
  4838 %{
  4843     int rslt;
  4839     int rslt;
  4844 
  4840 
  4845     if (__INST(handleType) == @symbol(socketHandle)) {
  4841     if (__INST(handleType) == @symbol(socketHandle)) {
  4846         SOCKET sock = (SOCKET)(__FILEVal(fp));
  4842 	SOCKET sock = (SOCKET)(__FILEVal(fp));
  4847 
  4843 
  4848         if (@global(FileOpenTrace) == true) {
  4844 	if (@global(FileOpenTrace) == true) {
  4849             fprintf(stderr, "close socket [ExternalStream] %"_lx_"\n", (INT)sock);
  4845 	    fprintf(stderr, "close socket [ExternalStream] %"_lx_"\n", (INT)sock);
  4850         }
  4846 	}
  4851 
  4847 
  4852         // whether the close() will be successful or not - the handle is invalid now!
  4848 	// whether the close() will be successful or not - the handle is invalid now!
  4853         __INST(handle) = nil;
  4849 	__INST(handle) = nil;
  4854         do {
  4850 	do {
  4855 #ifdef __win32__
  4851 #ifdef __win32__
  4856             rslt = __STX_WSA_NOINT_CALL1("closesocket", closesocket, sock);
  4852 	    rslt = __STX_WSA_NOINT_CALL1("closesocket", closesocket, sock);
  4857 #else
  4853 #else
  4858             rslt = close(sock);
  4854 	    rslt = close(sock);
  4859 #endif
  4855 #endif
  4860         } while((rslt < 0) && (__threadErrno == EINTR));
  4856 	} while((rslt < 0) && (__threadErrno == EINTR));
  4861     } else if ((__INST(handleType) == nil)
  4857     } else if ((__INST(handleType) == nil)
  4862                || (__INST(handleType) == @symbol(filePointer))
  4858 	       || (__INST(handleType) == @symbol(filePointer))
  4863                || (__INST(handleType) == @symbol(socketFilePointer))
  4859 	       || (__INST(handleType) == @symbol(socketFilePointer))
  4864                || (__INST(handleType) == @symbol(pipeFilePointer)))
  4860 	       || (__INST(handleType) == @symbol(pipeFilePointer)))
  4865     {
  4861     {
  4866         FILEPOINTER f = __FILEVal(fp);
  4862 	FILEPOINTER f = __FILEVal(fp);
  4867 
  4863 
  4868         if (@global(FileOpenTrace) == true) {
  4864 	if (@global(FileOpenTrace) == true) {
  4869             fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", (INT)f);
  4865 	    fprintf(stderr, "fclose [ExternalStream] %"_lx_"\n", (INT)f);
  4870         }
  4866 	}
  4871         // whether the close() will be successful or not - the handle is invalid now!
  4867 	// whether the close() will be successful or not - the handle is invalid now!
  4872         __INST(handle) = nil;
  4868 	__INST(handle) = nil;
  4873 
  4869 
  4874 #ifdef __win32__
  4870 #ifdef __win32__
  4875         if (__INST(mode) != @symbol(readonly) && __INST(buffered) != false) {
  4871 	if (__INST(mode) != @symbol(readonly) && __INST(buffered) != false) {
  4876             // do a fflush() first, so that fclose() doesn't block
  4872 	    // do a fflush() first, so that fclose() doesn't block
  4877             // we suspect, that EINTR causes problems in fclose()
  4873 	    // we suspect, that EINTR causes problems in fclose()
  4878             do {
  4874 	    do {
  4879                 __threadErrno = 0;
  4875 		__threadErrno = 0;
  4880                 rslt = __STX_C_CALL1("fflush", fflush, f);
  4876 		rslt = __STX_C_CALL1("fflush", fflush, f);
  4881             } while((rslt < 0) && (__threadErrno == EINTR));
  4877 	    } while((rslt < 0) && (__threadErrno == EINTR));
  4882         }
  4878 	}
  4883         do {
  4879 	do {
  4884             __threadErrno = 0;
  4880 	    __threadErrno = 0;
  4885             rslt = __STX_C_NOINT_CALL1("fclose", fclose, f);
  4881 	    rslt = __STX_C_NOINT_CALL1("fclose", fclose, f);
  4886         } while((rslt < 0) && (__threadErrno == EINTR));
  4882 	} while((rslt < 0) && (__threadErrno == EINTR));
  4887 #else
  4883 #else
  4888         // cg: not sure why, but on osx, I get blocked occasionally in fclose
  4884 	// cg: not sure why, but on osx, I get blocked occasionally in fclose
  4889         // lets try this:
  4885 	// lets try this:
  4890         if ((__INST(mode) != @symbol(readonly)) && (__INST(buffered) != false)) {
  4886 	if ((__INST(mode) != @symbol(readonly)) && (__INST(buffered) != false)) {
  4891             // do a fflush() first, so that fclose() doesn't block
  4887 	    // do a fflush() first, so that fclose() doesn't block
  4892             // we suspect, that EINTR causes problems in fclose()
  4888 	    // we suspect, that EINTR causes problems in fclose()
  4893             do {
  4889 	    do {
  4894                 clearerr(f);
  4890 		clearerr(f);
  4895                 __threadErrno = 0;
  4891 		__threadErrno = 0;
  4896                 __BEGIN_INTERRUPTABLE__
  4892 		__BEGIN_INTERRUPTABLE__
  4897                 rslt = fflush(f);
  4893 		rslt = fflush(f);
  4898                 __END_INTERRUPTABLE__
  4894 		__END_INTERRUPTABLE__
  4899             } while((rslt < 0) && (__threadErrno == EINTR));
  4895 	    } while((rslt < 0) && (__threadErrno == EINTR));
  4900         }
  4896 	}
  4901         do {
  4897 	do {
  4902             __threadErrno = 0;
  4898 	    __threadErrno = 0;
  4903             __BEGIN_INTERRUPTABLE__
  4899 	    __BEGIN_INTERRUPTABLE__
  4904             rslt = fclose(f);
  4900 	    rslt = fclose(f);
  4905             __END_INTERRUPTABLE__
  4901 	    __END_INTERRUPTABLE__
  4906         } while((rslt < 0) && (__threadErrno == EINTR));
  4902 	} while((rslt < 0) && (__threadErrno == EINTR));
  4907 #endif
  4903 #endif
  4908     } else {
  4904     } else {
  4909         error = @symbol(badHandleType);
  4905 	error = @symbol(badHandleType);
  4910         goto out;
  4906 	goto out;
  4911     }
  4907     }
  4912 
  4908 
  4913     if (rslt < 0) {
  4909     if (rslt < 0) {
  4914         error = __mkSmallInteger(__threadErrno);
  4910 	error = __mkSmallInteger(__threadErrno);
  4915         goto out;
  4911 	goto out;
  4916     }
  4912     }
  4917     RETURN (self);
  4913     RETURN (self);
  4918 
  4914 
  4919 out:;
  4915 out:;
  4920 %}.
  4916 %}.
  4921 
  4917 
  4922     error notNil ifTrue:[
  4918     error notNil ifTrue:[
  4923         error isInteger ifTrue:[
  4919 	error isInteger ifTrue:[
  4924             lastErrorNumber := error.
  4920 	    lastErrorNumber := error.
  4925             mode == #readonly ifTrue:[
  4921 	    mode == #readonly ifTrue:[
  4926                 self ioError:error.
  4922 		self ioError:error.
  4927             ] ifFalse:[
  4923 	    ] ifFalse:[
  4928                 self writeError:error.
  4924 		self writeError:error.
  4929             ].
  4925 	    ].
  4930             ^ self.
  4926 	    ^ self.
  4931         ].
  4927 	].
  4932         self primitiveFailed:error.
  4928 	self primitiveFailed:error.
  4933         ^ self.
  4929 	^ self.
  4934     ].
  4930     ].
  4935 
  4931 
  4936     "/ fallback for rel5
  4932     "/ fallback for rel5
  4937 
  4933 
  4938     fp := handle.
  4934     fp := handle.
  4939     fp notNil ifTrue:[
  4935     fp notNil ifTrue:[
  4940         handle := nil.
  4936 	handle := nil.
  4941         self closeFile:fp
  4937 	self closeFile:fp
  4942     ]
  4938     ]
  4943 
  4939 
  4944     "Modified: / 19-04-2018 / 10:57:54 / stefan"
  4940     "Modified: / 19-04-2018 / 10:57:54 / stefan"
  4945 !
  4941 !
  4946 
  4942 
  4969     FILE *fdopen();
  4965     FILE *fdopen();
  4970     int fd = -2;
  4966     int fd = -2;
  4971 
  4967 
  4972     if (__isStringLike(openmode)) {
  4968     if (__isStringLike(openmode)) {
  4973 #ifdef __win32__
  4969 #ifdef __win32__
  4974         __stxWrapApiEnterCritical();
  4970 	__stxWrapApiEnterCritical();
  4975 #endif
  4971 #endif
  4976         if (__isSmallInteger(aFileDescriptor)) {
  4972 	if (__isSmallInteger(aFileDescriptor)) {
  4977             fd = __intVal(aFileDescriptor);
  4973 	    fd = __intVal(aFileDescriptor);
  4978         }
  4974 	}
  4979 #ifdef __win32__
  4975 #ifdef __win32__
  4980         else if (__isExternalAddressLike(aFileDescriptor)) {
  4976 	else if (__isExternalAddressLike(aFileDescriptor)) {
  4981             fd = _open_osfhandle((long)__externalAddressVal(aFileDescriptor), O_BINARY);
  4977 	    fd = _open_osfhandle((long)__externalAddressVal(aFileDescriptor), O_BINARY);
  4982             if (fd < 0) {
  4978 	    if (fd < 0) {
  4983                 if (__threadErrno == 0) {
  4979 		if (__threadErrno == 0) {
  4984                     // no more file descriptors
  4980 		    // no more file descriptors
  4985                     __threadErrno = EMFILE;
  4981 		    __threadErrno = EMFILE;
  4986                 }
  4982 		}
  4987                 error = __mkSmallInteger(__threadErrno);
  4983 		error = __mkSmallInteger(__threadErrno);
  4988                 __stxWrapApiLeaveCritical();
  4984 		__stxWrapApiLeaveCritical();
  4989                 goto out;
  4985 		goto out;
  4990             }
  4986 	    }
  4991         }
  4987 	}
  4992 #endif
  4988 #endif
  4993         f = (FILEPOINTER) fdopen(fd, (char *)__stringVal(openmode));
  4989 	f = (FILEPOINTER) fdopen(fd, (char *)__stringVal(openmode));
  4994 #ifdef __win32__
  4990 #ifdef __win32__
  4995         __stxWrapApiLeaveCritical();
  4991 	__stxWrapApiLeaveCritical();
  4996 #endif
  4992 #endif
  4997         if (f == NULL) {
  4993 	if (f == NULL) {
  4998             error =__mkSmallInteger(__threadErrno);
  4994 	    error =__mkSmallInteger(__threadErrno);
  4999         } else {
  4995 	} else {
  5000             if (@global(FileOpenTrace) == true) {
  4996 	    if (@global(FileOpenTrace) == true) {
  5001                 fprintf(stderr, "fdopen [ExternalStream] %"_ld_" (%"_lx_") -> %"_lx_"\n", (INT)fd, (INT)fd, (INT)f);
  4997 		fprintf(stderr, "fdopen [ExternalStream] %"_ld_" (%"_lx_") -> %"_lx_"\n", (INT)fd, (INT)fd, (INT)f);
  5002             }
  4998 	    }
  5003 
  4999 
  5004             fp = __MKFILEPOINTER(f); __INST(handle) = fp; __STORE(self, fp);
  5000 	    fp = __MKFILEPOINTER(f); __INST(handle) = fp; __STORE(self, fp);
  5005         }
  5001 	}
  5006     }
  5002     }
  5007 out:;
  5003 out:;
  5008 %}.
  5004 %}.
  5009     error notNil ifTrue:[
  5005     error notNil ifTrue:[
  5010         "
  5006 	"
  5011          the open failed for some reason ...
  5007 	 the open failed for some reason ...
  5012         "
  5008 	"
  5013         OperatingSystem closeFd:aFileDescriptor.
  5009 	OperatingSystem closeFd:aFileDescriptor.
  5014         lastErrorNumber := error.
  5010 	lastErrorNumber := error.
  5015         position := nil.
  5011 	position := nil.
  5016         ^ self openError:error
  5012 	^ self openError:error
  5017     ].
  5013     ].
  5018 
  5014 
  5019     position := 0.
  5015     position := 0.
  5020     buffered isNil ifTrue:[
  5016     buffered isNil ifTrue:[
  5021         buffered := true.       "default is buffered"
  5017 	buffered := true.       "default is buffered"
  5022     ].
  5018     ].
  5023     handleType := handleTypeSymbol.
  5019     handleType := handleTypeSymbol.
  5024     self registerForFinalization.
  5020     self registerForFinalization.
  5025 !
  5021 !
  5026 
  5022 
  5029 
  5025 
  5030     |fd dupFd|
  5026     |fd dupFd|
  5031 
  5027 
  5032     fd := self fileHandle.
  5028     fd := self fileHandle.
  5033     fd isNil ifTrue:[
  5029     fd isNil ifTrue:[
  5034         ^ self errorNotOpen.
  5030 	^ self errorNotOpen.
  5035     ].
  5031     ].
  5036     dupFd := OperatingSystem dup:fd.
  5032     dupFd := OperatingSystem dup:fd.
  5037     self setFileHandle:dupFd mode:self fopenMode.
  5033     self setFileHandle:dupFd mode:self fopenMode.
  5038 !
  5034 !
  5039 
  5035 
  5040 fopenMode
  5036 fopenMode
  5041    "answer the mode for fopen.
  5037    "answer the mode for fopen.
  5042     Only used internally"
  5038     Only used internally"
  5043 
  5039 
  5044    mode == #readonly ifTrue:[
  5040    mode == #readonly ifTrue:[
  5045         ^ ReadMode
  5041 	^ ReadMode
  5046    ].
  5042    ].
  5047    mode == #writeonly ifTrue:[
  5043    mode == #writeonly ifTrue:[
  5048         ^ WriteMode
  5044 	^ WriteMode
  5049    ].
  5045    ].
  5050    mode == #readWrite ifTrue:[
  5046    mode == #readWrite ifTrue:[
  5051         ^ ReadWriteMode
  5047 	^ ReadWriteMode
  5052    ].
  5048    ].
  5053    mode == #append ifTrue:[
  5049    mode == #append ifTrue:[
  5054         ^ AppendMode
  5050 	^ AppendMode
  5055    ].
  5051    ].
  5056    ^ ReadWriteMode
  5052    ^ ReadWriteMode
  5057 !
  5053 !
  5058 
  5054 
  5059 open:aPath withMode:openModeString
  5055 open:aPath withMode:openModeString
  5070     if (__isStringLike(aPath) && __isStringLike(openModeString)) {
  5066     if (__isStringLike(aPath) && __isStringLike(openModeString)) {
  5071 #ifdef __win32__
  5067 #ifdef __win32__
  5072 # if 1
  5068 # if 1
  5073        f = fopen((char *) __stringVal(aPath), (char *) __stringVal(openModeString));
  5069        f = fopen((char *) __stringVal(aPath), (char *) __stringVal(openModeString));
  5074 # else
  5070 # else
  5075         __BEGIN_INTERRUPTABLE__
  5071 	__BEGIN_INTERRUPTABLE__
  5076         do {
  5072 	do {
  5077             f = fopen((char *) __stringVal(aPath), (char *) __stringVal(openModeString));
  5073 	    f = fopen((char *) __stringVal(aPath), (char *) __stringVal(openModeString));
  5078         } while ((f == NULL) && (__threadErrno == EINTR));
  5074 	} while ((f == NULL) && (__threadErrno == EINTR));
  5079         __END_INTERRUPTABLE__
  5075 	__END_INTERRUPTABLE__
  5080 # endif
  5076 # endif
  5081 #else /* UNIX */
  5077 #else /* UNIX */
  5082         __BEGIN_INTERRUPTABLE__
  5078 	__BEGIN_INTERRUPTABLE__
  5083         do {
  5079 	do {
  5084             f = fopen((char *) __stringVal(aPath), (char *) __stringVal(openModeString));
  5080 	    f = fopen((char *) __stringVal(aPath), (char *) __stringVal(openModeString));
  5085         } while ((f == NULL) && (__threadErrno == EINTR));
  5081 	} while ((f == NULL) && (__threadErrno == EINTR));
  5086         __END_INTERRUPTABLE__
  5082 	__END_INTERRUPTABLE__
  5087 #endif /* UNIX */
  5083 #endif /* UNIX */
  5088         if (f == NULL) {
  5084 	if (f == NULL) {
  5089             error = __mkSmallInteger(__threadErrno);
  5085 	    error = __mkSmallInteger(__threadErrno);
  5090         } else {
  5086 	} else {
  5091             if (@global(FileOpenTrace) == true) {
  5087 	    if (@global(FileOpenTrace) == true) {
  5092                 fprintf(stderr, "fopen %s [ExternalStream] -> %"_lx_"\n", __stringVal(aPath), (INT)f);
  5088 		fprintf(stderr, "fopen %s [ExternalStream] -> %"_lx_"\n", __stringVal(aPath), (INT)f);
  5093             }
  5089 	    }
  5094             fp = __MKFILEPOINTER(f); __INST(handle) = fp; __STORE(self, fp);
  5090 	    fp = __MKFILEPOINTER(f); __INST(handle) = fp; __STORE(self, fp);
  5095             __INST(handleType) = @symbol(filePointer);
  5091 	    __INST(handleType) = @symbol(filePointer);
  5096             ok = true;
  5092 	    ok = true;
  5097         }
  5093 	}
  5098     }
  5094     }
  5099 %}.
  5095 %}.
  5100     ok ifTrue:[
  5096     ok ifTrue:[
  5101         position := 0.
  5097 	position := 0.
  5102         self registerForFinalization.
  5098 	self registerForFinalization.
  5103         ^ self.
  5099 	^ self.
  5104     ].
  5100     ].
  5105     error notNil ifTrue:[
  5101     error notNil ifTrue:[
  5106         "
  5102 	"
  5107          the open failed for some reason ...
  5103 	 the open failed for some reason ...
  5108         "
  5104 	"
  5109         lastErrorNumber := error.
  5105 	lastErrorNumber := error.
  5110         self openError:error.
  5106 	self openError:error.
  5111     ].
  5107     ].
  5112     self primitiveFailed.
  5108     self primitiveFailed.
  5113 !
  5109 !
  5114 
  5110 
  5115 reOpen
  5111 reOpen
  5152     OBJ fp;
  5148     OBJ fp;
  5153     FILE *fdopen();
  5149     FILE *fdopen();
  5154     int fd;
  5150     int fd;
  5155 
  5151 
  5156     if (!__isStringLike(openMode))
  5152     if (!__isStringLike(openMode))
  5157         goto err;
  5153 	goto err;
  5158 
  5154 
  5159 #ifdef __win32__
  5155 #ifdef __win32__
  5160     __stxWrapApiEnterCritical();
  5156     __stxWrapApiEnterCritical();
  5161     if (__isExternalAddressLike(anIntegerOrExternalAddress) ) {
  5157     if (__isExternalAddressLike(anIntegerOrExternalAddress) ) {
  5162         HANDLE __fileHandle = (HANDLE)__externalAddressVal(anIntegerOrExternalAddress);
  5158 	HANDLE __fileHandle = (HANDLE)__externalAddressVal(anIntegerOrExternalAddress);
  5163         fd = _open_osfhandle((long)__fileHandle, O_BINARY);      /* should we handle readonly, append or text mode? */
  5159 	fd = _open_osfhandle((long)__fileHandle, O_BINARY);      /* should we handle readonly, append or text mode? */
  5164         if (fd < 0) {
  5160 	if (fd < 0) {
  5165             __stxWrapApiLeaveCritical();
  5161 	    __stxWrapApiLeaveCritical();
  5166             CloseHandle(__fileHandle);
  5162 	    CloseHandle(__fileHandle);
  5167             goto err;
  5163 	    goto err;
  5168         }
  5164 	}
  5169     } else
  5165     } else
  5170 #endif
  5166 #endif
  5171     if (__isSmallInteger(anIntegerOrExternalAddress)) {
  5167     if (__isSmallInteger(anIntegerOrExternalAddress)) {
  5172         fd = __smallIntegerVal(anIntegerOrExternalAddress);
  5168 	fd = __smallIntegerVal(anIntegerOrExternalAddress);
  5173     } else {
  5169     } else {
  5174 #ifdef __win32__
  5170 #ifdef __win32__
  5175         __stxWrapApiLeaveCritical();
  5171 	__stxWrapApiLeaveCritical();
  5176 #endif
  5172 #endif
  5177         goto err;
  5173 	goto err;
  5178     }
  5174     }
  5179     f = fdopen(fd, __stringVal(openMode));
  5175     f = fdopen(fd, __stringVal(openMode));
  5180 #ifdef __win32__
  5176 #ifdef __win32__
  5181     __stxWrapApiLeaveCritical();
  5177     __stxWrapApiLeaveCritical();
  5182 #endif
  5178 #endif
  5183     if (f != NULL) {
  5179     if (f != NULL) {
  5184         if (@global(FileOpenTrace) == true) {
  5180 	if (@global(FileOpenTrace) == true) {
  5185             fprintf(stderr, "fdopen [ExternalStream] %d -> %"_lx_"\n", fd, (INT)f);
  5181 	    fprintf(stderr, "fdopen [ExternalStream] %d -> %"_lx_"\n", fd, (INT)f);
  5186         }
  5182 	}
  5187         fp = __MKFILEPOINTER(f); __INST(handle) = fp; __STORE(self, fp);
  5183 	fp = __MKFILEPOINTER(f); __INST(handle) = fp; __STORE(self, fp);
  5188         __INST(handleType) = @symbol(filePointer);
  5184 	__INST(handleType) = @symbol(filePointer);
  5189         RETURN (self);
  5185 	RETURN (self);
  5190     }
  5186     }
  5191 err:;
  5187 err:;
  5192 %}.
  5188 %}.
  5193     ^ self primitiveFailed
  5189     ^ self primitiveFailed
  5194 !
  5190 !
  5230     if ((__INST(handleType) == nil)
  5226     if ((__INST(handleType) == nil)
  5231      || (__INST(handleType) == @symbol(filePointer))
  5227      || (__INST(handleType) == @symbol(filePointer))
  5232      || (__INST(handleType) == @symbol(socketFilePointer))
  5228      || (__INST(handleType) == @symbol(socketFilePointer))
  5233      || (__INST(handleType) == @symbol(socketHandle))
  5229      || (__INST(handleType) == @symbol(socketHandle))
  5234      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5230      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5235         if (((fp = __INST(handle)) != nil)
  5231 	if (((fp = __INST(handle)) != nil)
  5236             && (__INST(mode) != @symbol(writeonly))
  5232 	    && (__INST(mode) != @symbol(writeonly))
  5237         ) {
  5233 	) {
  5238             f = __FILEVal(fp);
  5234 	    f = __FILEVal(fp);
  5239 
  5235 
  5240             _buffered = (__INST(buffered) == true);
  5236 	    _buffered = (__INST(buffered) == true);
  5241             if (_buffered) {
  5237 	    if (_buffered) {
  5242                 __READING__(f)
  5238 		__READING__(f)
  5243             }
  5239 	    }
  5244             __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5240 	    __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5245 
  5241 
  5246             if (ret > 0) {
  5242 	    if (ret > 0) {
  5247                 RETURN(nil)
  5243 		RETURN(nil)
  5248             }
  5244 	    }
  5249             if (ret < 0) {
  5245 	    if (ret < 0) {
  5250                 RETURN(__mkSmallInteger(__threadErrno));
  5246 		RETURN(__mkSmallInteger(__threadErrno));
  5251             } else /* ret == 0 */ {
  5247 	    } else /* ret == 0 */ {
  5252                 RETURN(__mkSmallInteger(0)); /* EOF */
  5248 		RETURN(__mkSmallInteger(0)); /* EOF */
  5253             }
  5249 	    }
  5254         }
  5250 	}
  5255     }
  5251     }
  5256 %}.
  5252 %}.
  5257 !
  5253 !
  5258 
  5254 
  5259 numAvailable
  5255 numAvailable
  5273 %{
  5269 %{
  5274 #ifdef __SCHTEAM__
  5270 #ifdef __SCHTEAM__
  5275     STObject handle = self.instVarAt(I_handle);
  5271     STObject handle = self.instVarAt(I_handle);
  5276 
  5272 
  5277     if (handle != STObject.Nil) {
  5273     if (handle != STObject.Nil) {
  5278         STObject next;
  5274 	STObject next;
  5279 
  5275 
  5280         if (self.instVarAt(I_binary) == STObject.True) {
  5276 	if (self.instVarAt(I_binary) == STObject.True) {
  5281             next = handle.nextByte();
  5277 	    next = handle.nextByte();
  5282         } else {
  5278 	} else {
  5283             next = handle.nextChar();
  5279 	    next = handle.nextChar();
  5284         }
  5280 	}
  5285         if (next != STObject.EOF) {
  5281 	if (next != STObject.EOF) {
  5286             self.instVarAt_put(I_position, STObject.Nil);
  5282 	    self.instVarAt_put(I_position, STObject.Nil);
  5287             return __c__._RETURN( next );
  5283 	    return __c__._RETURN( next );
  5288         }
  5284 	}
  5289         self.instVarAt_put(I_hitEOF, STObject.True);
  5285 	self.instVarAt_put(I_hitEOF, STObject.True);
  5290     }
  5286     }
  5291 #else
  5287 #else
  5292     FILEPOINTER f;
  5288     FILEPOINTER f;
  5293     int ret, _buffered;
  5289     int ret, _buffered;
  5294     OBJ pos, fp;
  5290     OBJ pos, fp;
  5298     if ((__INST(handleType) == nil)
  5294     if ((__INST(handleType) == nil)
  5299      || (__INST(handleType) == @symbol(filePointer))
  5295      || (__INST(handleType) == @symbol(filePointer))
  5300      || (__INST(handleType) == @symbol(socketFilePointer))
  5296      || (__INST(handleType) == @symbol(socketFilePointer))
  5301      || (__INST(handleType) == @symbol(socketHandle))
  5297      || (__INST(handleType) == @symbol(socketHandle))
  5302      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5298      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5303         if (((fp = __INST(handle)) != nil)
  5299 	if (((fp = __INST(handle)) != nil)
  5304             && (__INST(mode) != @symbol(writeonly))
  5300 	    && (__INST(mode) != @symbol(writeonly))
  5305         ) {
  5301 	) {
  5306             f = __FILEVal(fp);
  5302 	    f = __FILEVal(fp);
  5307 
  5303 
  5308             _buffered = (__INST(buffered) == true);
  5304 	    _buffered = (__INST(buffered) == true);
  5309             if (_buffered) {
  5305 	    if (_buffered) {
  5310                 __READING__(f)
  5306 		__READING__(f)
  5311             }
  5307 	    }
  5312             __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5308 	    __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5313 
  5309 
  5314             if (ret > 0) {
  5310 	    if (ret > 0) {
  5315                 pos = __INST(position);
  5311 		pos = __INST(position);
  5316                 if (__isSmallInteger(pos)) {
  5312 		if (__isSmallInteger(pos)) {
  5317                     OBJ t;
  5313 		    OBJ t;
  5318 
  5314 
  5319                     t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5315 		    t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5320                 } else {
  5316 		} else {
  5321                     __INST(position) = nil; /* i.e. do not know */
  5317 		    __INST(position) = nil; /* i.e. do not know */
  5322                 }
  5318 		}
  5323                 if (__INST(binary) == true) {
  5319 		if (__INST(binary) == true) {
  5324                     RETURN ( __mkSmallInteger(ch) );
  5320 		    RETURN ( __mkSmallInteger(ch) );
  5325                 }
  5321 		}
  5326                 RETURN ( __MKCHARACTER(ch) );
  5322 		RETURN ( __MKCHARACTER(ch) );
  5327             }
  5323 	    }
  5328 
  5324 
  5329             __INST(position) = nil;
  5325 	    __INST(position) = nil;
  5330             if (ret < 0) {
  5326 	    if (ret < 0) {
  5331                 error = __mkSmallInteger(__threadErrno);
  5327 		error = __mkSmallInteger(__threadErrno);
  5332             } else /* ret == 0 */ {
  5328 	    } else /* ret == 0 */ {
  5333                 __INST(hitEOF) = true;
  5329 		__INST(hitEOF) = true;
  5334             }
  5330 	    }
  5335         }
  5331 	}
  5336     }
  5332     }
  5337 #endif /* not SCHTEAM */
  5333 #endif /* not SCHTEAM */
  5338 %}.
  5334 %}.
  5339     hitEOF ifTrue:[^ self pastEndRead].
  5335     hitEOF ifTrue:[^ self pastEndRead].
  5340     error notNil ifTrue:[
  5336     error notNil ifTrue:[
  5341         lastErrorNumber := error.
  5337 	lastErrorNumber := error.
  5342         ^ self readError:error
  5338 	^ self readError:error
  5343     ].
  5339     ].
  5344     handle isNil ifTrue:[^ self errorNotOpen].
  5340     handle isNil ifTrue:[^ self errorNotOpen].
  5345     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5341     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5346 
  5342 
  5347     readAhead notNil ifTrue:[
  5343     readAhead notNil ifTrue:[
  5348         c := readAhead.
  5344 	c := readAhead.
  5349         readAhead := nil.
  5345 	readAhead := nil.
  5350         ^ c.
  5346 	^ c.
  5351     ].
  5347     ].
  5352 
  5348 
  5353     "unknown handleType - future"
  5349     "unknown handleType - future"
  5354     c := self nextByteFromFile:handle.
  5350     c := self nextByteFromFile:handle.
  5355     c isNil ifTrue:[
  5351     c isNil ifTrue:[
  5356         ^ self pastEndRead.
  5352 	^ self pastEndRead.
  5357     ].
  5353     ].
  5358     binary ifTrue:[
  5354     binary ifTrue:[
  5359         ^ c
  5355 	^ c
  5360     ].
  5356     ].
  5361     ^ Character value:c
  5357     ^ Character value:c
  5362 !
  5358 !
  5363 
  5359 
  5364 next:count
  5360 next:count
  5369 
  5365 
  5370     coll := self contentsSpecies uninitializedNew:count.
  5366     coll := self contentsSpecies uninitializedNew:count.
  5371     nRead := self nextBytes:count into:coll startingAt:1.
  5367     nRead := self nextBytes:count into:coll startingAt:1.
  5372 
  5368 
  5373     nRead ~~ count ifTrue:[
  5369     nRead ~~ count ifTrue:[
  5374         "/ for readStream protocol compatibility,
  5370 	"/ for readStream protocol compatibility,
  5375         "/ we must raise an exception here.
  5371 	"/ we must raise an exception here.
  5376         ^ self pastEndRead
  5372 	^ self pastEndRead
  5377     ].
  5373     ].
  5378     ^ coll
  5374     ^ coll
  5379 
  5375 
  5380     "Modified: 11.1.1997 / 17:44:17 / cg"
  5376     "Modified: 11.1.1997 / 17:44:17 / cg"
  5381 !
  5377 !
  5397     if ((__INST(handleType) == nil)
  5393     if ((__INST(handleType) == nil)
  5398      || (__INST(handleType) == @symbol(filePointer))
  5394      || (__INST(handleType) == @symbol(filePointer))
  5399      || (__INST(handleType) == @symbol(socketFilePointer))
  5395      || (__INST(handleType) == @symbol(socketFilePointer))
  5400      || (__INST(handleType) == @symbol(socketHandle))
  5396      || (__INST(handleType) == @symbol(socketHandle))
  5401      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5397      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5402         if (((fp = __INST(handle)) != nil)
  5398 	if (((fp = __INST(handle)) != nil)
  5403             && (__INST(mode) != @symbol(writeonly))
  5399 	    && (__INST(mode) != @symbol(writeonly))
  5404         ) {
  5400 	) {
  5405             f = __FILEVal(fp);
  5401 	    f = __FILEVal(fp);
  5406 
  5402 
  5407             _buffered = (__INST(buffered) == true);
  5403 	    _buffered = (__INST(buffered) == true);
  5408             if (_buffered) {
  5404 	    if (_buffered) {
  5409                 __READING__(f)
  5405 		__READING__(f)
  5410             }
  5406 	    }
  5411             __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5407 	    __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5412 
  5408 
  5413             if (ret > 0) {
  5409 	    if (ret > 0) {
  5414                 pos = __INST(position);
  5410 		pos = __INST(position);
  5415                 if (__isSmallInteger(pos)) {
  5411 		if (__isSmallInteger(pos)) {
  5416                     OBJ t;
  5412 		    OBJ t;
  5417 
  5413 
  5418                     t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5414 		    t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5419                 } else {
  5415 		} else {
  5420                     __INST(position) = nil; /* i.e. do not know */
  5416 		    __INST(position) = nil; /* i.e. do not know */
  5421                 }
  5417 		}
  5422                 if (__INST(binary) == true) {
  5418 		if (__INST(binary) == true) {
  5423                     RETURN ( __mkSmallInteger(ch) );
  5419 		    RETURN ( __mkSmallInteger(ch) );
  5424                 }
  5420 		}
  5425                 RETURN ( __MKCHARACTER(ch) );
  5421 		RETURN ( __MKCHARACTER(ch) );
  5426             }
  5422 	    }
  5427 
  5423 
  5428             __INST(position) = nil;
  5424 	    __INST(position) = nil;
  5429             if (ret < 0) {
  5425 	    if (ret < 0) {
  5430                 error = __mkSmallInteger(__threadErrno);
  5426 		error = __mkSmallInteger(__threadErrno);
  5431             } else /* ret == 0 */ {
  5427 	    } else /* ret == 0 */ {
  5432                 __INST(hitEOF) = true;
  5428 		__INST(hitEOF) = true;
  5433             }
  5429 	    }
  5434         }
  5430 	}
  5435     }
  5431     }
  5436 %}.
  5432 %}.
  5437     hitEOF ifTrue:[^ nil].
  5433     hitEOF ifTrue:[^ nil].
  5438     error notNil ifTrue:[
  5434     error notNil ifTrue:[
  5439         lastErrorNumber := error.
  5435 	lastErrorNumber := error.
  5440         ^ self readError:error.
  5436 	^ self readError:error.
  5441     ].
  5437     ].
  5442     handle isNil ifTrue:[^ self errorNotOpen].
  5438     handle isNil ifTrue:[^ self errorNotOpen].
  5443     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5439     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5444 
  5440 
  5445     readAhead notNil ifTrue:[
  5441     readAhead notNil ifTrue:[
  5446         c := readAhead.
  5442 	c := readAhead.
  5447         readAhead := nil.
  5443 	readAhead := nil.
  5448         ^ c.
  5444 	^ c.
  5449     ].
  5445     ].
  5450 
  5446 
  5451     "unknown handleType - future"
  5447     "unknown handleType - future"
  5452     c := self nextByteFromFile:handle.
  5448     c := self nextByteFromFile:handle.
  5453     c isNil ifTrue:[
  5449     c isNil ifTrue:[
  5454         ^ nil.
  5450 	^ nil.
  5455     ].
  5451     ].
  5456     binary == true ifTrue:[
  5452     binary == true ifTrue:[
  5457         ^ c
  5453 	^ c
  5458     ].
  5454     ].
  5459     ^ Character value:c
  5455     ^ Character value:c
  5460 !
  5456 !
  5461 
  5457 
  5462 peek
  5458 peek
  5472     int ret, _buffered;
  5468     int ret, _buffered;
  5473     OBJ fp;
  5469     OBJ fp;
  5474     OBJ ra;
  5470     OBJ ra;
  5475 
  5471 
  5476     if ((ra = __INST(readAhead)) != nil) {
  5472     if ((ra = __INST(readAhead)) != nil) {
  5477         if (__INST(binary) == true) {
  5473 	if (__INST(binary) == true) {
  5478             RETURN ( ra );
  5474 	    RETURN ( ra );
  5479         }
  5475 	}
  5480         c = __intVal(ra);
  5476 	c = __intVal(ra);
  5481         RETURN ( __MKCHARACTER(c) );
  5477 	RETURN ( __MKCHARACTER(c) );
  5482     }
  5478     }
  5483 
  5479 
  5484     __INST(lastErrorNumber) = nil;
  5480     __INST(lastErrorNumber) = nil;
  5485 
  5481 
  5486     if ((__INST(handleType) == nil)
  5482     if ((__INST(handleType) == nil)
  5487      || (__INST(handleType) == @symbol(filePointer))
  5483      || (__INST(handleType) == @symbol(filePointer))
  5488      || (__INST(handleType) == @symbol(socketFilePointer))
  5484      || (__INST(handleType) == @symbol(socketFilePointer))
  5489      || (__INST(handleType) == @symbol(socketHandle))
  5485      || (__INST(handleType) == @symbol(socketHandle))
  5490      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5486      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5491         if (((fp = __INST(handle)) != nil)
  5487 	if (((fp = __INST(handle)) != nil)
  5492             && (__INST(mode) != @symbol(writeonly))
  5488 	    && (__INST(mode) != @symbol(writeonly))
  5493         ) {
  5489 	) {
  5494             f = __FILEVal(fp);
  5490 	    f = __FILEVal(fp);
  5495             _buffered = (__INST(buffered) == true);
  5491 	    _buffered = (__INST(buffered) == true);
  5496             if (_buffered) {
  5492 	    if (_buffered) {
  5497                 __READING__(f)
  5493 		__READING__(f)
  5498             }
  5494 	    }
  5499             __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5495 	    __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5500 
  5496 
  5501             if (ret > 0) {
  5497 	    if (ret > 0) {
  5502                 __UNGETC__(c, f, _buffered);
  5498 		__UNGETC__(c, f, _buffered);
  5503 
  5499 
  5504                 if (__INST(binary) == true) {
  5500 		if (__INST(binary) == true) {
  5505                     RETURN ( __mkSmallInteger(c) );
  5501 		    RETURN ( __mkSmallInteger(c) );
  5506                 }
  5502 		}
  5507                 RETURN ( __MKCHARACTER(c) );
  5503 		RETURN ( __MKCHARACTER(c) );
  5508             }
  5504 	    }
  5509             if (ret < 0) {
  5505 	    if (ret < 0) {
  5510                 error = __mkSmallInteger(__threadErrno);
  5506 		error = __mkSmallInteger(__threadErrno);
  5511             } else /* ret == 0 */ {
  5507 	    } else /* ret == 0 */ {
  5512                 __INST(hitEOF) = true;
  5508 		__INST(hitEOF) = true;
  5513             }
  5509 	    }
  5514         }
  5510 	}
  5515     }
  5511     }
  5516 %}.
  5512 %}.
  5517     hitEOF ifTrue:[^ self pastEndRead].
  5513     hitEOF ifTrue:[^ self pastEndRead].
  5518     error notNil ifTrue:[
  5514     error notNil ifTrue:[
  5519         lastErrorNumber := error.
  5515 	lastErrorNumber := error.
  5520         ^ self readError:error.
  5516 	^ self readError:error.
  5521     ].
  5517     ].
  5522     handle isNil ifTrue:[^ self errorNotOpen].
  5518     handle isNil ifTrue:[^ self errorNotOpen].
  5523     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5519     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5524 
  5520 
  5525     readAhead isNil ifTrue:[
  5521     readAhead isNil ifTrue:[
  5526         readAhead := self nextOrNil.
  5522 	readAhead := self nextOrNil.
  5527         readAhead isNil ifTrue:[
  5523 	readAhead isNil ifTrue:[
  5528             ^ self pastEndRead.
  5524 	    ^ self pastEndRead.
  5529         ].
  5525 	].
  5530     ].
  5526     ].
  5531     ^ readAhead
  5527     ^ readAhead
  5532 !
  5528 !
  5533 
  5529 
  5534 peekOrNil
  5530 peekOrNil
  5544     int ret, _buffered;
  5540     int ret, _buffered;
  5545     OBJ fp;
  5541     OBJ fp;
  5546     OBJ ra;
  5542     OBJ ra;
  5547 
  5543 
  5548     if ((ra = __INST(readAhead)) != nil) {
  5544     if ((ra = __INST(readAhead)) != nil) {
  5549         if (__INST(binary) == true) {
  5545 	if (__INST(binary) == true) {
  5550             RETURN ( ra );
  5546 	    RETURN ( ra );
  5551         }
  5547 	}
  5552         c = __intVal(ra);
  5548 	c = __intVal(ra);
  5553         RETURN ( __MKCHARACTER(c) );
  5549 	RETURN ( __MKCHARACTER(c) );
  5554     }
  5550     }
  5555 
  5551 
  5556     __INST(lastErrorNumber) = nil;
  5552     __INST(lastErrorNumber) = nil;
  5557 
  5553 
  5558     if ((__INST(handleType) == nil)
  5554     if ((__INST(handleType) == nil)
  5559      || (__INST(handleType) == @symbol(filePointer))
  5555      || (__INST(handleType) == @symbol(filePointer))
  5560      || (__INST(handleType) == @symbol(socketFilePointer))
  5556      || (__INST(handleType) == @symbol(socketFilePointer))
  5561      || (__INST(handleType) == @symbol(socketHandle))
  5557      || (__INST(handleType) == @symbol(socketHandle))
  5562      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5558      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5563         if (((fp = __INST(handle)) != nil)
  5559 	if (((fp = __INST(handle)) != nil)
  5564             && (__INST(mode) != @symbol(writeonly))
  5560 	    && (__INST(mode) != @symbol(writeonly))
  5565         ) {
  5561 	) {
  5566             f = __FILEVal(fp);
  5562 	    f = __FILEVal(fp);
  5567             _buffered = (__INST(buffered) == true);
  5563 	    _buffered = (__INST(buffered) == true);
  5568             if (_buffered) {
  5564 	    if (_buffered) {
  5569                 __READING__(f)
  5565 		__READING__(f)
  5570             }
  5566 	    }
  5571             __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5567 	    __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5572 
  5568 
  5573             if (ret > 0) {
  5569 	    if (ret > 0) {
  5574                 __UNGETC__(c, f, _buffered);
  5570 		__UNGETC__(c, f, _buffered);
  5575 
  5571 
  5576                 if (__INST(binary) == true) {
  5572 		if (__INST(binary) == true) {
  5577                     RETURN ( __mkSmallInteger(c) );
  5573 		    RETURN ( __mkSmallInteger(c) );
  5578                 }
  5574 		}
  5579                 RETURN ( __MKCHARACTER(c) );
  5575 		RETURN ( __MKCHARACTER(c) );
  5580             }
  5576 	    }
  5581             if (ret < 0) {
  5577 	    if (ret < 0) {
  5582                 error = __mkSmallInteger(__threadErrno);
  5578 		error = __mkSmallInteger(__threadErrno);
  5583             } else /* ret == 0 */ {
  5579 	    } else /* ret == 0 */ {
  5584                 __INST(hitEOF) = true;
  5580 		__INST(hitEOF) = true;
  5585             }
  5581 	    }
  5586         }
  5582 	}
  5587     }
  5583     }
  5588 %}.
  5584 %}.
  5589     hitEOF ifTrue:[^ nil].
  5585     hitEOF ifTrue:[^ nil].
  5590     error notNil ifTrue:[
  5586     error notNil ifTrue:[
  5591         lastErrorNumber := error.
  5587 	lastErrorNumber := error.
  5592         ^ self readError:error.
  5588 	^ self readError:error.
  5593     ].
  5589     ].
  5594     handle isNil ifTrue:[^ self errorNotOpen].
  5590     handle isNil ifTrue:[^ self errorNotOpen].
  5595     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5591     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5596 
  5592 
  5597     readAhead isNil ifTrue:[
  5593     readAhead isNil ifTrue:[
  5598         readAhead := self nextOrNil.
  5594 	readAhead := self nextOrNil.
  5599     ].
  5595     ].
  5600     ^ readAhead
  5596     ^ readAhead
  5601 !
  5597 !
  5602 
  5598 
  5603 upToEnd
  5599 upToEnd
  5613     chunkSize := 4096.
  5609     chunkSize := 4096.
  5614     byteCount := 0.
  5610     byteCount := 0.
  5615     contentsSpecies := self contentsSpecies.
  5611     contentsSpecies := self contentsSpecies.
  5616 
  5612 
  5617     [self atEnd] whileFalse:[
  5613     [self atEnd] whileFalse:[
  5618         |chunk cnt|
  5614 	|chunk cnt|
  5619 
  5615 
  5620         chunk := contentsSpecies uninitializedNew:chunkSize.
  5616 	chunk := contentsSpecies uninitializedNew:chunkSize.
  5621         cnt := self nextBytes:chunkSize into:chunk startingAt:1.
  5617 	cnt := self nextBytes:chunkSize into:chunk startingAt:1.
  5622         cnt ~~ 0 ifTrue:[
  5618 	cnt ~~ 0 ifTrue:[
  5623             chunksAndCounts isNil ifTrue:[
  5619 	    chunksAndCounts isNil ifTrue:[
  5624                 (cnt < chunkSize and:[self atEnd]) ifTrue:[
  5620 		(cnt < chunkSize and:[self atEnd]) ifTrue:[
  5625                     "all data is in a single chunk, so we are done"
  5621 		    "all data is in a single chunk, so we are done"
  5626                     ^ chunk copyFrom:1 to:cnt.
  5622 		    ^ chunk copyFrom:1 to:cnt.
  5627                 ].
  5623 		].
  5628                 chunksAndCounts := OrderedCollection new.
  5624 		chunksAndCounts := OrderedCollection new.
  5629             ].
  5625 	    ].
  5630             chunksAndCounts add:chunk; add:cnt.
  5626 	    chunksAndCounts add:chunk; add:cnt.
  5631             byteCount := byteCount + cnt.
  5627 	    byteCount := byteCount + cnt.
  5632         ]
  5628 	]
  5633     ].
  5629     ].
  5634 
  5630 
  5635     "now, create one big array"
  5631     "now, create one big array"
  5636     data := contentsSpecies uninitializedNew:byteCount.
  5632     data := contentsSpecies uninitializedNew:byteCount.
  5637     offset := 1.
  5633     offset := 1.
  5638     1 to:chunksAndCounts size by:2 do:[:index |
  5634     1 to:chunksAndCounts size by:2 do:[:index |
  5639         |chunk cnt|
  5635 	|chunk cnt|
  5640 
  5636 
  5641         chunk := chunksAndCounts at:index.
  5637 	chunk := chunksAndCounts at:index.
  5642         cnt := chunksAndCounts at:index+1.
  5638 	cnt := chunksAndCounts at:index+1.
  5643         data replaceFrom:offset to:(offset + cnt - 1) with:chunk startingAt:1.
  5639 	data replaceFrom:offset to:(offset + cnt - 1) with:chunk startingAt:1.
  5644         offset := offset + cnt
  5640 	offset := offset + cnt
  5645     ].
  5641     ].
  5646     ^ data
  5642     ^ data
  5647 
  5643 
  5648 
  5644 
  5649     "
  5645     "
  5650      '/dev/null' asFilename readStream upToEnd
  5646      '/dev/null' asFilename readStream upToEnd
  5651      '/proc/self/stat' asFilename readStream upToEnd
  5647      '/proc/self/stat' asFilename readStream upToEnd
  5652      'librun.so' asFilename readStream binary upToEnd
  5648      'librun.so' asFilename readStream binary upToEnd
  5653 
  5649 
  5654      self assert:('smalltalk.rc' asFilename readStream upToEnd size)
  5650      self assert:('smalltalk.rc' asFilename readStream upToEnd size)
  5655                   =  ('smalltalk.rc' asFilename readStream size)
  5651 		  =  ('smalltalk.rc' asFilename readStream size)
  5656     "
  5652     "
  5657 
  5653 
  5658     "Modified (format): / 09-05-2018 / 20:09:31 / stefan"
  5654     "Modified (format): / 09-05-2018 / 20:09:31 / stefan"
  5659 ! !
  5655 ! !
  5660 
  5656 
  5690 %{
  5686 %{
  5691     OBJ fp, lim;
  5687     OBJ fp, lim;
  5692     char c;
  5688     char c;
  5693 
  5689 
  5694     if (__INST(hitEOF) == true) {
  5690     if (__INST(hitEOF) == true) {
  5695         RETURN (true);
  5691 	RETURN (true);
  5696     }
  5692     }
  5697     lim = __INST(readLimit);
  5693     lim = __INST(readLimit);
  5698     if (lim != nil && __signedLongIntVal(__INST(position)) >= __signedLongIntVal(lim)) {
  5694     if (lim != nil && __signedLongIntVal(__INST(position)) >= __signedLongIntVal(lim)) {
  5699         RETURN (true);
  5695 	RETURN (true);
  5700     }
  5696     }
  5701 
  5697 
  5702     __INST(lastErrorNumber) = nil;
  5698     __INST(lastErrorNumber) = nil;
  5703 
  5699 
  5704     if ((__INST(handleType) == nil)
  5700     if ((__INST(handleType) == nil)
  5705      || (__INST(handleType) == @symbol(filePointer))
  5701      || (__INST(handleType) == @symbol(filePointer))
  5706      || (__INST(handleType) == @symbol(socketFilePointer))
  5702      || (__INST(handleType) == @symbol(socketFilePointer))
  5707      || (__INST(handleType) == @symbol(socketHandle))
  5703      || (__INST(handleType) == @symbol(socketHandle))
  5708      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5704      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5709         if ((fp = __INST(handle)) != nil) {
  5705 	if ((fp = __INST(handle)) != nil) {
  5710             int _buffered = (__INST(buffered) == true);
  5706 	    int _buffered = (__INST(buffered) == true);
  5711             int ret;
  5707 	    int ret;
  5712             FILEPOINTER f = __FILEVal(fp);
  5708 	    FILEPOINTER f = __FILEVal(fp);
  5713 
  5709 
  5714             if (_buffered) {
  5710 	    if (_buffered) {
  5715                 __READING__(f);
  5711 		__READING__(f);
  5716             } else if (__INST(readAhead) != nil) {
  5712 	    } else if (__INST(readAhead) != nil) {
  5717                 RETURN (false);
  5713 		RETURN (false);
  5718             }
  5714 	    }
  5719 
  5715 
  5720             /*
  5716 	    /*
  5721              * read ahead ...
  5717 	     * read ahead ...
  5722              */
  5718 	     */
  5723             do {
  5719 	    do {
  5724 #ifdef __win32__
  5720 #ifdef __win32__
  5725                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5721 		__READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5726 #else /* not __win32__ */
  5722 #else /* not __win32__ */
  5727                 __BEGIN_INTERRUPTABLE__
  5723 		__BEGIN_INTERRUPTABLE__
  5728                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5724 		__READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5729                 __END_INTERRUPTABLE__
  5725 		__END_INTERRUPTABLE__
  5730 #endif /* not __win32__ */
  5726 #endif /* not __win32__ */
  5731             } while ((ret < 0) && (__threadErrno == EINTR));
  5727 	    } while ((ret < 0) && (__threadErrno == EINTR));
  5732             if (ret > 0) {
  5728 	    if (ret > 0) {
  5733                 __UNGETC__(c&0xff, f, _buffered);
  5729 		__UNGETC__(c&0xff, f, _buffered);
  5734                 RETURN (false);
  5730 		RETURN (false);
  5735             }
  5731 	    }
  5736             if (ret == 0) {
  5732 	    if (ret == 0) {
  5737                 __INST(hitEOF) = true;
  5733 		__INST(hitEOF) = true;
  5738                 RETURN (true);
  5734 		RETURN (true);
  5739             }
  5735 	    }
  5740             /* ret < 0 -> error */
  5736 	    /* ret < 0 -> error */
  5741             __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  5737 	    __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  5742         }
  5738 	}
  5743         // we do not raise an error here - the next read operation will raise the error.
  5739 	// we do not raise an error here - the next read operation will raise the error.
  5744         RETURN(false);
  5740 	RETURN(false);
  5745     }
  5741     }
  5746 %}.
  5742 %}.
  5747 
  5743 
  5748     "/ we come here if the handle type is unknown
  5744     "/ we come here if the handle type is unknown
  5749     "/ migration support
  5745     "/ migration support
  5837     "answer the number of bytes available for reading"
  5833     "answer the number of bytes available for reading"
  5838 
  5834 
  5839     |available|
  5835     |available|
  5840 
  5836 
  5841     handle isNil ifTrue:[
  5837     handle isNil ifTrue:[
  5842         ^ self errorNotOpen
  5838 	^ self errorNotOpen
  5843     ].
  5839     ].
  5844     mode == #writeonly ifTrue:[
  5840     mode == #writeonly ifTrue:[
  5845         ^ self errorWriteOnly
  5841 	^ self errorWriteOnly
  5846     ].
  5842     ].
  5847     available := OperatingSystem numAvailableForReadOn:self fileHandle.
  5843     available := OperatingSystem numAvailableForReadOn:self fileHandle.
  5848     readAhead notNil ifTrue:[
  5844     readAhead notNil ifTrue:[
  5849         available := available + 1
  5845 	available := available + 1
  5850     ].
  5846     ].
  5851     ^ available.
  5847     ^ available.
  5852 
  5848 
  5853     "
  5849     "
  5854         '/etc/hosts' asFilename readStream numAvailableForRead
  5850 	'/etc/hosts' asFilename readStream numAvailableForRead
  5855     "
  5851     "
  5856 !
  5852 !
  5857 
  5853 
  5858 readWaitWithTimeoutMs:timeoutOrNil
  5854 readWaitWithTimeoutMs:timeoutOrNil
  5859     "suspend the current process, until the receiver
  5855     "suspend the current process, until the receiver
  5882     Smalltalk isInitialized ifFalse:[ ^ false ].
  5878     Smalltalk isInitialized ifFalse:[ ^ false ].
  5883 
  5879 
  5884     wasBlocked := OperatingSystem blockInterrupts.
  5880     wasBlocked := OperatingSystem blockInterrupts.
  5885     inputSema := Semaphore name:'readWait'.
  5881     inputSema := Semaphore name:'readWait'.
  5886     [
  5882     [
  5887         Processor signal:inputSema onInput:fd.
  5883 	Processor signal:inputSema onInput:fd.
  5888         hasTimedout := (inputSema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5884 	hasTimedout := (inputSema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5889     ] ifCurtailed:[
  5885     ] ifCurtailed:[
  5890         Processor disableSemaphore:inputSema.
  5886 	Processor disableSemaphore:inputSema.
  5891         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5887 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5892     ].
  5888     ].
  5893     hasTimedout ifTrue:[
  5889     hasTimedout ifTrue:[
  5894         Processor disableSemaphore:inputSema.
  5890 	Processor disableSemaphore:inputSema.
  5895     ].
  5891     ].
  5896     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5892     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5897     ^ hasTimedout
  5893     ^ hasTimedout
  5898 
  5894 
  5899     "Modified: / 09-08-2017 / 11:53:58 / cg"
  5895     "Modified: / 09-08-2017 / 11:53:58 / cg"
  5908 
  5904 
  5909     |fd sema hasTimedout wasBlocked|
  5905     |fd sema hasTimedout wasBlocked|
  5910 
  5906 
  5911     readAhead notNil ifTrue:[^ false].
  5907     readAhead notNil ifTrue:[^ false].
  5912     handle isNil ifTrue:[
  5908     handle isNil ifTrue:[
  5913         ^ self errorNotOpen
  5909 	^ self errorNotOpen
  5914     ].
  5910     ].
  5915 
  5911 
  5916     fd := self fileHandle.
  5912     fd := self fileHandle.
  5917     (OperatingSystem readWriteCheck:fd) ifTrue:[^ false].
  5913     (OperatingSystem readWriteCheck:fd) ifTrue:[^ false].
  5918 
  5914 
  5919     wasBlocked := OperatingSystem blockInterrupts.
  5915     wasBlocked := OperatingSystem blockInterrupts.
  5920     sema := Semaphore name:'readWriteWait'.
  5916     sema := Semaphore name:'readWriteWait'.
  5921     [
  5917     [
  5922         Processor 
  5918 	Processor
  5923             signal:sema onOutput:fd;
  5919 	    signal:sema onOutput:fd;
  5924             signal:sema onInput:fd.
  5920 	    signal:sema onInput:fd.
  5925         hasTimedout := (sema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5921 	hasTimedout := (sema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5926     ] ifCurtailed:[
  5922     ] ifCurtailed:[
  5927         Processor disableSemaphore:sema.
  5923 	Processor disableSemaphore:sema.
  5928         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5924 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5929     ].
  5925     ].
  5930     hasTimedout ifTrue:[
  5926     hasTimedout ifTrue:[
  5931         Processor disableSemaphore:sema.
  5927 	Processor disableSemaphore:sema.
  5932     ].
  5928     ].
  5933     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5929     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5934     ^ hasTimedout
  5930     ^ hasTimedout
  5935 
  5931 
  5936     "Modified: / 09-08-2017 / 11:54:03 / cg"
  5932     "Modified: / 09-08-2017 / 11:54:03 / cg"
  5944      The other threads are not affected by the wait."
  5940      The other threads are not affected by the wait."
  5945 
  5941 
  5946     |fd sema hasTimedout wasBlocked|
  5942     |fd sema hasTimedout wasBlocked|
  5947 
  5943 
  5948     handle isNil ifTrue:[
  5944     handle isNil ifTrue:[
  5949         ^ self errorNotOpen
  5945 	^ self errorNotOpen
  5950     ].
  5946     ].
  5951 
  5947 
  5952     fd := self fileHandle.
  5948     fd := self fileHandle.
  5953     (OperatingSystem writeExceptionCheck:fd) ifTrue:[^ false].
  5949     (OperatingSystem writeExceptionCheck:fd) ifTrue:[^ false].
  5954 
  5950 
  5955     wasBlocked := OperatingSystem blockInterrupts.
  5951     wasBlocked := OperatingSystem blockInterrupts.
  5956     sema := Semaphore name:'writeExceptionWait'.
  5952     sema := Semaphore name:'writeExceptionWait'.
  5957     [
  5953     [
  5958         Processor 
  5954 	Processor
  5959             signal:sema onOutput:fd;
  5955 	    signal:sema onOutput:fd;
  5960             signal:sema onException:fd.
  5956 	    signal:sema onException:fd.
  5961         hasTimedout := (sema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5957 	hasTimedout := (sema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5962     ] ifCurtailed:[
  5958     ] ifCurtailed:[
  5963         Processor disableSemaphore:sema.
  5959 	Processor disableSemaphore:sema.
  5964         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5960 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5965     ].
  5961     ].
  5966     hasTimedout ifTrue:[
  5962     hasTimedout ifTrue:[
  5967         Processor disableSemaphore:sema.
  5963 	Processor disableSemaphore:sema.
  5968     ].
  5964     ].
  5969     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5965     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5970     ^ hasTimedout
  5966     ^ hasTimedout
  5971 
  5967 
  5972     "Modified: / 09-08-2017 / 11:54:10 / cg"
  5968     "Modified: / 09-08-2017 / 11:54:10 / cg"
  5980      The other threads are not affected by the wait."
  5976      The other threads are not affected by the wait."
  5981 
  5977 
  5982     |fd outputSema hasTimedout wasBlocked|
  5978     |fd outputSema hasTimedout wasBlocked|
  5983 
  5979 
  5984     handle isNil ifTrue:[
  5980     handle isNil ifTrue:[
  5985         ^ self errorNotOpen
  5981 	^ self errorNotOpen
  5986     ].
  5982     ].
  5987     mode == #readonly ifTrue:[
  5983     mode == #readonly ifTrue:[
  5988         ^ self errorReadOnly
  5984 	^ self errorReadOnly
  5989     ].
  5985     ].
  5990 
  5986 
  5991     fd := self fileHandle.
  5987     fd := self fileHandle.
  5992     (OperatingSystem writeCheck:fd) ifTrue:[^ false].
  5988     (OperatingSystem writeCheck:fd) ifTrue:[^ false].
  5993 
  5989 
  5994     wasBlocked := OperatingSystem blockInterrupts.
  5990     wasBlocked := OperatingSystem blockInterrupts.
  5995     outputSema := Semaphore name:'writeWait'.
  5991     outputSema := Semaphore name:'writeWait'.
  5996     [
  5992     [
  5997         Processor signal:outputSema onOutput:fd.
  5993 	Processor signal:outputSema onOutput:fd.
  5998         hasTimedout := (outputSema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5994 	hasTimedout := (outputSema waitWithTimeoutMs:timeoutOrNil state:#ioWait) isNil.
  5999     ] ifCurtailed:[
  5995     ] ifCurtailed:[
  6000         Processor disableSemaphore:outputSema.
  5996 	Processor disableSemaphore:outputSema.
  6001         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  5997 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  6002     ].
  5998     ].
  6003     hasTimedout ifTrue:[
  5999     hasTimedout ifTrue:[
  6004         Processor disableSemaphore:outputSema.
  6000 	Processor disableSemaphore:outputSema.
  6005     ].
  6001     ].
  6006     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  6002     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  6007     ^ hasTimedout
  6003     ^ hasTimedout
  6008 
  6004 
  6009     "Modified: / 09-08-2017 / 11:54:14 / cg"
  6005     "Modified: / 09-08-2017 / 11:54:14 / cg"
  6019     if ((__INST(handleType) == nil)
  6015     if ((__INST(handleType) == nil)
  6020      || (__INST(handleType) == @symbol(filePointer))
  6016      || (__INST(handleType) == @symbol(filePointer))
  6021      || (__INST(handleType) == @symbol(socketHandle))
  6017      || (__INST(handleType) == @symbol(socketHandle))
  6022      || (__INST(handleType) == @symbol(socketFilePointer))
  6018      || (__INST(handleType) == @symbol(socketFilePointer))
  6023      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6019      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6024         OBJ fp;
  6020 	OBJ fp;
  6025 
  6021 
  6026         __INST(lastErrorNumber) = nil;
  6022 	__INST(lastErrorNumber) = nil;
  6027         if (((fp = __INST(handle)) != nil)
  6023 	if (((fp = __INST(handle)) != nil)
  6028          && (__INST(mode) != @symbol(readonly))
  6024 	 && (__INST(mode) != @symbol(readonly))
  6029          && (__INST(binary) != true)
  6025 	 && (__INST(binary) != true)
  6030         ) {
  6026 	) {
  6031             FILEPOINTER f = __FILEVal(fp);
  6027 	    FILEPOINTER f = __FILEVal(fp);
  6032             int _buffered = (__INST(buffered) == true);
  6028 	    int _buffered = (__INST(buffered) == true);
  6033             int len, cnt;
  6029 	    int len, cnt;
  6034             char *cp;
  6030 	    char *cp;
  6035 
  6031 
  6036             if (_buffered) {
  6032 	    if (_buffered) {
  6037                 __WRITING__(f)
  6033 		__WRITING__(f)
  6038             }
  6034 	    }
  6039             {
  6035 	    {
  6040                 OBJ mode = __INST(eolMode);
  6036 		OBJ mode = __INST(eolMode);
  6041 
  6037 
  6042                 if (mode == @symbol(cr)) {
  6038 		if (mode == @symbol(cr)) {
  6043                     cp = "\r"; len = 1;
  6039 		    cp = "\r"; len = 1;
  6044                 } else if (mode == @symbol(crlf)) {
  6040 		} else if (mode == @symbol(crlf)) {
  6045                     cp = "\r\n"; len = 2;
  6041 		    cp = "\r\n"; len = 2;
  6046                 } else if (mode == @symbol(eot)) {
  6042 		} else if (mode == @symbol(eot)) {
  6047                     cp = "\004"; len = 1;
  6043 		    cp = "\004"; len = 1;
  6048                 } else if (mode == @symbol(etx)) {
  6044 		} else if (mode == @symbol(etx)) {
  6049                     cp = "\003"; len = 1;
  6045 		    cp = "\003"; len = 1;
  6050                 } else {
  6046 		} else {
  6051                     cp = "\n"; len = 1;
  6047 		    cp = "\n"; len = 1;
  6052                 }
  6048 		}
  6053             }
  6049 	    }
  6054 #ifdef __win32__
  6050 #ifdef __win32__
  6055             if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6051 	    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6056                 cnt = __win32_fwrite(cp, 1, len, f);
  6052 		cnt = __win32_fwrite(cp, 1, len, f);
  6057             } else
  6053 	    } else
  6058 #endif
  6054 #endif
  6059             {
  6055 	    {
  6060                 __WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType));
  6056 		__WRITEBYTES__(cnt, f, cp, len, _buffered, __INST(handleType));
  6061             }
  6057 	    }
  6062             if (cnt == len) {
  6058 	    if (cnt == len) {
  6063                 if (__isSmallInteger(__INST(position))) {
  6059 		if (__isSmallInteger(__INST(position))) {
  6064                     INT np = __intVal(__INST(position)) + len;
  6060 		    INT np = __intVal(__INST(position)) + len;
  6065                     OBJ t;
  6061 		    OBJ t;
  6066 
  6062 
  6067                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6063 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6068                 } else {
  6064 		} else {
  6069                     __INST(position) = nil; /* i.e: don't know */
  6065 		    __INST(position) = nil; /* i.e: don't know */
  6070                 }
  6066 		}
  6071                 RETURN ( self );
  6067 		RETURN ( self );
  6072             }
  6068 	    }
  6073             __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  6069 	    __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  6074         }
  6070 	}
  6075     }
  6071     }
  6076 %}.
  6072 %}.
  6077     lastErrorNumber notNil ifTrue:[self writeError. ^ self].
  6073     lastErrorNumber notNil ifTrue:[self writeError. ^ self].
  6078     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6074     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6079     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6075     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6080     binary ifTrue:[self errorBinary. ^ self].
  6076     binary ifTrue:[self errorBinary. ^ self].
  6081 
  6077 
  6082     (eolMode == #cr) ifTrue:[
  6078     (eolMode == #cr) ifTrue:[
  6083         self nextPut:(Character return).
  6079 	self nextPut:(Character return).
  6084         ^ self
  6080 	^ self
  6085     ].
  6081     ].
  6086     (eolMode == #crlf) ifTrue:[
  6082     (eolMode == #crlf) ifTrue:[
  6087         self nextPut:(Character return).
  6083 	self nextPut:(Character return).
  6088     ].
  6084     ].
  6089     self nextPut:(Character nl).
  6085     self nextPut:(Character nl).
  6090     ^ self
  6086     ^ self
  6091 !
  6087 !
  6092 
  6088 
  6097     __INST(lastErrorNumber) = nil;
  6093     __INST(lastErrorNumber) = nil;
  6098     if ((__INST(handleType) == nil)
  6094     if ((__INST(handleType) == nil)
  6099      || (__INST(handleType) == @symbol(filePointer))
  6095      || (__INST(handleType) == @symbol(filePointer))
  6100      || (__INST(handleType) == @symbol(socketFilePointer))
  6096      || (__INST(handleType) == @symbol(socketFilePointer))
  6101      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6097      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6102         OBJ fp;
  6098 	OBJ fp;
  6103         int _buffered = (__INST(buffered) == true);
  6099 	int _buffered = (__INST(buffered) == true);
  6104 
  6100 
  6105         if ((fp = __INST(handle)) != nil) {
  6101 	if ((fp = __INST(handle)) != nil) {
  6106             if (__INST(mode) != @symbol(readonly)) {
  6102 	    if (__INST(mode) != @symbol(readonly)) {
  6107                 if (_buffered) {
  6103 		if (_buffered) {
  6108                     FILEPOINTER f = __FILEVal(fp);
  6104 		    FILEPOINTER f = __FILEVal(fp);
  6109 #ifdef __win32__
  6105 #ifdef __win32__
  6110                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6106 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6111                         __win32_fflush(f);
  6107 			__win32_fflush(f);
  6112                     } else {
  6108 		    } else {
  6113                         int rslt;
  6109 			int rslt;
  6114 
  6110 
  6115                         do {
  6111 			do {
  6116                             __threadErrno = 0;
  6112 			    __threadErrno = 0;
  6117                             rslt = __STX_C_CALL1("fflush", fflush, f);
  6113 			    rslt = __STX_C_CALL1("fflush", fflush, f);
  6118                         } while((rslt < 0) && (__threadErrno == EINTR));
  6114 			} while((rslt < 0) && (__threadErrno == EINTR));
  6119                     }
  6115 		    }
  6120 #else /* ! __win32__ */
  6116 #else /* ! __win32__ */
  6121                     __BEGIN_INTERRUPTABLE__
  6117 		    __BEGIN_INTERRUPTABLE__
  6122                     FFLUSH(f);
  6118 		    FFLUSH(f);
  6123                     __END_INTERRUPTABLE__
  6119 		    __END_INTERRUPTABLE__
  6124 #endif /* ! __win32__ */
  6120 #endif /* ! __win32__ */
  6125                 }
  6121 		}
  6126             }
  6122 	    }
  6127         }
  6123 	}
  6128     }
  6124     }
  6129 %}
  6125 %}
  6130 !
  6126 !
  6131 
  6127 
  6132 nextPut:aCharacter
  6128 nextPut:aCharacter
  6138 #ifdef __SCHTEAM__
  6134 #ifdef __SCHTEAM__
  6139     STObject handle = self.instVarAt(I_handle);
  6135     STObject handle = self.instVarAt(I_handle);
  6140 
  6136 
  6141     if ((handle != STObject.Nil)
  6137     if ((handle != STObject.Nil)
  6142      && (aCharacter.isSTCharacter())) {
  6138      && (aCharacter.isSTCharacter())) {
  6143         handle.writeChar( aCharacter );
  6139 	handle.writeChar( aCharacter );
  6144         self.instVarAt_put(I_position, STObject.Nil);
  6140 	self.instVarAt_put(I_position, STObject.Nil);
  6145         return __c__._RETURN_self();
  6141 	return __c__._RETURN_self();
  6146     }
  6142     }
  6147 #else
  6143 #else
  6148     __INST(lastErrorNumber) = nil;
  6144     __INST(lastErrorNumber) = nil;
  6149     if ((__INST(handleType) == nil)
  6145     if ((__INST(handleType) == nil)
  6150      || (__INST(handleType) == @symbol(filePointer))
  6146      || (__INST(handleType) == @symbol(filePointer))
  6151      || (__INST(handleType) == @symbol(socketFilePointer))
  6147      || (__INST(handleType) == @symbol(socketFilePointer))
  6152      || (__INST(handleType) == @symbol(socketHandle))
  6148      || (__INST(handleType) == @symbol(socketHandle))
  6153      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6149      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6154         OBJ fp;
  6150 	OBJ fp;
  6155 
  6151 
  6156         if (((fp = __INST(handle)) != nil)
  6152 	if (((fp = __INST(handle)) != nil)
  6157          && (__INST(mode) != @symbol(readonly))
  6153 	 && (__INST(mode) != @symbol(readonly))
  6158         ) {
  6154 	) {
  6159             FILEPOINTER f = __FILEVal(fp);
  6155 	    FILEPOINTER f = __FILEVal(fp);
  6160             int _buffered = (__INST(buffered) == true);
  6156 	    int _buffered = (__INST(buffered) == true);
  6161             int cnt;
  6157 	    int cnt;
  6162             char buff[2];
  6158 	    char buff[2];
  6163             int nBytes = 1;
  6159 	    int nBytes = 1;
  6164 
  6160 
  6165             if (__INST(binary) != true) {
  6161 	    if (__INST(binary) != true) {
  6166                 if (__isCharacter(aCharacter)) {
  6162 		if (__isCharacter(aCharacter)) {
  6167                     unsigned int codePoint = __intVal(__characterVal(aCharacter));
  6163 		    unsigned int codePoint = __intVal(__characterVal(aCharacter));
  6168                     if (codePoint <= 0xFF) {
  6164 		    if (codePoint <= 0xFF) {
  6169                         unsigned char c = codePoint;
  6165 			unsigned char c = codePoint;
  6170                         buff[0] = c; nBytes = 1;
  6166 			buff[0] = c; nBytes = 1;
  6171 
  6167 
  6172                         if (c == '\n') {
  6168 			if (c == '\n') {
  6173                             OBJ mode = __INST(eolMode);
  6169 			    OBJ mode = __INST(eolMode);
  6174                             if (mode == @symbol(nl)) {
  6170 			    if (mode == @symbol(nl)) {
  6175                                 // no EOL translation
  6171 				// no EOL translation
  6176                             } else if (mode == nil) {
  6172 			    } else if (mode == nil) {
  6177                                 // no EOL translation
  6173 				// no EOL translation
  6178                             } else if (mode == @symbol(cr)) {
  6174 			    } else if (mode == @symbol(cr)) {
  6179                                 buff[0] = '\r';
  6175 				buff[0] = '\r';
  6180                             } else if (mode == @symbol(eot)) {
  6176 			    } else if (mode == @symbol(eot)) {
  6181                                 buff[0] = '\004';
  6177 				buff[0] = '\004';
  6182                             } else if (mode == @symbol(etx)) {
  6178 			    } else if (mode == @symbol(etx)) {
  6183                                 buff[0] = '\003';
  6179 				buff[0] = '\003';
  6184                             } else if (mode == @symbol(crlf)) {
  6180 			    } else if (mode == @symbol(crlf)) {
  6185                                 buff[0] = '\r';
  6181 				buff[0] = '\r';
  6186                                 buff[1] = '\n';
  6182 				buff[1] = '\n';
  6187                                 nBytes = 2;
  6183 				nBytes = 2;
  6188                             }
  6184 			    }
  6189                         }
  6185 			}
  6190     doWrite:
  6186     doWrite:
  6191                         if (! f) {
  6187 			if (! f) {
  6192                             fprintf(stderr, "oops - fileHandle is NULL in nextPut:\n");
  6188 			    fprintf(stderr, "oops - fileHandle is NULL in nextPut:\n");
  6193                             __INST(handle) = nil;
  6189 			    __INST(handle) = nil;
  6194                             goto out;
  6190 			    goto out;
  6195                         }
  6191 			}
  6196 
  6192 
  6197                         if (_buffered) {
  6193 			if (_buffered) {
  6198                             __WRITING__(f)
  6194 			    __WRITING__(f)
  6199                         }
  6195 			}
  6200 # ifdef __win32__
  6196 # ifdef __win32__
  6201                         if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6197 			if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6202                             cnt = __win32_fwrite(buff, 1, nBytes, f);
  6198 			    cnt = __win32_fwrite(buff, 1, nBytes, f);
  6203                         } else
  6199 			} else
  6204 # endif
  6200 # endif
  6205                         {
  6201 			{
  6206                             __WRITEBYTES__(cnt, f, buff, nBytes, _buffered, __INST(handleType));
  6202 			    __WRITEBYTES__(cnt, f, buff, nBytes, _buffered, __INST(handleType));
  6207                         }
  6203 			}
  6208                         if (cnt == nBytes) {
  6204 			if (cnt == nBytes) {
  6209                             if (__isSmallInteger(__INST(position))) {
  6205 			    if (__isSmallInteger(__INST(position))) {
  6210                                 INT np = __intVal(__INST(position)) + nBytes;
  6206 				INT np = __intVal(__INST(position)) + nBytes;
  6211                                 OBJ t;
  6207 				OBJ t;
  6212 
  6208 
  6213                                 t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6209 				t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6214                             } else {
  6210 			    } else {
  6215                                 __INST(position) = nil; /* i.e. do not know */
  6211 				__INST(position) = nil; /* i.e. do not know */
  6216                             }
  6212 			    }
  6217                             RETURN ( self );
  6213 			    RETURN ( self );
  6218                         }
  6214 			}
  6219                         error = __mkSmallInteger(__threadErrno);
  6215 			error = __mkSmallInteger(__threadErrno);
  6220                     }
  6216 		    }
  6221                 }
  6217 		}
  6222             } else {
  6218 	    } else {
  6223                 if (__isSmallInteger(aCharacter)) {
  6219 		if (__isSmallInteger(aCharacter)) {
  6224                     unsigned char c = __intVal(aCharacter);
  6220 		    unsigned char c = __intVal(aCharacter);
  6225                     buff[0] = c; nBytes = 1;
  6221 		    buff[0] = c; nBytes = 1;
  6226                     goto doWrite;
  6222 		    goto doWrite;
  6227                 }
  6223 		}
  6228             }
  6224 	    }
  6229         }
  6225 	}
  6230     }
  6226     }
  6231 out: ;
  6227 out: ;
  6232 #endif /* not SCHTEAM */
  6228 #endif /* not SCHTEAM */
  6233 %}.
  6229 %}.
  6234     error notNil ifTrue:[
  6230     error notNil ifTrue:[
  6235         lastErrorNumber := error.
  6231 	lastErrorNumber := error.
  6236         self writeError:error.
  6232 	self writeError:error.
  6237         ^ self
  6233 	^ self
  6238     ].
  6234     ].
  6239     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6235     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6240     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6236     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6241     binary == true ifTrue:[
  6237     binary == true ifTrue:[
  6242         aCharacter isInteger ifFalse:[
  6238 	aCharacter isInteger ifFalse:[
  6243             self argumentMustBeInteger.
  6239 	    self argumentMustBeInteger.
  6244             ^ self.
  6240 	    ^ self.
  6245         ].
  6241 	].
  6246     ] ifFalse:[
  6242     ] ifFalse:[
  6247         (aCharacter isCharacter not
  6243 	(aCharacter isCharacter not
  6248          or:[aCharacter codePoint > 16rFF]) ifTrue:[
  6244 	 or:[aCharacter codePoint > 16rFF]) ifTrue:[
  6249             self argumentMustBeCharacter.
  6245 	    self argumentMustBeCharacter.
  6250             ^ self.
  6246 	    ^ self.
  6251         ].
  6247 	].
  6252     ].
  6248     ].
  6253     "/ migration support
  6249     "/ migration support
  6254     self
  6250     self
  6255         nextPutByte:aCharacter asInteger
  6251 	nextPutByte:aCharacter asInteger
  6256         toFile:handle
  6252 	toFile:handle
  6257 !
  6253 !
  6258 
  6254 
  6259 nextPutAll:aCollection
  6255 nextPutAll:aCollection
  6260     "write all elements of the argument, aCollection.
  6256     "write all elements of the argument, aCollection.
  6261      Reimplemented for speed when writing strings or byteArrays.
  6257      Reimplemented for speed when writing strings or byteArrays.
  6266 #ifdef __SCHTEAM__
  6262 #ifdef __SCHTEAM__
  6267     STObject handle = self.instVarAt(I_handle);
  6263     STObject handle = self.instVarAt(I_handle);
  6268 
  6264 
  6269     if ((handle != STObject.Nil)
  6265     if ((handle != STObject.Nil)
  6270      && (aCollection.isSTString())) {
  6266      && (aCollection.isSTString())) {
  6271         handle.writeCharacters( aCollection.asSTString().characters );
  6267 	handle.writeCharacters( aCollection.asSTString().characters );
  6272         self.instVarAt_put(I_position, STObject.Nil);
  6268 	self.instVarAt_put(I_position, STObject.Nil);
  6273         return __c__._RETURN_self();
  6269 	return __c__._RETURN_self();
  6274     }
  6270     }
  6275 #else
  6271 #else
  6276 
  6272 
  6277     __INST(lastErrorNumber) = nil;
  6273     __INST(lastErrorNumber) = nil;
  6278 
  6274 
  6279     if ((__INST(handleType) == nil)
  6275     if ((__INST(handleType) == nil)
  6280      || (__INST(handleType) == @symbol(filePointer))
  6276      || (__INST(handleType) == @symbol(filePointer))
  6281      || (__INST(handleType) == @symbol(socketFilePointer))
  6277      || (__INST(handleType) == @symbol(socketFilePointer))
  6282      || (__INST(handleType) == @symbol(socketHandle))
  6278      || (__INST(handleType) == @symbol(socketHandle))
  6283      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6279      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6284         OBJ fp;
  6280 	OBJ fp;
  6285 
  6281 
  6286         if (((fp = __INST(handle)) != nil)
  6282 	if (((fp = __INST(handle)) != nil)
  6287             && (__INST(mode) != @symbol(readonly))
  6283 	    && (__INST(mode) != @symbol(readonly))
  6288         ) {
  6284 	) {
  6289             INT len, cnt;
  6285 	    INT len, cnt;
  6290             INT o_offs;
  6286 	    INT o_offs;
  6291             FILEPOINTER f = __FILEVal(fp);
  6287 	    FILEPOINTER f = __FILEVal(fp);
  6292             int _buffered = (__INST(buffered) == true);
  6288 	    int _buffered = (__INST(buffered) == true);
  6293 
  6289 
  6294             if (! f) {
  6290 	    if (! f) {
  6295                 fprintf(stderr, "oops - fileHandle is NULL in nextPutAll:\n");
  6291 		fprintf(stderr, "oops - fileHandle is NULL in nextPutAll:\n");
  6296                 __INST(handle) = nil;
  6292 		__INST(handle) = nil;
  6297                 goto out;
  6293 		goto out;
  6298             }
  6294 	    }
  6299             if (_buffered) {
  6295 	    if (_buffered) {
  6300                 __WRITING__(f)
  6296 		__WRITING__(f)
  6301             }
  6297 	    }
  6302 
  6298 
  6303             if (__isStringLike(aCollection)) {
  6299 	    if (__isStringLike(aCollection)) {
  6304                 OBJ mode = __INST(eolMode);
  6300 		OBJ mode = __INST(eolMode);
  6305                 char *stringP = __stringVal(aCollection);
  6301 		char *stringP = __stringVal(aCollection);
  6306                 len = __stringSize(aCollection);
  6302 		len = __stringSize(aCollection);
  6307 
  6303 
  6308                 if (__INST(binary) != true
  6304 		if (__INST(binary) != true
  6309                     && ((mode == @symbol(cr))
  6305 		    && ((mode == @symbol(cr))
  6310                         || (mode == @symbol(etx))
  6306 			|| (mode == @symbol(etx))
  6311                         || (mode == @symbol(eot))
  6307 			|| (mode == @symbol(eot))
  6312                         || (mode == @symbol(crlf)))
  6308 			|| (mode == @symbol(crlf)))
  6313                     && memchr(stringP, '\n', len) != NULL)
  6309 		    && memchr(stringP, '\n', len) != NULL)
  6314                 {
  6310 		{
  6315                     // there is a '\n' to be translated, replace it into a buffer
  6311 		    // there is a '\n' to be translated, replace it into a buffer
  6316 
  6312 
  6317                     char *end;
  6313 		    char *end;
  6318                     char sep[2];
  6314 		    char sep[2];
  6319                     int sepLen = 1;
  6315 		    int sepLen = 1;
  6320                     int bufLen;
  6316 		    int bufLen;
  6321                     char *buf, *endBuf, *sp, *dp;
  6317 		    char *buf, *endBuf, *sp, *dp;
  6322 
  6318 
  6323                     sep[0] = '\n';
  6319 		    sep[0] = '\n';
  6324                     if (mode == @symbol(crlf)) {
  6320 		    if (mode == @symbol(crlf)) {
  6325                          sep[0] = '\r'; sep[1] = '\n'; sepLen = 2;
  6321 			 sep[0] = '\r'; sep[1] = '\n'; sepLen = 2;
  6326                     } else if (mode == @symbol(cr)) {
  6322 		    } else if (mode == @symbol(cr)) {
  6327                          sep[0] = '\r';
  6323 			 sep[0] = '\r';
  6328                     } else if (mode == @symbol(eot)) {
  6324 		    } else if (mode == @symbol(eot)) {
  6329                          sep[0] = '\004';
  6325 			 sep[0] = '\004';
  6330                     } else if (mode == @symbol(etx)) {
  6326 		    } else if (mode == @symbol(etx)) {
  6331                          sep[0] = '\003';
  6327 			 sep[0] = '\003';
  6332                     }
  6328 		    }
  6333 
  6329 
  6334                     // estimate size of buffer - assume every 4th char is a separator
  6330 		    // estimate size of buffer - assume every 4th char is a separator
  6335                     bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
  6331 		    bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
  6336                     buf = (char *)malloc(bufLen);
  6332 		    buf = (char *)malloc(bufLen);
  6337                     if (buf == NULL) {
  6333 		    if (buf == NULL) {
  6338                         error = __mkSmallInteger(ENOMEM);
  6334 			error = __mkSmallInteger(ENOMEM);
  6339                         goto out;
  6335 			goto out;
  6340                     }
  6336 		    }
  6341 
  6337 
  6342                     endBuf = buf + bufLen;
  6338 		    endBuf = buf + bufLen;
  6343                     end = stringP + len;
  6339 		    end = stringP + len;
  6344                     for (sp = stringP, dp = buf; sp < end; sp++) {
  6340 		    for (sp = stringP, dp = buf; sp < end; sp++) {
  6345                         char c;
  6341 			char c;
  6346 
  6342 
  6347                         if ((dp+sepLen) >= endBuf) {
  6343 			if ((dp+sepLen) >= endBuf) {
  6348                             char *newBuf;
  6344 			    char *newBuf;
  6349 
  6345 
  6350                             bufLen = bufLen * 2;
  6346 			    bufLen = bufLen * 2;
  6351                             newBuf = (char *)realloc(buf, bufLen);
  6347 			    newBuf = (char *)realloc(buf, bufLen);
  6352                             if (newBuf == NULL) {
  6348 			    if (newBuf == NULL) {
  6353                                 free(buf);
  6349 				free(buf);
  6354                                 error = __mkSmallInteger(ENOMEM);
  6350 				error = __mkSmallInteger(ENOMEM);
  6355                                 goto out;
  6351 				goto out;
  6356                             }
  6352 			    }
  6357                             endBuf = newBuf + bufLen;
  6353 			    endBuf = newBuf + bufLen;
  6358                             dp = newBuf + (dp-buf);
  6354 			    dp = newBuf + (dp-buf);
  6359                             buf = newBuf;
  6355 			    buf = newBuf;
  6360                         }
  6356 			}
  6361 
  6357 
  6362                         if ((c = *sp) != '\n') {
  6358 			if ((c = *sp) != '\n') {
  6363                             *dp++ = c;
  6359 			    *dp++ = c;
  6364                         } else {
  6360 			} else {
  6365                             *dp++ = sep[0];
  6361 			    *dp++ = sep[0];
  6366                             if (sepLen == 2) {
  6362 			    if (sepLen == 2) {
  6367                                 *dp++ = sep[1];
  6363 				*dp++ = sep[1];
  6368                             };
  6364 			    };
  6369                         }
  6365 			}
  6370                     }
  6366 		    }
  6371 
  6367 
  6372                     len = dp - buf;
  6368 		    len = dp - buf;
  6373 # ifdef __win32__
  6369 # ifdef __win32__
  6374                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6370 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6375                         cnt = __win32_fwrite(buf, 1, len, f);
  6371 			cnt = __win32_fwrite(buf, 1, len, f);
  6376                     } else
  6372 		    } else
  6377 # endif
  6373 # endif
  6378                     {
  6374 		    {
  6379                         __WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
  6375 			__WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
  6380                     }
  6376 		    }
  6381                     free(buf);
  6377 		    free(buf);
  6382                 } else  {  // No EOL conversion needed
  6378 		} else  {  // No EOL conversion needed
  6383 # ifdef __win32__
  6379 # ifdef __win32__
  6384                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6380 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6385                         cnt = __win32_fwrite(stringP, 1, len, f);
  6381 			cnt = __win32_fwrite(stringP, 1, len, f);
  6386                     } else
  6382 		    } else
  6387 # endif
  6383 # endif
  6388                     {
  6384 		    {
  6389                         o_offs = stringP - (char *)__InstPtr(aCollection);
  6385 			o_offs = stringP - (char *)__InstPtr(aCollection);
  6390                         __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6386 			__WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6391                     }
  6387 		    }
  6392                 }
  6388 		}
  6393             } else {   // Not a String
  6389 	    } else {   // Not a String
  6394                 if (__INST(binary) == true) {
  6390 		if (__INST(binary) == true) {
  6395                     INT offs;
  6391 		    INT offs;
  6396 
  6392 
  6397                     if (__isByteArrayLike(aCollection)) {
  6393 		    if (__isByteArrayLike(aCollection)) {
  6398                         offs = 0;
  6394 			offs = 0;
  6399                         len = __byteArraySize(aCollection);
  6395 			len = __byteArraySize(aCollection);
  6400                     } else if (__isBytes(aCollection)) {
  6396 		    } else if (__isBytes(aCollection)) {
  6401                         offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars));
  6397 			offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars));
  6402                         len = __byteArraySize(aCollection) - offs;
  6398 			len = __byteArraySize(aCollection) - offs;
  6403                     } else
  6399 		    } else
  6404                         goto out;
  6400 			goto out;
  6405 # ifdef __win32__
  6401 # ifdef __win32__
  6406                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6402 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6407                         cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f);
  6403 			cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f);
  6408                     } else
  6404 		    } else
  6409 # endif
  6405 # endif
  6410                     {
  6406 		    {
  6411                         o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element) - (char *)__InstPtr(aCollection);
  6407 			o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element) - (char *)__InstPtr(aCollection);
  6412                         o_offs += offs;
  6408 			o_offs += offs;
  6413                         __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6409 			__WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6414                     }
  6410 		    }
  6415                 } else  // Not binary mode
  6411 		} else  // Not binary mode
  6416                     goto out;
  6412 		    goto out;
  6417             }
  6413 	    }
  6418 
  6414 
  6419             // Now check for errors
  6415 	    // Now check for errors
  6420             if (cnt == len) {
  6416 	    if (cnt == len) {
  6421                 if (__isSmallInteger(__INST(position))) {
  6417 		if (__isSmallInteger(__INST(position))) {
  6422                     INT np = __intVal(__INST(position)) + len;
  6418 		    INT np = __intVal(__INST(position)) + len;
  6423                     OBJ t;
  6419 		    OBJ t;
  6424 
  6420 
  6425                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6421 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6426                 } else {
  6422 		} else {
  6427                     __INST(position) = nil; /* i.e. do not know */
  6423 		    __INST(position) = nil; /* i.e. do not know */
  6428                 }
  6424 		}
  6429                 RETURN (self);
  6425 		RETURN (self);
  6430             }
  6426 	    }
  6431             fprintf(stderr, "cnt=%"_ld_" len=%"_ld_"\n", (INT)cnt, (INT)len);
  6427 	    fprintf(stderr, "cnt=%"_ld_" len=%"_ld_"\n", (INT)cnt, (INT)len);
  6432             error = __mkSmallInteger(__threadErrno);
  6428 	    error = __mkSmallInteger(__threadErrno);
  6433         }
  6429 	}
  6434     }
  6430     }
  6435 out: ;
  6431 out: ;
  6436 #endif /* not SCHTEAM */
  6432 #endif /* not SCHTEAM */
  6437 %}.
  6433 %}.
  6438     error notNil ifTrue:[
  6434     error notNil ifTrue:[
  6439         lastErrorNumber := error.
  6435 	lastErrorNumber := error.
  6440         self writeError:error.
  6436 	self writeError:error.
  6441         ^ self
  6437 	^ self
  6442     ].
  6438     ].
  6443     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6439     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6444     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6440     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6445 
  6441 
  6446     ^ super nextPutAll:aCollection
  6442     ^ super nextPutAll:aCollection
  6453      Answer the number of elements that were appended.
  6449      Answer the number of elements that were appended.
  6454      Buffer should be a byte collection.
  6450      Buffer should be a byte collection.
  6455      I don't know how to write non-bytes to an external stream, but let superclass handle this."
  6451      I don't know how to write non-bytes to an external stream, but let superclass handle this."
  6456 
  6452 
  6457     buffer isSingleByteCollection ifTrue:[
  6453     buffer isSingleByteCollection ifTrue:[
  6458         ^ self nextPutBytes:initialWriteCount from:buffer startingAt:initialOffset.
  6454 	^ self nextPutBytes:initialWriteCount from:buffer startingAt:initialOffset.
  6459     ].
  6455     ].
  6460 
  6456 
  6461     ^ super nextPutAll:initialWriteCount from:buffer startingAt:initialOffset
  6457     ^ super nextPutAll:initialWriteCount from:buffer startingAt:initialOffset
  6462 !
  6458 !
  6463 
  6459 
  6473     if ((__INST(handleType) == nil)
  6469     if ((__INST(handleType) == nil)
  6474      || (__INST(handleType) == @symbol(filePointer))
  6470      || (__INST(handleType) == @symbol(filePointer))
  6475      || (__INST(handleType) == @symbol(socketFilePointer))
  6471      || (__INST(handleType) == @symbol(socketFilePointer))
  6476      || (__INST(handleType) == @symbol(socketHandle))
  6472      || (__INST(handleType) == @symbol(socketHandle))
  6477      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6473      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6478         OBJ fp = __INST(handle);
  6474 	OBJ fp = __INST(handle);
  6479 
  6475 
  6480         if ((fp != nil)
  6476 	if ((fp != nil)
  6481          && (__INST(mode) != @symbol(readonly))
  6477 	 && (__INST(mode) != @symbol(readonly))
  6482          && __bothSmallInteger(start, stop)
  6478 	 && __bothSmallInteger(start, stop)
  6483         ) {
  6479 	) {
  6484             int _buffered = (__INST(buffered) == true);
  6480 	    int _buffered = (__INST(buffered) == true);
  6485             FILEPOINTER f = __FILEVal(fp);
  6481 	    FILEPOINTER f = __FILEVal(fp);
  6486             int offs, len, cnt;
  6482 	    int offs, len, cnt;
  6487             int iStart = __intVal(start);
  6483 	    int iStart = __intVal(start);
  6488             int iStop = __intVal(stop);
  6484 	    int iStop = __intVal(stop);
  6489             int o_offs;
  6485 	    int o_offs;
  6490 
  6486 
  6491             if (_buffered ) {
  6487 	    if (_buffered ) {
  6492                 __WRITING__(f)
  6488 		__WRITING__(f)
  6493             }
  6489 	    }
  6494 
  6490 
  6495             if ((iStart < 1) || (iStop < iStart)) {
  6491 	    if ((iStart < 1) || (iStop < iStart)) {
  6496                 RETURN(self);
  6492 		RETURN(self);
  6497             }
  6493 	    }
  6498             if (__isStringLike(aCollection)) {
  6494 	    if (__isStringLike(aCollection)) {
  6499                 char *stringP;
  6495 		char *stringP;
  6500                 OBJ mode = __INST(eolMode);
  6496 		OBJ mode = __INST(eolMode);
  6501 
  6497 
  6502                 len = __stringSize(aCollection);
  6498 		len = __stringSize(aCollection);
  6503                 if (iStop > len) {
  6499 		if (iStop > len) {
  6504                     RETURN(self);
  6500 		    RETURN(self);
  6505                 }
  6501 		}
  6506                 if (iStop > len)
  6502 		if (iStop > len)
  6507                     iStop = len;
  6503 		    iStop = len;
  6508                 len = iStop - iStart + 1;
  6504 		len = iStop - iStart + 1;
  6509                 stringP = __stringVal(aCollection) + iStart - 1;
  6505 		stringP = __stringVal(aCollection) + iStart - 1;
  6510 
  6506 
  6511                 if (__INST(binary) != true
  6507 		if (__INST(binary) != true
  6512                     && ((mode == @symbol(cr))
  6508 		    && ((mode == @symbol(cr))
  6513                         || (mode == @symbol(etx))
  6509 			|| (mode == @symbol(etx))
  6514                         || (mode == @symbol(eot))
  6510 			|| (mode == @symbol(eot))
  6515                         || (mode == @symbol(crlf)))
  6511 			|| (mode == @symbol(crlf)))
  6516                     && memchr(stringP, '\n', len) != NULL)
  6512 		    && memchr(stringP, '\n', len) != NULL)
  6517                 {
  6513 		{
  6518                     // see if there is a \n which needs to be translated, replace it
  6514 		    // see if there is a \n which needs to be translated, replace it
  6519 
  6515 
  6520                     char *end = stringP + len;
  6516 		    char *end = stringP + len;
  6521                     char sep[2];
  6517 		    char sep[2];
  6522                     int sepLen = 1;
  6518 		    int sepLen = 1;
  6523                     int bufLen;
  6519 		    int bufLen;
  6524                     char *buf, *endBuf, *sp, *dp;
  6520 		    char *buf, *endBuf, *sp, *dp;
  6525 
  6521 
  6526                     sep[0] = '\n';
  6522 		    sep[0] = '\n';
  6527                     if (mode == @symbol(crlf)) {
  6523 		    if (mode == @symbol(crlf)) {
  6528                          sep[0] = '\r'; sep[1] = '\n'; sepLen = 2;
  6524 			 sep[0] = '\r'; sep[1] = '\n'; sepLen = 2;
  6529                     } else if (mode == @symbol(cr)) {
  6525 		    } else if (mode == @symbol(cr)) {
  6530                          sep[0] = '\r';
  6526 			 sep[0] = '\r';
  6531                     } else if (mode == @symbol(eot)) {
  6527 		    } else if (mode == @symbol(eot)) {
  6532                          sep[0] = '\004';
  6528 			 sep[0] = '\004';
  6533                     } else if (mode == @symbol(etx)) {
  6529 		    } else if (mode == @symbol(etx)) {
  6534                          sep[0] = '\003';
  6530 			 sep[0] = '\003';
  6535                     }
  6531 		    }
  6536 
  6532 
  6537                     // estimate size of buffer - assume every 4th char is a separator
  6533 		    // estimate size of buffer - assume every 4th char is a separator
  6538                     bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
  6534 		    bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
  6539                     buf = (char *)malloc(bufLen);
  6535 		    buf = (char *)malloc(bufLen);
  6540                     if (buf == NULL) {
  6536 		    if (buf == NULL) {
  6541                         error = __mkSmallInteger(ENOMEM);
  6537 			error = __mkSmallInteger(ENOMEM);
  6542                         goto out;
  6538 			goto out;
  6543                     }
  6539 		    }
  6544 
  6540 
  6545                     endBuf = buf + bufLen;
  6541 		    endBuf = buf + bufLen;
  6546 
  6542 
  6547                     for (sp = stringP, dp = buf; sp < end; sp++) {
  6543 		    for (sp = stringP, dp = buf; sp < end; sp++) {
  6548                         char c;
  6544 			char c;
  6549 
  6545 
  6550                         if ((dp+sepLen) >= endBuf) {
  6546 			if ((dp+sepLen) >= endBuf) {
  6551                             char *newBuf;
  6547 			    char *newBuf;
  6552 
  6548 
  6553                             bufLen = bufLen * 2;
  6549 			    bufLen = bufLen * 2;
  6554                             newBuf = (char *)realloc(buf, bufLen);
  6550 			    newBuf = (char *)realloc(buf, bufLen);
  6555                             if (newBuf == NULL) {
  6551 			    if (newBuf == NULL) {
  6556                                 free(buf);
  6552 				free(buf);
  6557                                 error = __mkSmallInteger(ENOMEM);
  6553 				error = __mkSmallInteger(ENOMEM);
  6558                                 goto out;
  6554 				goto out;
  6559                             }
  6555 			    }
  6560                             endBuf = newBuf + bufLen;
  6556 			    endBuf = newBuf + bufLen;
  6561                             dp = newBuf + (dp-buf);
  6557 			    dp = newBuf + (dp-buf);
  6562                             buf = newBuf;
  6558 			    buf = newBuf;
  6563                         }
  6559 			}
  6564 
  6560 
  6565                         if ((c = *sp) == '\n') {
  6561 			if ((c = *sp) == '\n') {
  6566                             *dp++ = sep[0];
  6562 			    *dp++ = sep[0];
  6567                             if (sepLen == 2) {
  6563 			    if (sepLen == 2) {
  6568                                 *dp++ = sep[1];
  6564 				*dp++ = sep[1];
  6569                             };
  6565 			    };
  6570                         } else {
  6566 			} else {
  6571                             *dp++ = c;
  6567 			    *dp++ = c;
  6572                         }
  6568 			}
  6573                     }
  6569 		    }
  6574 
  6570 
  6575                     len = dp - buf;
  6571 		    len = dp - buf;
  6576 #ifdef __win32__
  6572 #ifdef __win32__
  6577                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6573 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6578                         cnt = __win32_fwrite(buf, 1, len, f);
  6574 			cnt = __win32_fwrite(buf, 1, len, f);
  6579                     } else
  6575 		    } else
  6580 #endif
  6576 #endif
  6581                     {
  6577 		    {
  6582                         __WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
  6578 			__WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
  6583                     }
  6579 		    }
  6584                     free(buf);
  6580 		    free(buf);
  6585                 } else  {  // No EOL conversion needed
  6581 		} else  {  // No EOL conversion needed
  6586 #ifdef __win32__
  6582 #ifdef __win32__
  6587                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6583 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6588                         cnt = __win32_fwrite(stringP, 1, len, f);
  6584 			cnt = __win32_fwrite(stringP, 1, len, f);
  6589                     } else
  6585 		    } else
  6590 #endif
  6586 #endif
  6591                     {
  6587 		    {
  6592                         o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection);
  6588 			o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection);
  6593                         __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+iStart-1, len, _buffered, __INST(handleType));
  6589 			__WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+iStart-1, len, _buffered, __INST(handleType));
  6594                     }
  6590 		    }
  6595                 }
  6591 		}
  6596             } else {  // Not a string
  6592 	    } else {  // Not a string
  6597                 if (__INST(binary) == true) {
  6593 		if (__INST(binary) == true) {
  6598                     int offs;
  6594 		    int offs;
  6599 
  6595 
  6600                     if (__isByteArrayLike(aCollection)) {
  6596 		    if (__isByteArrayLike(aCollection)) {
  6601                         offs = 0;
  6597 			offs = 0;
  6602                         len = __byteArraySize(aCollection);
  6598 			len = __byteArraySize(aCollection);
  6603                     } else if (__isBytes(aCollection)) {
  6599 		    } else if (__isBytes(aCollection)) {
  6604                         offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars));
  6600 			offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars));
  6605                         len = __byteArraySize(aCollection) - offs;
  6601 			len = __byteArraySize(aCollection) - offs;
  6606                     } else
  6602 		    } else
  6607                         goto out;
  6603 			goto out;
  6608 
  6604 
  6609                     if (iStop > len) {
  6605 		    if (iStop > len) {
  6610                         RETURN(self);
  6606 			RETURN(self);
  6611                     }
  6607 		    }
  6612                     if (iStop > len)
  6608 		    if (iStop > len)
  6613                         iStop = len;
  6609 			iStop = len;
  6614                     len = iStop - iStart + 1;
  6610 		    len = iStop - iStart + 1;
  6615                     offs += iStart - 1;
  6611 		    offs += iStart - 1;
  6616 #ifdef __win32__
  6612 #ifdef __win32__
  6617                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6613 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6618                         cnt = __win32_fwrite(__stringVal(aCollection)+iStart-1, 1, len, f);
  6614 			cnt = __win32_fwrite(__stringVal(aCollection)+iStart-1, 1, len, f);
  6619                     } else
  6615 		    } else
  6620 #endif
  6616 #endif
  6621                     {
  6617 		    {
  6622                         o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element)-(char *)__InstPtr(aCollection);
  6618 			o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element)-(char *)__InstPtr(aCollection);
  6623                         __WRITEBYTES_OBJ__(cnt, f,  aCollection, o_offs+offs, len, _buffered, __INST(handleType));
  6619 			__WRITEBYTES_OBJ__(cnt, f,  aCollection, o_offs+offs, len, _buffered, __INST(handleType));
  6624                     }
  6620 		    }
  6625                 } else
  6621 		} else
  6626                     goto out;
  6622 		    goto out;
  6627             }
  6623 	    }
  6628             if (cnt == len) {
  6624 	    if (cnt == len) {
  6629                 if (__isSmallInteger(__INST(position))) {
  6625 		if (__isSmallInteger(__INST(position))) {
  6630                     INT np = __intVal(__INST(position)) + len;
  6626 		    INT np = __intVal(__INST(position)) + len;
  6631                     OBJ t;
  6627 		    OBJ t;
  6632 
  6628 
  6633                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6629 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6634                 } else {
  6630 		} else {
  6635                     __INST(position) = nil; /* i.e. do not know */
  6631 		    __INST(position) = nil; /* i.e. do not know */
  6636                 }
  6632 		}
  6637                 RETURN (self);
  6633 		RETURN (self);
  6638             }
  6634 	    }
  6639             error = __mkSmallInteger(__threadErrno);
  6635 	    error = __mkSmallInteger(__threadErrno);
  6640         }
  6636 	}
  6641     }
  6637     }
  6642 out: ;
  6638 out: ;
  6643 %}.
  6639 %}.
  6644     error notNil ifTrue:[
  6640     error notNil ifTrue:[
  6645         lastErrorNumber := error.
  6641 	lastErrorNumber := error.
  6646         self writeError:error.
  6642 	self writeError:error.
  6647         ^ self
  6643 	^ self
  6648     ].
  6644     ].
  6649     ^ super nextPutAll:aCollection startingAt:start to:stop
  6645     ^ super nextPutAll:aCollection startingAt:start to:stop
  6650 !
  6646 !
  6651 
  6647 
  6652 nextPutAllUnicode:aString
  6648 nextPutAllUnicode:aString
  6653     "normal streams can not handle multi-byte characters, so convert them to utf8.
  6649     "normal streams can not handle multi-byte characters, so convert them to utf8.
  6654      This is needed, so that you can do ('something' asUnicode16String errorPrintCR)"
  6650      This is needed, so that you can do ('something' asUnicode16String errorPrintCR)"
  6655 
  6651 
  6656     aString do:[:eachCharacter|
  6652     aString do:[:eachCharacter|
  6657         self nextPutUtf8:eachCharacter.
  6653 	self nextPutUtf8:eachCharacter.
  6658     ].
  6654     ].
  6659 
  6655 
  6660     "
  6656     "
  6661         'Bönnigheim' asUnicode16String errorPrintCR
  6657 	'Bönnigheim' asUnicode16String errorPrintCR
  6662     "
  6658     "
  6663 !
  6659 !
  6664 
  6660 
  6665 nextPutBytes:count from:anObject startingAt:start
  6661 nextPutBytes:count from:anObject startingAt:start
  6666     "write count bytes from an object starting at index start.
  6662     "write count bytes from an object starting at index start.
  6669      (i.e. be a ByteArray, String, Float- or DoubleArray),
  6665      (i.e. be a ByteArray, String, Float- or DoubleArray),
  6670      or an externalBytes object (with known size).
  6666      or an externalBytes object (with known size).
  6671 
  6667 
  6672      Use with care - non object oriented i/o.
  6668      Use with care - non object oriented i/o.
  6673      Warning:
  6669      Warning:
  6674         in general, you cannot use this method to pass non-byte data to other
  6670 	in general, you cannot use this method to pass non-byte data to other
  6675         architectures (unless you prepared the buffer with care),
  6671 	architectures (unless you prepared the buffer with care),
  6676         since it does not care for byte order or float representation."
  6672 	since it does not care for byte order or float representation."
  6677 
  6673 
  6678     |error|
  6674     |error|
  6679 
  6675 
  6680 %{
  6676 %{
  6681 #ifdef __SCHTEAM__
  6677 #ifdef __SCHTEAM__
  6682     byte[] bytes;
  6678     byte[] bytes;
  6683     STObject handle = self.instVarAt(I_handle);
  6679     STObject handle = self.instVarAt(I_handle);
  6684 
  6680 
  6685     if (anObject.isSTString()) {
  6681     if (anObject.isSTString()) {
  6686         char[] chars = anObject.asSTString().characters;
  6682 	char[] chars = anObject.asSTString().characters;
  6687         handle.writeCharacters(chars, start.intValue()-1, count.intValue());
  6683 	handle.writeCharacters(chars, start.intValue()-1, count.intValue());
  6688         self.instVarAt_put(I_position, STObject.Nil);
  6684 	self.instVarAt_put(I_position, STObject.Nil);
  6689         return context._RETURN(count);
  6685 	return context._RETURN(count);
  6690     }
  6686     }
  6691     if (anObject.isSymbol()) {
  6687     if (anObject.isSymbol()) {
  6692         java.lang.String chars = anObject.asSTSymbol().characters;
  6688 	java.lang.String chars = anObject.asSTSymbol().characters;
  6693         handle.writeString(chars, start.intValue()-1, count.intValue());
  6689 	handle.writeString(chars, start.intValue()-1, count.intValue());
  6694         self.instVarAt_put(I_position, STObject.Nil);
  6690 	self.instVarAt_put(I_position, STObject.Nil);
  6695         return context._RETURN(count);
  6691 	return context._RETURN(count);
  6696     }
  6692     }
  6697 #else
  6693 #else
  6698     int ret;
  6694     int ret;
  6699     int objSize, nInstBytes;
  6695     int objSize, nInstBytes;
  6700     char *extPtr;
  6696     char *extPtr;
  6704     if ((__INST(handleType) == nil)
  6700     if ((__INST(handleType) == nil)
  6705      || (__INST(handleType) == @symbol(filePointer))
  6701      || (__INST(handleType) == @symbol(filePointer))
  6706      || (__INST(handleType) == @symbol(socketFilePointer))
  6702      || (__INST(handleType) == @symbol(socketFilePointer))
  6707      || (__INST(handleType) == @symbol(socketHandle))
  6703      || (__INST(handleType) == @symbol(socketHandle))
  6708      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6704      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6709         if (((fp = __INST(handle)) != nil)
  6705 	if (((fp = __INST(handle)) != nil)
  6710             && (__INST(mode) != @symbol(readonly))
  6706 	    && (__INST(mode) != @symbol(readonly))
  6711             && __bothSmallInteger(count, start)
  6707 	    && __bothSmallInteger(count, start)
  6712         ) {
  6708 	) {
  6713             int _buffered = (__INST(buffered) == true);
  6709 	    int _buffered = (__INST(buffered) == true);
  6714             FILEPOINTER f = __FILEVal(fp);
  6710 	    FILEPOINTER f = __FILEVal(fp);
  6715             int len = __intVal(count);
  6711 	    int len = __intVal(count);
  6716             int offs = __intVal(start) - 1;
  6712 	    int offs = __intVal(start) - 1;
  6717 
  6713 
  6718             if (__isExternalBytesLike(anObject)) {
  6714 	    if (__isExternalBytesLike(anObject)) {
  6719                 OBJ sz;
  6715 		OBJ sz;
  6720 
  6716 
  6721                 nInstBytes = 0;
  6717 		nInstBytes = 0;
  6722                 extPtr = (char *)__externalBytesAddress(anObject);
  6718 		extPtr = (char *)__externalBytesAddress(anObject);
  6723                 if (extPtr == NULL) goto bad;
  6719 		if (extPtr == NULL) goto bad;
  6724                 sz = __externalBytesSize(anObject);
  6720 		sz = __externalBytesSize(anObject);
  6725                 if (__isSmallInteger(sz)) {
  6721 		if (__isSmallInteger(sz)) {
  6726                     objSize = __intVal(sz);
  6722 		    objSize = __intVal(sz);
  6727                 } else {
  6723 		} else {
  6728                     objSize = 0; /* unknown */
  6724 		    objSize = 0; /* unknown */
  6729                 }
  6725 		}
  6730             } else {
  6726 	    } else {
  6731                 OBJ oClass = __Class(anObject);
  6727 		OBJ oClass = __Class(anObject);
  6732                 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  6728 		int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  6733 
  6729 
  6734                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  6730 		nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  6735                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  6731 		switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  6736                     case BYTEARRAY:
  6732 		    case BYTEARRAY:
  6737                     case WORDARRAY:
  6733 		    case WORDARRAY:
  6738                     case LONGARRAY:
  6734 		    case LONGARRAY:
  6739                     case SWORDARRAY:
  6735 		    case SWORDARRAY:
  6740                     case SLONGARRAY:
  6736 		    case SLONGARRAY:
  6741                     case FLOATARRAY:
  6737 		    case FLOATARRAY:
  6742                         break;
  6738 			break;
  6743                     case DOUBLEARRAY:
  6739 		    case DOUBLEARRAY:
  6744 # ifdef __NEED_DOUBLE_ALIGN
  6740 # ifdef __NEED_DOUBLE_ALIGN
  6745                         nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  6741 			nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  6746 # endif
  6742 # endif
  6747                         break;
  6743 			break;
  6748                     case LONGLONGARRAY:
  6744 		    case LONGLONGARRAY:
  6749                     case SLONGLONGARRAY:
  6745 		    case SLONGLONGARRAY:
  6750 # ifdef __NEED_LONGLONG_ALIGN
  6746 # ifdef __NEED_LONGLONG_ALIGN
  6751                         nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  6747 			nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  6752 # endif
  6748 # endif
  6753                         break;
  6749 			break;
  6754                     default:
  6750 		    default:
  6755                         goto bad;
  6751 			goto bad;
  6756                 }
  6752 		}
  6757                 extPtr = (char *)0;
  6753 		extPtr = (char *)0;
  6758                 objSize = __Size(anObject) - nInstBytes;
  6754 		objSize = __Size(anObject) - nInstBytes;
  6759             }
  6755 	    }
  6760             if ( (offs >= 0) && (len >= 0) && (objSize >= (len + offs)) ) {
  6756 	    if ( (offs >= 0) && (len >= 0) && (objSize >= (len + offs)) ) {
  6761                 int cnt;
  6757 		int cnt;
  6762 
  6758 
  6763                 if (_buffered) {
  6759 		if (_buffered) {
  6764                     __WRITING__(f)
  6760 		    __WRITING__(f)
  6765                 }
  6761 		}
  6766 
  6762 
  6767                 if (extPtr) {
  6763 		if (extPtr) {
  6768 # ifdef __win32__
  6764 # ifdef __win32__
  6769                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6765 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6770                         cnt = __win32_fwrite(extPtr+offs, 1, len, f);
  6766 			cnt = __win32_fwrite(extPtr+offs, 1, len, f);
  6771                     } else
  6767 		    } else
  6772 # endif
  6768 # endif
  6773                     {
  6769 		    {
  6774                         __WRITEBYTES__(cnt, f, extPtr+offs, len, _buffered, __INST(handleType));
  6770 			__WRITEBYTES__(cnt, f, extPtr+offs, len, _buffered, __INST(handleType));
  6775                     }
  6771 		    }
  6776                 } else {
  6772 		} else {
  6777                     /*
  6773 		    /*
  6778                      * on interrupt, anObject may be moved to another location.
  6774 		     * on interrupt, anObject may be moved to another location.
  6779                      * So we pass anObject, and the offset to the __WRITEBYTES_OBJ__ macro.
  6775 		     * So we pass anObject, and the offset to the __WRITEBYTES_OBJ__ macro.
  6780                      */
  6776 		     */
  6781                     offs += nInstBytes;
  6777 		    offs += nInstBytes;
  6782 # ifdef __win32__
  6778 # ifdef __win32__
  6783                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6779 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6784                         cnt = __win32_fwrite((char *)anObject+offs, 1, len, f);
  6780 			cnt = __win32_fwrite((char *)anObject+offs, 1, len, f);
  6785                     } else
  6781 		    } else
  6786 # endif
  6782 # endif
  6787                     {
  6783 		    {
  6788                          __WRITEBYTES_OBJ__(cnt, f, anObject, offs, len, _buffered, __INST(handleType));
  6784 			 __WRITEBYTES_OBJ__(cnt, f, anObject, offs, len, _buffered, __INST(handleType));
  6789                     }
  6785 		    }
  6790                 }
  6786 		}
  6791 
  6787 
  6792                 if (cnt >= 0) {
  6788 		if (cnt >= 0) {
  6793                     if (__isSmallInteger(__INST(position))) {
  6789 		    if (__isSmallInteger(__INST(position))) {
  6794                         INT np = __intVal(__INST(position)) + cnt;
  6790 			INT np = __intVal(__INST(position)) + cnt;
  6795                         OBJ t;
  6791 			OBJ t;
  6796 
  6792 
  6797                         t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6793 			t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6798                     } else {
  6794 		    } else {
  6799                         __INST(position) = nil; /* i.e. do not know */
  6795 			__INST(position) = nil; /* i.e. do not know */
  6800                     }
  6796 		    }
  6801                     RETURN ( __mkSmallInteger(cnt) );
  6797 		    RETURN ( __mkSmallInteger(cnt) );
  6802                 } else /* cnt < 0 */ {
  6798 		} else /* cnt < 0 */ {
  6803                     if (
  6799 		    if (
  6804 # ifdef EWOULDBLOCK
  6800 # ifdef EWOULDBLOCK
  6805                         (__threadErrno == EWOULDBLOCK) ||
  6801 			(__threadErrno == EWOULDBLOCK) ||
  6806 # endif
  6802 # endif
  6807                         (__threadErrno == EAGAIN)
  6803 			(__threadErrno == EAGAIN)
  6808                     ) {
  6804 		    ) {
  6809                         RETURN ( __mkSmallInteger(0) );
  6805 			RETURN ( __mkSmallInteger(0) );
  6810                     }
  6806 		    }
  6811                     __INST(position) = nil; /* i.e. do not know */
  6807 		    __INST(position) = nil; /* i.e. do not know */
  6812                     error = __mkSmallInteger(__threadErrno);
  6808 		    error = __mkSmallInteger(__threadErrno);
  6813                 }
  6809 		}
  6814             }
  6810 	    }
  6815         }
  6811 	}
  6816     }
  6812     }
  6817 bad: ;
  6813 bad: ;
  6818 #endif /* not SCHTEAM */
  6814 #endif /* not SCHTEAM */
  6819 %}.
  6815 %}.
  6820     error notNil ifTrue:[
  6816     error notNil ifTrue:[
  6821         lastErrorNumber := error.
  6817 	lastErrorNumber := error.
  6822         self writeError:error.
  6818 	self writeError:error.
  6823         ^ 0
  6819 	^ 0
  6824     ].
  6820     ].
  6825     handle isNil ifTrue:[self errorNotOpen. ^ 0].
  6821     handle isNil ifTrue:[self errorNotOpen. ^ 0].
  6826     (mode == #readonly) ifTrue:[self errorReadOnly. ^ 0].
  6822     (mode == #readonly) ifTrue:[self errorReadOnly. ^ 0].
  6827     self primitiveFailed.
  6823     self primitiveFailed.
  6828     ^ 0.
  6824     ^ 0.