ExternalStream.st
changeset 17115 2ef08a902c34
parent 17078 f3ded8a6f9d9
child 17332 f223abac93ca
equal deleted inserted replaced
17114:592d806673a8 17115:2ef08a902c34
   200 #ifdef DEBUGGING
   200 #ifdef DEBUGGING
   201   extern char *__survStartPtr, *__survEndPtr;
   201   extern char *__survStartPtr, *__survEndPtr;
   202 # define DEBUGBUFFER(buf)  \
   202 # define DEBUGBUFFER(buf)  \
   203     if (((char *)(buf) >= __survStartPtr) \
   203     if (((char *)(buf) >= __survStartPtr) \
   204      && ((char *)(buf) < __survEndPtr)) { \
   204      && ((char *)(buf) < __survEndPtr)) { \
   205         __fatal0("read into survivor\n"); \
   205 	__fatal0("read into survivor\n"); \
   206     }
   206     }
   207 
   207 
   208 #else
   208 #else
   209 # define DEBUGBUFFER(buf) /* nothing */
   209 # define DEBUGBUFFER(buf) /* nothing */
   210 #endif
   210 #endif
   223 
   223 
   224 #ifdef WIN32
   224 #ifdef WIN32
   225 // Win returns from ReadFile() with false and _threadErrno == 0 on end of pipe.
   225 // Win returns from ReadFile() with false and _threadErrno == 0 on end of pipe.
   226 // We don't know why
   226 // We don't know why
   227 #  define READ(ret, f, cp, n, handleType) { \
   227 #  define READ(ret, f, cp, n, handleType) { \
   228         if (handleType == @symbol(socketHandle)) { \
   228 	if (handleType == @symbol(socketHandle)) { \
   229           (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \
   229 	  (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \
   230         } else { \
   230 	} else { \
   231           HANDLE h = _get_osfhandle(fileno(f)); \
   231 	  HANDLE h = _get_osfhandle(fileno(f)); \
   232           if (handleType == @symbol(socketFilePointer)) { \
   232 	  if (handleType == @symbol(socketFilePointer)) { \
   233             (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   233 	    (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   234           } else { \
   234 	  } else { \
   235             int __res; \
   235 	    int __res; \
   236             (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   236 	    (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   237             (ret) = (ret) ? __res : ((__threadErrno == EPIPE || __threadErrno == 0) ? 0 : -1); \
   237 	    (ret) = (ret) ? __res : ((__threadErrno == EPIPE || __threadErrno == 0) ? 0 : -1); \
   238           } \
   238 	  } \
   239         } \
   239 	} \
   240       }
   240       }
   241 
   241 
   242 #  define WRITE(ret, f, cp, n, handleType) { \
   242 #  define WRITE(ret, f, cp, n, handleType) { \
   243         if (handleType == @symbol(socketHandle)) { \
   243 	if (handleType == @symbol(socketHandle)) { \
   244           (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \
   244 	  (ret) = __STX_WSA_NOINT_CALL4("send", send, (f), (cp), (n), 0); \
   245         } else {\
   245 	} else {\
   246           HANDLE h = _get_osfhandle(fileno(f)); \
   246 	  HANDLE h = _get_osfhandle(fileno(f)); \
   247           if (handleType == @symbol(socketFilePointer)) { \
   247 	  if (handleType == @symbol(socketFilePointer)) { \
   248             (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   248 	    (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   249           } else {\
   249 	  } else {\
   250             int __res; \
   250 	    int __res; \
   251             (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\
   251 	    (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\
   252             (ret) = (ret) ? __res : -1; \
   252 	    (ret) = (ret) ? __res : -1; \
   253           } \
   253 	  } \
   254         } \
   254 	} \
   255       }
   255       }
   256 
   256 
   257 # define FFLUSH(fp)             fflush(fp)
   257 # define FFLUSH(fp)             fflush(fp)
   258 # undef STDIO_NEEDS_FSEEK
   258 # undef STDIO_NEEDS_FSEEK
   259 # define FILEPOINTER            FILE *
   259 # define FILEPOINTER            FILE *
   260 # define FILENO(f)              fileno(f)
   260 # define FILENO(f)              fileno(f)
   261 
   261 
   262 # define __READING__(f)                          \
   262 # define __READING__(f)                          \
   263     if ((__INST(didWrite) != false)              \
   263     if ((__INST(didWrite) != false)              \
   264      && (__INST(mode) == @symbol(readwrite))) {  \
   264      && (__INST(mode) == @symbol(readwrite))) {  \
   265         __INST(didWrite) = false;                \
   265 	__INST(didWrite) = false;                \
   266         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   266 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   267     }
   267     }
   268 
   268 
   269 # define __WRITING__(f)                          \
   269 # define __WRITING__(f)                          \
   270     if ((__INST(didWrite) != true)               \
   270     if ((__INST(didWrite) != true)               \
   271      && (__INST(mode) == @symbol(readwrite))) {  \
   271      && (__INST(mode) == @symbol(readwrite))) {  \
   272         __INST(didWrite) = true;                 \
   272 	__INST(didWrite) = true;                 \
   273         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   273 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   274     }
   274     }
   275 
   275 
   276 # define __UNGETC__(c, f, isBuffered)                   \
   276 # define __UNGETC__(c, f, isBuffered)                   \
   277     if (isBuffered) {                                   \
   277     if (isBuffered) {                                   \
   278         ungetc((c), (f));                               \
   278 	ungetc((c), (f));                               \
   279     } else {                                            \
   279     } else {                                            \
   280       __INST(readAhead) = __mkSmallInteger((c));        \
   280       __INST(readAhead) = __mkSmallInteger((c));        \
   281     }
   281     }
   282 
   282 
   283 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \
   283 # define __READBYTE__(ret, f, buf, isBuffered, handleType) \
   284     if (isBuffered) {                                   \
   284     if (isBuffered) {                                   \
   285         for (;;) {                                      \
   285 	for (;;) {                                      \
   286             CLEAR_ERRNO;                                \
   286 	    CLEAR_ERRNO;                                \
   287             (ret) = getc(f);                            \
   287 	    (ret) = getc(f);                            \
   288             if ((ret) >= 0) {                           \
   288 	    if ((ret) >= 0) {                           \
   289                 *(buf) = (ret);                         \
   289 		*(buf) = (ret);                         \
   290                 (ret) = 1;                              \
   290 		(ret) = 1;                              \
   291             } else if (ferror(f)) {                     \
   291 	    } else if (ferror(f)) {                     \
   292                 if (__threadErrno == EINTR) {           \
   292 		if (__threadErrno == EINTR) {           \
   293                     clearerr(f);                        \
   293 		    clearerr(f);                        \
   294                     continue;                           \
   294 		    continue;                           \
   295                 }                                       \
   295 		}                                       \
   296             } else {                                    \
   296 	    } else {                                    \
   297                 (ret) = 0;                              \
   297 		(ret) = 0;                              \
   298             }                                           \
   298 	    }                                           \
   299             break;                                      \
   299 	    break;                                      \
   300         }                                               \
   300 	}                                               \
   301     } else {                                            \
   301     } else {                                            \
   302         OBJ rA = __INST(readAhead);                     \
   302 	OBJ rA = __INST(readAhead);                     \
   303         if (rA != nil) {                                \
   303 	if (rA != nil) {                                \
   304             *(buf) = (char)__intVal(rA);                \
   304 	    *(buf) = (char)__intVal(rA);                \
   305             __INST(readAhead) = nil;                    \
   305 	    __INST(readAhead) = nil;                    \
   306             (ret) = 1;                                  \
   306 	    (ret) = 1;                                  \
   307         } else {                                        \
   307 	} else {                                        \
   308             for (;;) {                                  \
   308 	    for (;;) {                                  \
   309                 CLEAR_ERRNO;                            \
   309 		CLEAR_ERRNO;                            \
   310                 READ((ret), f, buf, 1, handleType);       \
   310 		READ((ret), f, buf, 1, handleType);       \
   311                 if ((ret) >= 0 || __threadErrno != EINTR) \
   311 		if ((ret) >= 0 || __threadErrno != EINTR) \
   312                     break;                              \
   312 		    break;                              \
   313             }                                           \
   313 	    }                                           \
   314         }                                               \
   314 	}                                               \
   315     }
   315     }
   316 
   316 
   317   /*
   317   /*
   318    * read_bytes into a c-buffer
   318    * read_bytes into a c-buffer
   319    * (which may NOT move)
   319    * (which may NOT move)
   320    */
   320    */
   321 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
   321 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
   322     (ret) = 0;                                          \
   322     (ret) = 0;                                          \
   323     if (isBuffered) {                                   \
   323     if (isBuffered) {                                   \
   324         int __offs = 0;                                 \
   324 	int __offs = 0;                                 \
   325         while (__offs < (cnt)) {                        \
   325 	while (__offs < (cnt)) {                        \
   326             CLEAR_ERRNO;                                \
   326 	    CLEAR_ERRNO;                                \
   327             (ret) = getc(f);                            \
   327 	    (ret) = getc(f);                            \
   328             if ((ret) < 0) {                            \
   328 	    if ((ret) < 0) {                            \
   329                 if (ferror(f)) {                        \
   329 		if (ferror(f)) {                        \
   330                     if (__threadErrno == EINTR) {       \
   330 		    if (__threadErrno == EINTR) {       \
   331                         clearerr(f);                    \
   331 			clearerr(f);                    \
   332                         continue;                       \
   332 			continue;                       \
   333                     }                                   \
   333 		    }                                   \
   334                 } else {                                \
   334 		} else {                                \
   335                     (ret) = 0;                          \
   335 		    (ret) = 0;                          \
   336                 }                                       \
   336 		}                                       \
   337                 break;                                  \
   337 		break;                                  \
   338             }                                           \
   338 	    }                                           \
   339             (buf)[__offs++] = (ret);                    \
   339 	    (buf)[__offs++] = (ret);                    \
   340         }                                               \
   340 	}                                               \
   341         if (__offs > 0)                                 \
   341 	if (__offs > 0)                                 \
   342             (ret) = __offs;                             \
   342 	    (ret) = __offs;                             \
   343     } else {                                            \
   343     } else {                                            \
   344         int __offs = 0;                                 \
   344 	int __offs = 0;                                 \
   345                                                         \
   345 							\
   346         while (__offs < (cnt)) {                        \
   346 	while (__offs < (cnt)) {                        \
   347             OBJ rA = __INST(readAhead);                 \
   347 	    OBJ rA = __INST(readAhead);                 \
   348             if (rA != nil) {                            \
   348 	    if (rA != nil) {                            \
   349                 (buf)[__offs] = __intVal(rA);           \
   349 		(buf)[__offs] = __intVal(rA);           \
   350                 __INST(readAhead) = nil;                \
   350 		__INST(readAhead) = nil;                \
   351                 (ret) = 1;                              \
   351 		(ret) = 1;                              \
   352             } else {                                    \
   352 	    } else {                                    \
   353                 CLEAR_ERRNO;                            \
   353 		CLEAR_ERRNO;                            \
   354                 READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   354 		READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   355                 if ((ret) <= 0) {                       \
   355 		if ((ret) <= 0) {                       \
   356                     if ((ret) < 0 && __threadErrno == EINTR) {  \
   356 		    if ((ret) < 0 && __threadErrno == EINTR) {  \
   357                         continue;                       \
   357 			continue;                       \
   358                     }                                   \
   358 		    }                                   \
   359                     break;                              \
   359 		    break;                              \
   360                 }                                       \
   360 		}                                       \
   361             }                                           \
   361 	    }                                           \
   362             __offs += (ret);                            \
   362 	    __offs += (ret);                            \
   363         }                                               \
   363 	}                                               \
   364         if (__offs > 0)                                 \
   364 	if (__offs > 0)                                 \
   365             (ret) = __offs;                             \
   365 	    (ret) = __offs;                             \
   366    }
   366    }
   367 
   367 
   368 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   368 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   369   {                                                     \
   369   {                                                     \
   370     int __offs = 0;                                     \
   370     int __offs = 0;                                     \
   371     int oldFlags;                                       \
   371     int oldFlags;                                       \
   372                                                         \
   372 							\
   373     (ret) = 0;                                          \
   373     (ret) = 0;                                          \
   374     if (isBuffered) {                                   \
   374     if (isBuffered) {                                   \
   375         while (__offs < (cnt)) {                        \
   375 	while (__offs < (cnt)) {                        \
   376             CLEAR_ERRNO;                                \
   376 	    CLEAR_ERRNO;                                \
   377             (ret) = getc(f);                            \
   377 	    (ret) = getc(f);                            \
   378             if ((ret) < 0) {                            \
   378 	    if ((ret) < 0) {                            \
   379                 if (ferror(f)) {                        \
   379 		if (ferror(f)) {                        \
   380                     if (__threadErrno == EINTR) {       \
   380 		    if (__threadErrno == EINTR) {       \
   381                         clearerr(f);                    \
   381 			clearerr(f);                    \
   382                         continue;                       \
   382 			continue;                       \
   383                     }                                   \
   383 		    }                                   \
   384                 } else {                                \
   384 		} else {                                \
   385                     (ret) = 0;                          \
   385 		    (ret) = 0;                          \
   386                 }                                       \
   386 		}                                       \
   387                 break;                                  \
   387 		break;                                  \
   388             }                                           \
   388 	    }                                           \
   389             (buf)[__offs++] = (ret);                    \
   389 	    (buf)[__offs++] = (ret);                    \
   390         }                                               \
   390 	}                                               \
   391         (ret) = __offs;                                 \
   391 	(ret) = __offs;                                 \
   392     } else {                                            \
   392     } else {                                            \
   393         while (__offs < (cnt)) {                        \
   393 	while (__offs < (cnt)) {                        \
   394             OBJ rA = __INST(readAhead);                 \
   394 	    OBJ rA = __INST(readAhead);                 \
   395             if (rA != nil) {                            \
   395 	    if (rA != nil) {                            \
   396                 (buf)[__offs] = __intVal(rA);           \
   396 		(buf)[__offs] = __intVal(rA);           \
   397                 __INST(readAhead) = nil;                \
   397 		__INST(readAhead) = nil;                \
   398                 (ret) = 1;                              \
   398 		(ret) = 1;                              \
   399                 __offs ++;                              \
   399 		__offs ++;                              \
   400                 continue;                               \
   400 		continue;                               \
   401             }                                           \
   401 	    }                                           \
   402             CLEAR_ERRNO;                                \
   402 	    CLEAR_ERRNO;                                \
   403             {                                           \
   403 	    {                                           \
   404               int res = 0;                              \
   404 	      int res = 0;                              \
   405               if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res), 1)) \
   405 	      if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res), 1)) \
   406                   || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \
   406 		  || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \
   407                   || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0), 1))) { \
   407 		  || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0), 1))) { \
   408                   if (res > 0) {                        \
   408 		  if (res > 0) {                        \
   409                       if (res > ((cnt)-__offs))         \
   409 		      if (res > ((cnt)-__offs))         \
   410                           res = (cnt)-__offs;           \
   410 			  res = (cnt)-__offs;           \
   411                       READ((ret), f, (buf)+__offs, res, handleType); \
   411 		      READ((ret), f, (buf)+__offs, res, handleType); \
   412                   } else {                              \
   412 		  } else {                              \
   413                       (ret) = 0;                        \
   413 		      (ret) = 0;                        \
   414                       break;                            \
   414 		      break;                            \
   415                   }                                     \
   415 		  }                                     \
   416               } else {                                  \
   416 	      } else {                                  \
   417                   READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   417 		  READ((ret), f, (buf)+__offs, (cnt)-__offs, handleType); \
   418               }                                         \
   418 	      }                                         \
   419             }                                           \
   419 	    }                                           \
   420             if ((ret) <= 0) {                           \
   420 	    if ((ret) <= 0) {                           \
   421                 if (ret < 0 && __threadErrno == EINTR)  \
   421 		if (ret < 0 && __threadErrno == EINTR)  \
   422                     continue;                           \
   422 		    continue;                           \
   423                 break;                                  \
   423 		break;                                  \
   424             }                                           \
   424 	    }                                           \
   425             __offs += (ret);                            \
   425 	    __offs += (ret);                            \
   426         }                                               \
   426 	}                                               \
   427         (ret) = __offs;                                 \
   427 	(ret) = __offs;                                 \
   428     }                                                   \
   428     }                                                   \
   429   }
   429   }
   430 
   430 
   431 # define IO_BUFFER_SIZE        (8*1024)
   431 # define IO_BUFFER_SIZE        (8*1024)
   432 
   432 
   433 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   433 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   434   {                                                     \
   434   {                                                     \
   435     int __ooffs = obj_offs;                             \
   435     int __ooffs = obj_offs;                             \
   436     int __offs = 0;                                     \
   436     int __offs = 0;                                     \
   437     char *buf = (char *)(obj);                          \
   437     char *buf = (char *)(obj);                          \
   438                                                         \
   438 							\
   439     (ret) = 0;                                          \
   439     (ret) = 0;                                          \
   440     if (isBuffered) {                                   \
   440     if (isBuffered) {                                   \
   441         while (__offs < (cnt)) {                        \
   441 	while (__offs < (cnt)) {                        \
   442             CLEAR_ERRNO;                                \
   442 	    CLEAR_ERRNO;                                \
   443             (ret) = getc(f);                            \
   443 	    (ret) = getc(f);                            \
   444             if ((ret) < 0) {                            \
   444 	    if ((ret) < 0) {                            \
   445                 if (ferror(f)) {                        \
   445 		if (ferror(f)) {                        \
   446                     if (__threadErrno == EINTR) {       \
   446 		    if (__threadErrno == EINTR) {       \
   447                         clearerr(f);                    \
   447 			clearerr(f);                    \
   448                         /* refetch */                   \
   448 			/* refetch */                   \
   449                         buf = (char *)(obj);   \
   449 			buf = (char *)(obj);   \
   450                         continue;                       \
   450 			continue;                       \
   451                     }                                   \
   451 		    }                                   \
   452                 } else {                                \
   452 		} else {                                \
   453                     (ret) = 0;                          \
   453 		    (ret) = 0;                          \
   454                 }                                       \
   454 		}                                       \
   455                 break;                                  \
   455 		break;                                  \
   456             }                                           \
   456 	    }                                           \
   457             (buf)[__ooffs+__offs] = (ret);              \
   457 	    (buf)[__ooffs+__offs] = (ret);              \
   458             __offs++;                                   \
   458 	    __offs++;                                   \
   459         }                                               \
   459 	}                                               \
   460         if (__offs > 0)                                 \
   460 	if (__offs > 0)                                 \
   461             (ret) = __offs;                             \
   461 	    (ret) = __offs;                             \
   462     } else {                                            \
   462     } else {                                            \
   463         while (__offs < (cnt)) {                        \
   463 	while (__offs < (cnt)) {                        \
   464             char __buf[IO_BUFFER_SIZE];                 \
   464 	    char __buf[IO_BUFFER_SIZE];                 \
   465             OBJ rA = __INST(readAhead);                 \
   465 	    OBJ rA = __INST(readAhead);                 \
   466             if (rA != nil) {                            \
   466 	    if (rA != nil) {                            \
   467                 (buf)[__ooffs+__offs] = __intVal(rA);   \
   467 		(buf)[__ooffs+__offs] = __intVal(rA);   \
   468                 __INST(readAhead) = nil;                \
   468 		__INST(readAhead) = nil;                \
   469                 (ret) = 1;                              \
   469 		(ret) = 1;                              \
   470             } else {                                    \
   470 	    } else {                                    \
   471                 int l;                                  \
   471 		int l;                                  \
   472                 CLEAR_ERRNO;                            \
   472 		CLEAR_ERRNO;                            \
   473                 l = (cnt)-__offs;                       \
   473 		l = (cnt)-__offs;                       \
   474                 if ( l > IO_BUFFER_SIZE)                \
   474 		if ( l > IO_BUFFER_SIZE)                \
   475                   l = IO_BUFFER_SIZE;                   \
   475 		  l = IO_BUFFER_SIZE;                   \
   476                 READ((ret),f, __buf, l, handleType);                  \
   476 		READ((ret),f, __buf, l, handleType);                  \
   477                 if ((ret) <= 0) {                       \
   477 		if ((ret) <= 0) {                       \
   478                     if ((ret) < 0 && __threadErrno == EINTR) {  \
   478 		    if ((ret) < 0 && __threadErrno == EINTR) {  \
   479                         continue;                       \
   479 			continue;                       \
   480                     }                                   \
   480 		    }                                   \
   481                     break;                              \
   481 		    break;                              \
   482                 }                                       \
   482 		}                                       \
   483             }                                           \
   483 	    }                                           \
   484             if ((ret) > 0 ) {                           \
   484 	    if ((ret) > 0 ) {                           \
   485                 /* refetch */                               \
   485 		/* refetch */                               \
   486                 buf = (char *)(obj);               \
   486 		buf = (char *)(obj);               \
   487                 memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   487 		memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   488                 __offs += (ret);                            \
   488 		__offs += (ret);                            \
   489             } else {                                        \
   489 	    } else {                                        \
   490                 (ret) = 0;                                  \
   490 		(ret) = 0;                                  \
   491             }                                               \
   491 	    }                                               \
   492         }                                               \
   492 	}                                               \
   493         if (__offs > 0)                                 \
   493 	if (__offs > 0)                                 \
   494             (ret) = __offs;                             \
   494 	    (ret) = __offs;                             \
   495     }                                                   \
   495     }                                                   \
   496   }
   496   }
   497 
   497 
   498 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   498 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   499   {                                                  \
   499   {                                                  \
   500     int __ooffs = obj_offs;                          \
   500     int __ooffs = obj_offs;                          \
   501     int __offs = 0;                                  \
   501     int __offs = 0;                                  \
   502     char *buf = (char *)(obj);                       \
   502     char *buf = (char *)(obj);                       \
   503                                                      \
   503 						     \
   504     (ret) = 0;                                       \
   504     (ret) = 0;                                       \
   505     if (isBuffered) {                                \
   505     if (isBuffered) {                                \
   506         while (__offs < (cnt)) {                     \
   506 	while (__offs < (cnt)) {                     \
   507             CLEAR_ERRNO;                             \
   507 	    CLEAR_ERRNO;                             \
   508             (ret) = getc(f);                         \
   508 	    (ret) = getc(f);                         \
   509             if ((ret) < 0) {                         \
   509 	    if ((ret) < 0) {                         \
   510                 if (ferror(f)) {                     \
   510 		if (ferror(f)) {                     \
   511                     if (__threadErrno == EINTR) {    \
   511 		    if (__threadErrno == EINTR) {    \
   512                         clearerr(f);                 \
   512 			clearerr(f);                 \
   513                         /* refetch */                \
   513 			/* refetch */                \
   514                         buf = (char *)(obj);\
   514 			buf = (char *)(obj);\
   515                         continue;                    \
   515 			continue;                    \
   516                     }                                \
   516 		    }                                \
   517                 } else {                             \
   517 		} else {                             \
   518                     (ret) = 0;                       \
   518 		    (ret) = 0;                       \
   519                 }                                    \
   519 		}                                    \
   520                 break;                               \
   520 		break;                               \
   521             }                                        \
   521 	    }                                        \
   522             (buf)[__ooffs+__offs] = (ret);           \
   522 	    (buf)[__ooffs+__offs] = (ret);           \
   523             __offs++;                                \
   523 	    __offs++;                                \
   524         }                                            \
   524 	}                                            \
   525         if (__offs > 0)                              \
   525 	if (__offs > 0)                              \
   526             (ret) = __offs;                          \
   526 	    (ret) = __offs;                          \
   527     } else {                                         \
   527     } else {                                         \
   528         while (__offs < (cnt)) {                     \
   528 	while (__offs < (cnt)) {                     \
   529             char __buf[IO_BUFFER_SIZE];              \
   529 	    char __buf[IO_BUFFER_SIZE];              \
   530             OBJ rA = __INST(readAhead);              \
   530 	    OBJ rA = __INST(readAhead);              \
   531             if (rA != nil) {                         \
   531 	    if (rA != nil) {                         \
   532                 (buf)[__ooffs+__offs] = __intVal(rA);\
   532 		(buf)[__ooffs+__offs] = __intVal(rA);\
   533                 __INST(readAhead) = nil;             \
   533 		__INST(readAhead) = nil;             \
   534                 (ret) = 1;                           \
   534 		(ret) = 1;                           \
   535                 __offs++;                            \
   535 		__offs++;                            \
   536                 continue;                            \
   536 		continue;                            \
   537             }                                        \
   537 	    }                                        \
   538             {                                        \
   538 	    {                                        \
   539                 int res = 0;                         \
   539 		int res = 0;                         \
   540                 int l = (cnt)-__offs;                \
   540 		int l = (cnt)-__offs;                \
   541                 CLEAR_ERRNO;                         \
   541 		CLEAR_ERRNO;                         \
   542                 if (l > IO_BUFFER_SIZE)              \
   542 		if (l > IO_BUFFER_SIZE)              \
   543                     l = IO_BUFFER_SIZE;              \
   543 		    l = IO_BUFFER_SIZE;              \
   544                 if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)), FIONREAD, &res), 1)) \
   544 		if ((handleType == @symbol(socketFilePointer) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)), FIONREAD, &res), 1)) \
   545                     || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \
   545 		    || (handleType == @symbol(socketHandle) && (ioctlsocket((SOCKET)(f), FIONREAD, &res), 1)) \
   546                     || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0,0,0,&res,0), 1))) { \
   546 		    || (handleType == @symbol(pipeFilePointer) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0,0,0,&res,0), 1))) { \
   547                     if (res > 0) {                   \
   547 		    if (res > 0) {                   \
   548                         if (res > l) res = l;        \
   548 			if (res > l) res = l;        \
   549                         READ((ret), f, __buf, res, handleType); \
   549 			READ((ret), f, __buf, res, handleType); \
   550                     } else {                         \
   550 		    } else {                         \
   551                         (ret) = 0;                   \
   551 			(ret) = 0;                   \
   552                         break;                       \
   552 			break;                       \
   553                     }                                \
   553 		    }                                \
   554                 } else {                             \
   554 		} else {                             \
   555                     READ((ret), f, __buf, l, handleType); \
   555 		    READ((ret), f, __buf, l, handleType); \
   556                 }                                     \
   556 		}                                     \
   557                 if ((ret) <= 0) {                     \
   557 		if ((ret) <= 0) {                     \
   558                     if (ret < 0 && __threadErrno == EINTR) \
   558 		    if (ret < 0 && __threadErrno == EINTR) \
   559                         continue;                       \
   559 			continue;                       \
   560                     break;                              \
   560 		    break;                              \
   561                 }                                       \
   561 		}                                       \
   562             }                                           \
   562 	    }                                           \
   563             if ((ret) > 0) {                            \
   563 	    if ((ret) > 0) {                            \
   564                 buf = (char *)(obj);                    \
   564 		buf = (char *)(obj);                    \
   565                 memcpy((buf)+__ooffs+__offs, __buf, (ret)); \
   565 		memcpy((buf)+__ooffs+__offs, __buf, (ret)); \
   566                 __offs += (ret);                        \
   566 		__offs += (ret);                        \
   567             } else {                                    \
   567 	    } else {                                    \
   568                 (ret) = 0;                              \
   568 		(ret) = 0;                              \
   569             }                                           \
   569 	    }                                           \
   570         }                                               \
   570 	}                                               \
   571         if (__offs > 0)                                 \
   571 	if (__offs > 0)                                 \
   572             (ret) = __offs;                             \
   572 	    (ret) = __offs;                             \
   573     }                                                   \
   573     }                                                   \
   574   }
   574   }
   575 
   575 
   576 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)         \
   576 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)         \
   577     if (isBuffered) {                                   \
   577     if (isBuffered) {                                   \
   578         for (;;) {                                      \
   578 	for (;;) {                                      \
   579             CLEAR_ERRNO;                                \
   579 	    CLEAR_ERRNO;                                \
   580             ret = putc(*(buf), f);                      \
   580 	    ret = putc(*(buf), f);                      \
   581             if ((ret) >= 0) {                           \
   581 	    if ((ret) >= 0) {                           \
   582                 (ret) = 1;                              \
   582 		(ret) = 1;                              \
   583             } else if (ferror(f)) {                     \
   583 	    } else if (ferror(f)) {                     \
   584                 if (__threadErrno == EINTR) {                   \
   584 		if (__threadErrno == EINTR) {                   \
   585                     clearerr(f);                        \
   585 		    clearerr(f);                        \
   586                     continue;                           \
   586 		    continue;                           \
   587                 }                                       \
   587 		}                                       \
   588             } else                                      \
   588 	    } else                                      \
   589                 (ret) = 0;                              \
   589 		(ret) = 0;                              \
   590             break;                                      \
   590 	    break;                                      \
   591         }                                               \
   591 	}                                               \
   592     } else {                                            \
   592     } else {                                            \
   593         for (;;) {                                      \
   593 	for (;;) {                                      \
   594             CLEAR_ERRNO;                                \
   594 	    CLEAR_ERRNO;                                \
   595             WRITE(ret,f, buf, 1, handleType);                       \
   595 	    WRITE(ret,f, buf, 1, handleType);                       \
   596             if ((ret) >= 0 || __threadErrno != EINTR)           \
   596 	    if ((ret) >= 0 || __threadErrno != EINTR)           \
   597                 break;                                  \
   597 		break;                                  \
   598         }                                               \
   598 	}                                               \
   599    }
   599    }
   600 
   600 
   601 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   601 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   602     (ret) = 0;                                          \
   602     (ret) = 0;                                          \
   603     if (isBuffered) {                                   \
   603     if (isBuffered) {                                   \
   604         int __offs = 0;                                 \
   604 	int __offs = 0;                                 \
   605         while (__offs < (cnt)) {                        \
   605 	while (__offs < (cnt)) {                        \
   606             CLEAR_ERRNO;                                \
   606 	    CLEAR_ERRNO;                                \
   607             (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
   607 	    (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
   608             if ((ret) <= 0) {                           \
   608 	    if ((ret) <= 0) {                           \
   609                 if (ferror(f)) {                        \
   609 		if (ferror(f)) {                        \
   610                     if (__threadErrno == EINTR) {               \
   610 		    if (__threadErrno == EINTR) {               \
   611                         clearerr(f);                    \
   611 			clearerr(f);                    \
   612                         continue;                       \
   612 			continue;                       \
   613                     }                                   \
   613 		    }                                   \
   614                     break;                              \
   614 		    break;                              \
   615                 } else {                                \
   615 		} else {                                \
   616                     (ret) = 0;                          \
   616 		    (ret) = 0;                          \
   617                 }                                       \
   617 		}                                       \
   618             }                                           \
   618 	    }                                           \
   619             __offs += (ret);                            \
   619 	    __offs += (ret);                            \
   620         }                                               \
   620 	}                                               \
   621         if (__offs > 0)                                 \
   621 	if (__offs > 0)                                 \
   622             (ret) = __offs;                             \
   622 	    (ret) = __offs;                             \
   623     } else {                                            \
   623     } else {                                            \
   624         int __offs = 0;                                 \
   624 	int __offs = 0;                                 \
   625         while (__offs < (cnt)) {                        \
   625 	while (__offs < (cnt)) {                        \
   626             CLEAR_ERRNO;                                \
   626 	    CLEAR_ERRNO;                                \
   627             WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType);   \
   627 	    WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType);   \
   628             if (ret <= 0) {                             \
   628 	    if (ret <= 0) {                             \
   629                 if (ret < 0 && __threadErrno == EINTR) { \
   629 		if (ret < 0 && __threadErrno == EINTR) { \
   630                     continue;                           \
   630 		    continue;                           \
   631                 }                                       \
   631 		}                                       \
   632                 break;                                  \
   632 		break;                                  \
   633             }                                           \
   633 	    }                                           \
   634             __offs += (ret);                            \
   634 	    __offs += (ret);                            \
   635         }                                               \
   635 	}                                               \
   636         if (__offs > 0)                                 \
   636 	if (__offs > 0)                                 \
   637             (ret) = __offs;                             \
   637 	    (ret) = __offs;                             \
   638    }
   638    }
   639 
   639 
   640 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   640 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   641   {                                                     \
   641   {                                                     \
   642     int __ooffs = obj_offs;                             \
   642     int __ooffs = obj_offs;                             \
   643     int __offs = 0;                                     \
   643     int __offs = 0;                                     \
   644     char *buf = (char *)(obj);                          \
   644     char *buf = (char *)(obj);                          \
   645                                                         \
   645 							\
   646     (ret) = 0;                                          \
   646     (ret) = 0;                                          \
   647     if (isBuffered) {                                   \
   647     if (isBuffered) {                                   \
   648         while (__offs < (cnt)) {                        \
   648 	while (__offs < (cnt)) {                        \
   649             CLEAR_ERRNO;                                \
   649 	    CLEAR_ERRNO;                                \
   650             ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \
   650 	    ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \
   651             if ((ret) <= 0) {                           \
   651 	    if ((ret) <= 0) {                           \
   652                 if (ferror(f)) {                        \
   652 		if (ferror(f)) {                        \
   653                     if (__threadErrno == EINTR) {       \
   653 		    if (__threadErrno == EINTR) {       \
   654                         /* refetch */                   \
   654 			/* refetch */                   \
   655                         buf = (char *)(obj);   \
   655 			buf = (char *)(obj);   \
   656                         clearerr(f);                    \
   656 			clearerr(f);                    \
   657                         continue;                       \
   657 			continue;                       \
   658                     }                                   \
   658 		    }                                   \
   659                     break;                              \
   659 		    break;                              \
   660                 } else {                                \
   660 		} else {                                \
   661                     (ret) = 0;                          \
   661 		    (ret) = 0;                          \
   662                 }                                       \
   662 		}                                       \
   663             }                                           \
   663 	    }                                           \
   664             __offs += (ret);                            \
   664 	    __offs += (ret);                            \
   665         }                                               \
   665 	}                                               \
   666         if (__offs > 0)                                 \
   666 	if (__offs > 0)                                 \
   667             (ret) = __offs;                             \
   667 	    (ret) = __offs;                             \
   668     } else {                                            \
   668     } else {                                            \
   669         while (__offs < (cnt)) {                        \
   669 	while (__offs < (cnt)) {                        \
   670             char __buf[IO_BUFFER_SIZE];                 \
   670 	    char __buf[IO_BUFFER_SIZE];                 \
   671             int l;                                      \
   671 	    int l;                                      \
   672             CLEAR_ERRNO;                                \
   672 	    CLEAR_ERRNO;                                \
   673             l = (cnt)-__offs;                           \
   673 	    l = (cnt)-__offs;                           \
   674             if ( l > IO_BUFFER_SIZE)                    \
   674 	    if ( l > IO_BUFFER_SIZE)                    \
   675               l = IO_BUFFER_SIZE;                       \
   675 	      l = IO_BUFFER_SIZE;                       \
   676             /* refetch */                               \
   676 	    /* refetch */                               \
   677             buf = (char *)(obj);               \
   677 	    buf = (char *)(obj);               \
   678             memcpy(__buf,(buf)+__ooffs+__offs,l);       \
   678 	    memcpy(__buf,(buf)+__ooffs+__offs,l);       \
   679             WRITE(ret,f, __buf, l, handleType);                     \
   679 	    WRITE(ret,f, __buf, l, handleType);                     \
   680             if (ret <= 0) {                             \
   680 	    if (ret <= 0) {                             \
   681                 if (ret < 0 && __threadErrno == EINTR) {        \
   681 		if (ret < 0 && __threadErrno == EINTR) {        \
   682                     continue;                           \
   682 		    continue;                           \
   683                 }                                       \
   683 		}                                       \
   684                 break;                                  \
   684 		break;                                  \
   685             }                                           \
   685 	    }                                           \
   686             __offs += (ret);                            \
   686 	    __offs += (ret);                            \
   687         }                                               \
   687 	}                                               \
   688         if (__offs > 0)                                 \
   688 	if (__offs > 0)                                 \
   689             (ret) = __offs;                             \
   689 	    (ret) = __offs;                             \
   690     }                                                   \
   690     }                                                   \
   691   }
   691   }
   692 
   692 
   693 #else /* ! WIN32 */
   693 #else /* ! WIN32 */
   694 /* ========================   UNIX / LINUX ====================================================== */
   694 /* ========================   UNIX / LINUX ====================================================== */
   695 typedef int SOCKET;
   695 typedef int SOCKET;
   696 
   696 
   697 # define __READING__(f)                          \
   697 # define __READING__(f)                          \
   698     if ((__INST(didWrite) != false)              \
   698     if ((__INST(didWrite) != false)              \
   699      && (__INST(mode) == @symbol(readwrite))) {  \
   699      && (__INST(mode) == @symbol(readwrite))) {  \
   700         __INST(didWrite) = false;                \
   700 	__INST(didWrite) = false;                \
   701         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   701 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   702     }
   702     }
   703 
   703 
   704 # define __WRITING__(f)                          \
   704 # define __WRITING__(f)                          \
   705     if ((__INST(didWrite) != true)               \
   705     if ((__INST(didWrite) != true)               \
   706      && (__INST(mode) == @symbol(readwrite))) {  \
   706      && (__INST(mode) == @symbol(readwrite))) {  \
   707         __INST(didWrite) = true;                 \
   707 	__INST(didWrite) = true;                 \
   708         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   708 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   709     }
   709     }
   710 
   710 
   711 
   711 
   712 # ifdef NO_STDIO
   712 # ifdef NO_STDIO
   713 #  define __UNGETC__(c, f, isBuffered)                  \
   713 #  define __UNGETC__(c, f, isBuffered)                  \
   714     __INST(readAhead) = __mkSmallInteger((c));
   714     __INST(readAhead) = __mkSmallInteger((c));
   715 # else /* use STDIO */
   715 # else /* use STDIO */
   716 #  define __UNGETC__(c, f, isBuffered)                  \
   716 #  define __UNGETC__(c, f, isBuffered)                  \
   717     if (isBuffered) {                                   \
   717     if (isBuffered) {                                   \
   718         ungetc((c), (f));                               \
   718 	ungetc((c), (f));                               \
   719     } else {                                            \
   719     } else {                                            \
   720         __INST(readAhead) = __mkSmallInteger((c));          \
   720 	__INST(readAhead) = __mkSmallInteger((c));          \
   721     }
   721     }
   722 # endif /* use STDIO */
   722 # endif /* use STDIO */
   723 
   723 
   724 # ifdef NO_STDIO
   724 # ifdef NO_STDIO
   725 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   725 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   726     {                                                   \
   726     {                                                   \
   727         OBJ rA = __INST(readAhead);                     \
   727 	OBJ rA = __INST(readAhead);                     \
   728         if (rA != nil) {                                \
   728 	if (rA != nil) {                                \
   729             *(buf) = __intVal(rA);                      \
   729 	    *(buf) = __intVal(rA);                      \
   730             DEBUGBUFFER(buf);                           \
   730 	    DEBUGBUFFER(buf);                           \
   731             __INST(readAhead) = nil;                    \
   731 	    __INST(readAhead) = nil;                    \
   732             (ret) = 1;                                  \
   732 	    (ret) = 1;                                  \
   733         } else {                                        \
   733 	} else {                                        \
   734             for (;;) {                                  \
   734 	    for (;;) {                                  \
   735                 CLEAR_ERRNO;                            \
   735 		CLEAR_ERRNO;                            \
   736                 (ret) = READ(f, buf, 1, handleType);    \
   736 		(ret) = READ(f, buf, 1, handleType);    \
   737                 DEBUGBUFFER(buf);                       \
   737 		DEBUGBUFFER(buf);                       \
   738                 if ((ret) >= 0) break;                  \
   738 		if ((ret) >= 0) break;                  \
   739                 if (errno != EINTR) {                   \
   739 		if (errno != EINTR) {                   \
   740                     break;                              \
   740 		    break;                              \
   741                 }                                       \
   741 		}                                       \
   742                 __HANDLE_INTERRUPTS__;                  \
   742 		__HANDLE_INTERRUPTS__;                  \
   743             }                                           \
   743 	    }                                           \
   744         }                                               \
   744 	}                                               \
   745     }
   745     }
   746 # else /* use STDIO */
   746 # else /* use STDIO */
   747 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   747 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   748     if (isBuffered) {                                   \
   748     if (isBuffered) {                                   \
   749         for (;;) {                                      \
   749 	for (;;) {                                      \
   750             CLEAR_ERRNO;                                \
   750 	    CLEAR_ERRNO;                                \
   751             (ret) = getc(f);                            \
   751 	    (ret) = getc(f);                            \
   752             if ((ret) >= 0) {                           \
   752 	    if ((ret) >= 0) {                           \
   753                 DEBUGBUFFER(buf);                       \
   753 		DEBUGBUFFER(buf);                       \
   754                 *(buf) = (ret);                         \
   754 		*(buf) = (ret);                         \
   755                 (ret) = 1;                              \
   755 		(ret) = 1;                              \
   756             } else if (ferror(f)) {                     \
   756 	    } else if (ferror(f)) {                     \
   757                 if (errno == EINTR) {                   \
   757 		if (errno == EINTR) {                   \
   758                     __HANDLE_INTERRUPTS__;              \
   758 		    __HANDLE_INTERRUPTS__;              \
   759                     clearerr(f);                        \
   759 		    clearerr(f);                        \
   760                     continue;                           \
   760 		    continue;                           \
   761                 }                                       \
   761 		}                                       \
   762             } else                                      \
   762 	    } else                                      \
   763                 (ret) = 0;                              \
   763 		(ret) = 0;                              \
   764             break;                                      \
   764 	    break;                                      \
   765         }                                               \
   765 	}                                               \
   766     } else {                                            \
   766     } else {                                            \
   767         OBJ rA = __INST(readAhead);                     \
   767 	OBJ rA = __INST(readAhead);                     \
   768         if (rA != nil) {                                \
   768 	if (rA != nil) {                                \
   769             *(buf) = __intVal(rA);                      \
   769 	    *(buf) = __intVal(rA);                      \
   770             DEBUGBUFFER(buf);                           \
   770 	    DEBUGBUFFER(buf);                           \
   771             __INST(readAhead) = nil;                    \
   771 	    __INST(readAhead) = nil;                    \
   772             (ret) = 1;                                  \
   772 	    (ret) = 1;                                  \
   773         } else {                                        \
   773 	} else {                                        \
   774             for (;;) {                                  \
   774 	    for (;;) {                                  \
   775                 CLEAR_ERRNO;                            \
   775 		CLEAR_ERRNO;                            \
   776                 (ret) = read(fileno(f), buf, 1);        \
   776 		(ret) = read(fileno(f), buf, 1);        \
   777                 DEBUGBUFFER(buf);                       \
   777 		DEBUGBUFFER(buf);                       \
   778                 if ((ret) >= 0) break;                  \
   778 		if ((ret) >= 0) break;                  \
   779                 if (errno != EINTR) {                   \
   779 		if (errno != EINTR) {                   \
   780                     break;                              \
   780 		    break;                              \
   781                 }                                       \
   781 		}                                       \
   782                 __HANDLE_INTERRUPTS__;                  \
   782 		__HANDLE_INTERRUPTS__;                  \
   783             }                                           \
   783 	    }                                           \
   784         }                                               \
   784 	}                                               \
   785    }
   785    }
   786 # endif /* use STDIO */
   786 # endif /* use STDIO */
   787 
   787 
   788 /*
   788 /*
   789  * read_bytes into a c-buffer
   789  * read_bytes into a c-buffer
   790  * (which may NOT move)
   790  * (which may NOT move)
   791  */
   791  */
   792 # ifdef NO_STDIO
   792 # ifdef NO_STDIO
   793 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   793 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   794     {                                                   \
   794     {                                                   \
   795         int __offs = 0, __cnt;                          \
   795 	int __offs = 0, __cnt;                          \
   796                                                         \
   796 							\
   797         while (__offs < (cnt)) {                        \
   797 	while (__offs < (cnt)) {                        \
   798             OBJ rA = __INST(readAhead);                 \
   798 	    OBJ rA = __INST(readAhead);                 \
   799             if (rA != nil) {                            \
   799 	    if (rA != nil) {                            \
   800                 (buf)[__offs] = __intVal(rA);           \
   800 		(buf)[__offs] = __intVal(rA);           \
   801                 DEBUGBUFFER(buf);                       \
   801 		DEBUGBUFFER(buf);                       \
   802                 __INST(readAhead) = nil;                \
   802 		__INST(readAhead) = nil;                \
   803                 __offs++;                               \
   803 		__offs++;                               \
   804             } else {                                    \
   804 	    } else {                                    \
   805                 CLEAR_ERRNO;                            \
   805 		CLEAR_ERRNO;                            \
   806                 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \
   806 		__cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \
   807                 DEBUGBUFFER(buf);                       \
   807 		DEBUGBUFFER(buf);                       \
   808                 if (__cnt <= 0) {                       \
   808 		if (__cnt <= 0) {                       \
   809                     if (__cnt < 0 && errno == EINTR) {  \
   809 		    if (__cnt < 0 && errno == EINTR) {  \
   810                         __HANDLE_INTERRUPTS__;          \
   810 			__HANDLE_INTERRUPTS__;          \
   811                         continue;                       \
   811 			continue;                       \
   812                     }                                   \
   812 		    }                                   \
   813                     break;                              \
   813 		    break;                              \
   814                 }                                       \
   814 		}                                       \
   815                 __offs += __cnt;                        \
   815 		__offs += __cnt;                        \
   816             }                                           \
   816 	    }                                           \
   817         }                                               \
   817 	}                                               \
   818         if (__offs > 0)                                 \
   818 	if (__offs > 0)                                 \
   819             (ret) = __offs;                             \
   819 	    (ret) = __offs;                             \
   820    }
   820    }
   821 # else /* use STDIO */
   821 # else /* use STDIO */
   822 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)     \
   822 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)     \
   823     (ret) = 0;                                          \
   823     (ret) = 0;                                          \
   824     if (isBuffered) {                                   \
   824     if (isBuffered) {                                   \
   825         int __offs = 0;                                 \
   825 	int __offs = 0;                                 \
   826         while (__offs < (cnt)) {                        \
   826 	while (__offs < (cnt)) {                        \
   827             CLEAR_ERRNO;                                \
   827 	    CLEAR_ERRNO;                                \
   828             (ret) = getc(f);                            \
   828 	    (ret) = getc(f);                            \
   829             if ((ret) < 0) {                            \
   829 	    if ((ret) < 0) {                            \
   830                 if (ferror(f)) {                        \
   830 		if (ferror(f)) {                        \
   831                     if (errno == EINTR) {               \
   831 		    if (errno == EINTR) {               \
   832                         __HANDLE_INTERRUPTS__;          \
   832 			__HANDLE_INTERRUPTS__;          \
   833                         clearerr(f);                    \
   833 			clearerr(f);                    \
   834                         continue;                       \
   834 			continue;                       \
   835                     }                                   \
   835 		    }                                   \
   836                 } else {                                \
   836 		} else {                                \
   837                     (ret) = 0;                          \
   837 		    (ret) = 0;                          \
   838                 }                                       \
   838 		}                                       \
   839                 break;                                  \
   839 		break;                                  \
   840             }                                           \
   840 	    }                                           \
   841             DEBUGBUFFER(buf);                           \
   841 	    DEBUGBUFFER(buf);                           \
   842             (buf)[__offs++] = (ret);                    \
   842 	    (buf)[__offs++] = (ret);                    \
   843         }                                               \
   843 	}                                               \
   844         if (__offs > 0)                                 \
   844 	if (__offs > 0)                                 \
   845             (ret) = __offs;                             \
   845 	    (ret) = __offs;                             \
   846     } else {                                            \
   846     } else {                                            \
   847         int __offs = 0, __cnt;                          \
   847 	int __offs = 0, __cnt;                          \
   848         int fd = fileno(f);                             \
   848 	int fd = fileno(f);                             \
   849                                                         \
   849 							\
   850         while (__offs < (cnt)) {                        \
   850 	while (__offs < (cnt)) {                        \
   851             OBJ rA = __INST(readAhead);                 \
   851 	    OBJ rA = __INST(readAhead);                 \
   852             if (rA != nil) {                            \
   852 	    if (rA != nil) {                            \
   853                 DEBUGBUFFER(buf);                       \
   853 		DEBUGBUFFER(buf);                       \
   854                 (buf)[__offs] = __intVal(rA);           \
   854 		(buf)[__offs] = __intVal(rA);           \
   855                 __INST(readAhead) = nil;                \
   855 		__INST(readAhead) = nil;                \
   856                 __offs++;                               \
   856 		__offs++;                               \
   857             } else {                                    \
   857 	    } else {                                    \
   858                 CLEAR_ERRNO;                            \
   858 		CLEAR_ERRNO;                            \
   859                 __cnt = read(fd, (buf)+__offs, (cnt)-__offs);  \
   859 		__cnt = read(fd, (buf)+__offs, (cnt)-__offs);  \
   860                 DEBUGBUFFER(buf);                       \
   860 		DEBUGBUFFER(buf);                       \
   861                 if (__cnt <= 0) {                       \
   861 		if (__cnt <= 0) {                       \
   862                     if (__cnt < 0 && errno == EINTR) {  \
   862 		    if (__cnt < 0 && errno == EINTR) {  \
   863                         __HANDLE_INTERRUPTS__;          \
   863 			__HANDLE_INTERRUPTS__;          \
   864                         continue;                       \
   864 			continue;                       \
   865                     }                                   \
   865 		    }                                   \
   866                     break;                              \
   866 		    break;                              \
   867                 }                                       \
   867 		}                                       \
   868                 __offs += __cnt;                        \
   868 		__offs += __cnt;                        \
   869             }                                           \
   869 	    }                                           \
   870         }                                               \
   870 	}                                               \
   871         if (__offs > 0)                                 \
   871 	if (__offs > 0)                                 \
   872             (ret) = __offs;                             \
   872 	    (ret) = __offs;                             \
   873    }
   873    }
   874 
   874 
   875 
   875 
   876 /*
   876 /*
   877  * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc...
   877  * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc...
   878  */
   878  */
   879 
   879 
   880 #  if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY))
   880 #  if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY))
   881 #   define SETFLAGS(fd, flags) \
   881 #   define SETFLAGS(fd, flags) \
   882         fcntl(fd, F_SETFL, flags)
   882 	fcntl(fd, F_SETFL, flags)
   883 
   883 
   884 #   if defined(O_NONBLOCK)
   884 #   if defined(O_NONBLOCK)
   885 #    define __STX_NONBLOCK_FLAG O_NONBLOCK
   885 #    define __STX_NONBLOCK_FLAG O_NONBLOCK
   886 #   else
   886 #   else
   887 #    if defined(O_NDELAY)
   887 #    if defined(O_NDELAY)
   890 #     define __STX_NONBLOCK_FLAG FNDELAY
   890 #     define __STX_NONBLOCK_FLAG FNDELAY
   891 #    endif
   891 #    endif
   892 #   endif
   892 #   endif
   893 
   893 
   894 #   define SETNONBLOCKING(fd, oldFlags) \
   894 #   define SETNONBLOCKING(fd, oldFlags) \
   895         { \
   895 	{ \
   896             int flags = fcntl(fd, F_GETFL, 0); \
   896 	    int flags = fcntl(fd, F_GETFL, 0); \
   897             if (flags >= 0) { \
   897 	    if (flags >= 0) { \
   898                 fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \
   898 		fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \
   899             } \
   899 	    } \
   900             oldFlags = flags; \
   900 	    oldFlags = flags; \
   901         }
   901 	}
   902 #  else
   902 #  else
   903 #   define SETFLAGS(fd, flags) /* nothing */
   903 #   define SETFLAGS(fd, flags) /* nothing */
   904 #   define SETNONBLOCKING(fd, oldFlags) /* nothing */
   904 #   define SETNONBLOCKING(fd, oldFlags) /* nothing */
   905 #  endif
   905 #  endif
   906 
   906 
   907 #  define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   907 #  define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   908   {                                                     \
   908   {                                                     \
   909     int __offs = 0, __cnt;                              \
   909     int __offs = 0, __cnt;                              \
   910     int oldFlags;                                       \
   910     int oldFlags;                                       \
   911                                                         \
   911 							\
   912     (ret) = 0;                                          \
   912     (ret) = 0;                                          \
   913     SETNONBLOCKING(fileno(f), oldFlags);                \
   913     SETNONBLOCKING(fileno(f), oldFlags);                \
   914     if (isBuffered) {                                   \
   914     if (isBuffered) {                                   \
   915         while (__offs < (cnt)) {                        \
   915 	while (__offs < (cnt)) {                        \
   916             CLEAR_ERRNO;                                \
   916 	    CLEAR_ERRNO;                                \
   917             (ret) = getc(f);                            \
   917 	    (ret) = getc(f);                            \
   918             if ((ret) < 0) {                            \
   918 	    if ((ret) < 0) {                            \
   919                 if (ferror(f)) {                        \
   919 		if (ferror(f)) {                        \
   920                     if (errno == EINTR) {               \
   920 		    if (errno == EINTR) {               \
   921                         (ret) = 0;                      \
   921 			(ret) = 0;                      \
   922                         clearerr(f);                    \
   922 			clearerr(f);                    \
   923                         break;                          \
   923 			break;                          \
   924                     }                                   \
   924 		    }                                   \
   925                 } else {                                \
   925 		} else {                                \
   926                     (ret) = 0;                          \
   926 		    (ret) = 0;                          \
   927                 }                                       \
   927 		}                                       \
   928                 break;                                  \
   928 		break;                                  \
   929             }                                           \
   929 	    }                                           \
   930             (buf)[__offs++] = (ret);                    \
   930 	    (buf)[__offs++] = (ret);                    \
   931             DEBUGBUFFER(buf);                           \
   931 	    DEBUGBUFFER(buf);                           \
   932         }                                               \
   932 	}                                               \
   933         if (__offs > 0)                                 \
   933 	if (__offs > 0)                                 \
   934             (ret) = __offs;                             \
   934 	    (ret) = __offs;                             \
   935     } else {                                            \
   935     } else {                                            \
   936         int fd = fileno(f);                             \
   936 	int fd = fileno(f);                             \
   937                                                         \
   937 							\
   938         while (__offs < (cnt)) {                        \
   938 	while (__offs < (cnt)) {                        \
   939             OBJ rA = __INST(readAhead);                 \
   939 	    OBJ rA = __INST(readAhead);                 \
   940             if (rA != nil) {                            \
   940 	    if (rA != nil) {                            \
   941                 (buf)[__offs] = __intVal(rA);           \
   941 		(buf)[__offs] = __intVal(rA);           \
   942                 DEBUGBUFFER(buf);                       \
   942 		DEBUGBUFFER(buf);                       \
   943                 __INST(readAhead) = nil;                \
   943 		__INST(readAhead) = nil;                \
   944                 __offs++;                               \
   944 		__offs++;                               \
   945                 continue;                               \
   945 		continue;                               \
   946             }                                           \
   946 	    }                                           \
   947             CLEAR_ERRNO;                                \
   947 	    CLEAR_ERRNO;                                \
   948             __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \
   948 	    __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \
   949             DEBUGBUFFER(buf);                           \
   949 	    DEBUGBUFFER(buf);                           \
   950             if (__cnt > 0) {                            \
   950 	    if (__cnt > 0) {                            \
   951                 __offs += __cnt;                        \
   951 		__offs += __cnt;                        \
   952             }                                           \
   952 	    }                                           \
   953             break;                                      \
   953 	    break;                                      \
   954         }                                               \
   954 	}                                               \
   955         if (__offs > 0)                                 \
   955 	if (__offs > 0)                                 \
   956             (ret) = __offs;                             \
   956 	    (ret) = __offs;                             \
   957     }                                                   \
   957     }                                                   \
   958     SETFLAGS(fileno(f), oldFlags);                      \
   958     SETFLAGS(fileno(f), oldFlags);                      \
   959   }
   959   }
   960 
   960 
   961 # endif /* use STDIO */
   961 # endif /* use STDIO */
   969   {                                                     \
   969   {                                                     \
   970     int __ooffs = obj_offs;                             \
   970     int __ooffs = obj_offs;                             \
   971     int __offs = 0;                                     \
   971     int __offs = 0;                                     \
   972     int __cnt;                                          \
   972     int __cnt;                                          \
   973     char *buf = (char *)(obj);                          \
   973     char *buf = (char *)(obj);                          \
   974                                                         \
   974 							\
   975     (ret) = 0;                                          \
   975     (ret) = 0;                                          \
   976     {                                                   \
   976     {                                                   \
   977         while (__offs < (cnt)) {                        \
   977 	while (__offs < (cnt)) {                        \
   978             OBJ rA = __INST(readAhead);                 \
   978 	    OBJ rA = __INST(readAhead);                 \
   979             if (rA != nil) {                            \
   979 	    if (rA != nil) {                            \
   980                 (buf)[__ooffs+__offs] = __intVal(rA);   \
   980 		(buf)[__ooffs+__offs] = __intVal(rA);   \
   981                 DEBUGBUFFER(buf);                       \
   981 		DEBUGBUFFER(buf);                       \
   982                 __INST(readAhead) = nil;                \
   982 		__INST(readAhead) = nil;                \
   983                 __offs++;                               \
   983 		__offs++;                               \
   984             } else {                                    \
   984 	    } else {                                    \
   985                 CLEAR_ERRNO;                            \
   985 		CLEAR_ERRNO;                            \
   986                 __cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
   986 		__cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
   987                 DEBUGBUFFER(buf);                       \
   987 		DEBUGBUFFER(buf);                       \
   988                 if (__cnt <= 0) {                       \
   988 		if (__cnt <= 0) {                       \
   989                     if (__cnt < 0 && errno == EINTR) {  \
   989 		    if (__cnt < 0 && errno == EINTR) {  \
   990                         __HANDLE_INTERRUPTS__;          \
   990 			__HANDLE_INTERRUPTS__;          \
   991                         /* refetch */                   \
   991 			/* refetch */                   \
   992                         buf = (char *)(obj);            \
   992 			buf = (char *)(obj);            \
   993                         continue;                       \
   993 			continue;                       \
   994                     }                                   \
   994 		    }                                   \
   995                     break;                              \
   995 		    break;                              \
   996                 }                                       \
   996 		}                                       \
   997                 __offs += __cnt;                        \
   997 		__offs += __cnt;                        \
   998             }                                           \
   998 	    }                                           \
   999         }                                               \
   999 	}                                               \
  1000         if (__offs > 0)                                 \
  1000 	if (__offs > 0)                                 \
  1001             (ret) = __offs;                             \
  1001 	    (ret) = __offs;                             \
  1002     }                                                   \
  1002     }                                                   \
  1003   }
  1003   }
  1004 
  1004 
  1005 # else /* use STDIO */
  1005 # else /* use STDIO */
  1006 
  1006 
  1008   {                                                     \
  1008   {                                                     \
  1009     int __ooffs = obj_offs;                             \
  1009     int __ooffs = obj_offs;                             \
  1010     int __offs = 0;                                     \
  1010     int __offs = 0;                                     \
  1011     int __cnt;                                          \
  1011     int __cnt;                                          \
  1012     char *buf = (char *)(obj);                          \
  1012     char *buf = (char *)(obj);                          \
  1013                                                         \
  1013 							\
  1014     (ret) = 0;                                          \
  1014     (ret) = 0;                                          \
  1015     if (isBuffered) {                                   \
  1015     if (isBuffered) {                                   \
  1016         while (__offs < (cnt)) {                        \
  1016 	while (__offs < (cnt)) {                        \
  1017             CLEAR_ERRNO;                                \
  1017 	    CLEAR_ERRNO;                                \
  1018             (ret) = getc(f);                            \
  1018 	    (ret) = getc(f);                            \
  1019             if ((ret) < 0) {                            \
  1019 	    if ((ret) < 0) {                            \
  1020                 if (ferror(f)) {                        \
  1020 		if (ferror(f)) {                        \
  1021                     if (errno == EINTR) {               \
  1021 		    if (errno == EINTR) {               \
  1022                         __HANDLE_INTERRUPTS__;          \
  1022 			__HANDLE_INTERRUPTS__;          \
  1023                         clearerr(f);                    \
  1023 			clearerr(f);                    \
  1024                         /* refetch */                   \
  1024 			/* refetch */                   \
  1025                         buf = (char *)(obj);            \
  1025 			buf = (char *)(obj);            \
  1026                         DEBUGBUFFER(buf);               \
  1026 			DEBUGBUFFER(buf);               \
  1027                         continue;                       \
  1027 			continue;                       \
  1028                     }                                   \
  1028 		    }                                   \
  1029                 } else {                                \
  1029 		} else {                                \
  1030                     (ret) = 0;                          \
  1030 		    (ret) = 0;                          \
  1031                 }                                       \
  1031 		}                                       \
  1032                 break;                                  \
  1032 		break;                                  \
  1033             }                                           \
  1033 	    }                                           \
  1034             (buf)[__ooffs+__offs] = (ret);              \
  1034 	    (buf)[__ooffs+__offs] = (ret);              \
  1035             DEBUGBUFFER(buf);                           \
  1035 	    DEBUGBUFFER(buf);                           \
  1036             __offs++;                                   \
  1036 	    __offs++;                                   \
  1037         }                                               \
  1037 	}                                               \
  1038         if (__offs > 0)                                 \
  1038 	if (__offs > 0)                                 \
  1039             (ret) = __offs;                             \
  1039 	    (ret) = __offs;                             \
  1040     } else {                                            \
  1040     } else {                                            \
  1041         int fd = fileno(f);                             \
  1041 	int fd = fileno(f);                             \
  1042                                                         \
  1042 							\
  1043         while (__offs < (cnt)) {                        \
  1043 	while (__offs < (cnt)) {                        \
  1044             OBJ rA = __INST(readAhead);                 \
  1044 	    OBJ rA = __INST(readAhead);                 \
  1045             if (rA != nil) {                            \
  1045 	    if (rA != nil) {                            \
  1046                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1046 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1047                 DEBUGBUFFER(buf);                       \
  1047 		DEBUGBUFFER(buf);                       \
  1048                 __INST(readAhead) = nil;                \
  1048 		__INST(readAhead) = nil;                \
  1049                 __offs++;                               \
  1049 		__offs++;                               \
  1050             } else {                                    \
  1050 	    } else {                                    \
  1051                 CLEAR_ERRNO;                            \
  1051 		CLEAR_ERRNO;                            \
  1052                 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1052 		__cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1053                 DEBUGBUFFER(buf);                       \
  1053 		DEBUGBUFFER(buf);                       \
  1054                 if (__cnt <= 0) {                       \
  1054 		if (__cnt <= 0) {                       \
  1055                     if (__cnt < 0 && errno == EINTR) {  \
  1055 		    if (__cnt < 0 && errno == EINTR) {  \
  1056                         __HANDLE_INTERRUPTS__;          \
  1056 			__HANDLE_INTERRUPTS__;          \
  1057                         /* refetch */                   \
  1057 			/* refetch */                   \
  1058                         buf = (char *)(obj);            \
  1058 			buf = (char *)(obj);            \
  1059                         continue;                       \
  1059 			continue;                       \
  1060                     }                                   \
  1060 		    }                                   \
  1061                     break;                              \
  1061 		    break;                              \
  1062                 }                                       \
  1062 		}                                       \
  1063                 __offs += __cnt;                        \
  1063 		__offs += __cnt;                        \
  1064             }                                           \
  1064 	    }                                           \
  1065         }                                               \
  1065 	}                                               \
  1066         if (__offs > 0)                                 \
  1066 	if (__offs > 0)                                 \
  1067             (ret) = __offs;                             \
  1067 	    (ret) = __offs;                             \
  1068     }                                                   \
  1068     }                                                   \
  1069   }
  1069   }
  1070 
  1070 
  1071 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)     \
  1071 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)     \
  1072   {                                                     \
  1072   {                                                     \
  1073     int __ooffs = obj_offs;                             \
  1073     int __ooffs = obj_offs;                             \
  1074     int __offs = 0;                                     \
  1074     int __offs = 0;                                     \
  1075     int __cnt;                                          \
  1075     int __cnt;                                          \
  1076     char *buf = (char *)(obj);                          \
  1076     char *buf = (char *)(obj);                          \
  1077     int oldFlags;                                       \
  1077     int oldFlags;                                       \
  1078                                                         \
  1078 							\
  1079     (ret) = 0;                                          \
  1079     (ret) = 0;                                          \
  1080     SETNONBLOCKING(fileno(f), oldFlags);                \
  1080     SETNONBLOCKING(fileno(f), oldFlags);                \
  1081                                                         \
  1081 							\
  1082     if (isBuffered) {                                   \
  1082     if (isBuffered) {                                   \
  1083         while (__offs < (cnt)) {                        \
  1083 	while (__offs < (cnt)) {                        \
  1084             CLEAR_ERRNO;                                \
  1084 	    CLEAR_ERRNO;                                \
  1085             (ret) = getc(f);                            \
  1085 	    (ret) = getc(f);                            \
  1086             if ((ret) < 0) {                            \
  1086 	    if ((ret) < 0) {                            \
  1087                 if (ferror(f)) {                        \
  1087 		if (ferror(f)) {                        \
  1088                     if (errno == EINTR) {               \
  1088 		    if (errno == EINTR) {               \
  1089                         clearerr(f);                    \
  1089 			clearerr(f);                    \
  1090                         /* refetch */                   \
  1090 			/* refetch */                   \
  1091                         buf = (char *)(obj);            \
  1091 			buf = (char *)(obj);            \
  1092                         (ret) = 0;                      \
  1092 			(ret) = 0;                      \
  1093                         break;                          \
  1093 			break;                          \
  1094                     }                                   \
  1094 		    }                                   \
  1095                 } else {                                \
  1095 		} else {                                \
  1096                     (ret) = 0;                          \
  1096 		    (ret) = 0;                          \
  1097                 }                                       \
  1097 		}                                       \
  1098                 break;                                  \
  1098 		break;                                  \
  1099             }                                           \
  1099 	    }                                           \
  1100             (buf)[__ooffs+__offs] = (ret);              \
  1100 	    (buf)[__ooffs+__offs] = (ret);              \
  1101             DEBUGBUFFER(buf);                           \
  1101 	    DEBUGBUFFER(buf);                           \
  1102             __offs++;                                   \
  1102 	    __offs++;                                   \
  1103         }                                               \
  1103 	}                                               \
  1104         if (__offs > 0)                                 \
  1104 	if (__offs > 0)                                 \
  1105             (ret) = __offs;                             \
  1105 	    (ret) = __offs;                             \
  1106     } else {                                            \
  1106     } else {                                            \
  1107         int fd = fileno(f);                             \
  1107 	int fd = fileno(f);                             \
  1108                                                         \
  1108 							\
  1109         while (__offs < (cnt)) {                        \
  1109 	while (__offs < (cnt)) {                        \
  1110             OBJ rA = __INST(readAhead);                 \
  1110 	    OBJ rA = __INST(readAhead);                 \
  1111             if (rA != nil) {                            \
  1111 	    if (rA != nil) {                            \
  1112                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1112 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1113                 DEBUGBUFFER(buf);                       \
  1113 		DEBUGBUFFER(buf);                       \
  1114                 __INST(readAhead) = nil;                \
  1114 		__INST(readAhead) = nil;                \
  1115                 __offs++;                               \
  1115 		__offs++;                               \
  1116                 continue;                               \
  1116 		continue;                               \
  1117             }                                           \
  1117 	    }                                           \
  1118             CLEAR_ERRNO;                                \
  1118 	    CLEAR_ERRNO;                                \
  1119             __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1119 	    __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1120             DEBUGBUFFER(buf);                           \
  1120 	    DEBUGBUFFER(buf);                           \
  1121             if (__cnt > 0) {                            \
  1121 	    if (__cnt > 0) {                            \
  1122                 __offs += __cnt;                        \
  1122 		__offs += __cnt;                        \
  1123             }                                           \
  1123 	    }                                           \
  1124             break;                                      \
  1124 	    break;                                      \
  1125         }                                               \
  1125 	}                                               \
  1126         if (__offs > 0)                                 \
  1126 	if (__offs > 0)                                 \
  1127             (ret) = __offs;                             \
  1127 	    (ret) = __offs;                             \
  1128     }                                                   \
  1128     }                                                   \
  1129     SETFLAGS(fileno(f), oldFlags);                      \
  1129     SETFLAGS(fileno(f), oldFlags);                      \
  1130   }
  1130   }
  1131 
  1131 
  1132 
  1132 
  1133 # endif /* use STDIO */
  1133 # endif /* use STDIO */
  1134 
  1134 
  1135 # ifdef NO_STDIO
  1135 # ifdef NO_STDIO
  1136 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)          \
  1136 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)          \
  1137         for (;;) {                                      \
  1137 	for (;;) {                                      \
  1138             CLEAR_ERRNO;                                \
  1138 	    CLEAR_ERRNO;                                \
  1139             (ret) = WRITE(f, buf, 1, handleType);       \
  1139 	    (ret) = WRITE(f, buf, 1, handleType);       \
  1140             if ((ret) >= 0) break;                      \
  1140 	    if ((ret) >= 0) break;                      \
  1141             if (errno != EINTR) {                       \
  1141 	    if (errno != EINTR) {                       \
  1142                 break;                                  \
  1142 		break;                                  \
  1143             }                                           \
  1143 	    }                                           \
  1144             __HANDLE_INTERRUPTS__;                      \
  1144 	    __HANDLE_INTERRUPTS__;                      \
  1145         }
  1145 	}
  1146 # else /* use STDIO */
  1146 # else /* use STDIO */
  1147 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)        \
  1147 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)        \
  1148     if (isBuffered) {                                   \
  1148     if (isBuffered) {                                   \
  1149         for (;;) {                                      \
  1149 	for (;;) {                                      \
  1150             CLEAR_ERRNO;                                \
  1150 	    CLEAR_ERRNO;                                \
  1151             ret = putc(*(buf), f);                      \
  1151 	    ret = putc(*(buf), f);                      \
  1152             if ((ret) >= 0) {                           \
  1152 	    if ((ret) >= 0) {                           \
  1153                 (ret) = 1;                              \
  1153 		(ret) = 1;                              \
  1154             } else if (ferror(f)) {                     \
  1154 	    } else if (ferror(f)) {                     \
  1155                 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \
  1155 		/* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \
  1156                 if (errno == EINTR || errno == 0) {     \
  1156 		if (errno == EINTR || errno == 0) {     \
  1157                     __HANDLE_INTERRUPTS__;              \
  1157 		    __HANDLE_INTERRUPTS__;              \
  1158                     clearerr(f);                        \
  1158 		    clearerr(f);                        \
  1159                     continue;                           \
  1159 		    continue;                           \
  1160                 }                                       \
  1160 		}                                       \
  1161             } else                                      \
  1161 	    } else                                      \
  1162                 (ret) = 0;                              \
  1162 		(ret) = 0;                              \
  1163             break;                                      \
  1163 	    break;                                      \
  1164         }                                               \
  1164 	}                                               \
  1165     } else {                                            \
  1165     } else {                                            \
  1166         for (;;) {                                      \
  1166 	for (;;) {                                      \
  1167             CLEAR_ERRNO;                                \
  1167 	    CLEAR_ERRNO;                                \
  1168             (ret) = write(fileno(f), buf, 1);           \
  1168 	    (ret) = write(fileno(f), buf, 1);           \
  1169             if ((ret) >= 0) break;                      \
  1169 	    if ((ret) >= 0) break;                      \
  1170             if (errno != EINTR) {                       \
  1170 	    if (errno != EINTR) {                       \
  1171                 break;                                  \
  1171 		break;                                  \
  1172             }                                           \
  1172 	    }                                           \
  1173             __HANDLE_INTERRUPTS__;                      \
  1173 	    __HANDLE_INTERRUPTS__;                      \
  1174         }                                               \
  1174 	}                                               \
  1175    }
  1175    }
  1176 # endif /* use STDIO */
  1176 # endif /* use STDIO */
  1177 
  1177 
  1178 /*
  1178 /*
  1179  * write_bytes from a c-buffer
  1179  * write_bytes from a c-buffer
  1181  */
  1181  */
  1182 # ifdef NO_STDIO
  1182 # ifdef NO_STDIO
  1183 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1183 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1184     (ret) = 0;                                          \
  1184     (ret) = 0;                                          \
  1185     {                                                   \
  1185     {                                                   \
  1186         int __offs = 0;                                 \
  1186 	int __offs = 0;                                 \
  1187         while (__offs < (cnt)) {                        \
  1187 	while (__offs < (cnt)) {                        \
  1188             CLEAR_ERRNO;                                \
  1188 	    CLEAR_ERRNO;                                \
  1189             ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \
  1189 	    ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \
  1190             if (ret <= 0) {                             \
  1190 	    if (ret <= 0) {                             \
  1191                 if (ret < 0 && errno == EINTR) {        \
  1191 		if (ret < 0 && errno == EINTR) {        \
  1192                     __HANDLE_INTERRUPTS__;              \
  1192 		    __HANDLE_INTERRUPTS__;              \
  1193                     continue;                           \
  1193 		    continue;                           \
  1194                 }                                       \
  1194 		}                                       \
  1195                 break;                                  \
  1195 		break;                                  \
  1196             }                                           \
  1196 	    }                                           \
  1197             __offs += (ret);                            \
  1197 	    __offs += (ret);                            \
  1198         }                                               \
  1198 	}                                               \
  1199         if (__offs > 0)                                 \
  1199 	if (__offs > 0)                                 \
  1200             (ret) = __offs;                             \
  1200 	    (ret) = __offs;                             \
  1201    }
  1201    }
  1202 # else /* use STDIO */
  1202 # else /* use STDIO */
  1203 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1203 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1204     (ret) = 0;                                          \
  1204     (ret) = 0;                                          \
  1205     if (isBuffered) {                                   \
  1205     if (isBuffered) {                                   \
  1206         int __offs = 0;                                 \
  1206 	int __offs = 0;                                 \
  1207         while (__offs < (cnt)) {                        \
  1207 	while (__offs < (cnt)) {                        \
  1208             CLEAR_ERRNO;                                \
  1208 	    CLEAR_ERRNO;                                \
  1209             (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
  1209 	    (ret) = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
  1210             if ((ret) <= 0) {                            \
  1210 	    if ((ret) <= 0) {                            \
  1211                 if (ferror(f)) {                        \
  1211 		if (ferror(f)) {                        \
  1212                     if (errno == EINTR) {               \
  1212 		    if (errno == EINTR) {               \
  1213                         __HANDLE_INTERRUPTS__;          \
  1213 			__HANDLE_INTERRUPTS__;          \
  1214                         clearerr(f);                    \
  1214 			clearerr(f);                    \
  1215                         continue;                       \
  1215 			continue;                       \
  1216                     }                                   \
  1216 		    }                                   \
  1217                 } else {                                \
  1217 		} else {                                \
  1218                     (ret) = 0;                          \
  1218 		    (ret) = 0;                          \
  1219                 }                                       \
  1219 		}                                       \
  1220                 break;                                  \
  1220 		break;                                  \
  1221             }                                           \
  1221 	    }                                           \
  1222             __offs += (ret);                            \
  1222 	    __offs += (ret);                            \
  1223         }                                               \
  1223 	}                                               \
  1224         if (__offs > 0)                                 \
  1224 	if (__offs > 0)                                 \
  1225             (ret) = __offs;                             \
  1225 	    (ret) = __offs;                             \
  1226     } else {                                            \
  1226     } else {                                            \
  1227         int __offs = 0;                                 \
  1227 	int __offs = 0;                                 \
  1228         while (__offs < (cnt)) {                        \
  1228 	while (__offs < (cnt)) {                        \
  1229             CLEAR_ERRNO;                                \
  1229 	    CLEAR_ERRNO;                                \
  1230             (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\
  1230 	    (ret) = write(fileno(f), (buf)+__offs, (cnt)-__offs);\
  1231             if ((ret) <= 0) {                           \
  1231 	    if ((ret) <= 0) {                           \
  1232                 if ((ret) < 0) {                        \
  1232 		if ((ret) < 0) {                        \
  1233                     if (errno == EINTR) {               \
  1233 		    if (errno == EINTR) {               \
  1234                         __HANDLE_INTERRUPTS__;          \
  1234 			__HANDLE_INTERRUPTS__;          \
  1235                         continue;                       \
  1235 			continue;                       \
  1236                     }                                   \
  1236 		    }                                   \
  1237                 }                                       \
  1237 		}                                       \
  1238                 break;                                  \
  1238 		break;                                  \
  1239             }                                           \
  1239 	    }                                           \
  1240             __offs += (ret);                            \
  1240 	    __offs += (ret);                            \
  1241         }                                               \
  1241 	}                                               \
  1242         if (__offs > 0)                                 \
  1242 	if (__offs > 0)                                 \
  1243             (ret) = __offs;                             \
  1243 	    (ret) = __offs;                             \
  1244    }
  1244    }
  1245 # endif /* use STDIO */
  1245 # endif /* use STDIO */
  1246 
  1246 
  1247 /*
  1247 /*
  1248  * write_bytes from an object
  1248  * write_bytes from an object
  1252 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1252 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1253   {                                                     \
  1253   {                                                     \
  1254     int __ooffs = obj_offs;                             \
  1254     int __ooffs = obj_offs;                             \
  1255     int __offs = 0;                                     \
  1255     int __offs = 0;                                     \
  1256     char *buf = (char *)(obj);                          \
  1256     char *buf = (char *)(obj);                          \
  1257                                                         \
  1257 							\
  1258     (ret) = 0;                                          \
  1258     (ret) = 0;                                          \
  1259     {                                                   \
  1259     {                                                   \
  1260         while (__offs < (cnt)) {                        \
  1260 	while (__offs < (cnt)) {                        \
  1261             CLEAR_ERRNO;                                \
  1261 	    CLEAR_ERRNO;                                \
  1262             ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1262 	    ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1263             if (ret <= 0) {                             \
  1263 	    if (ret <= 0) {                             \
  1264                 if (ret < 0 && errno == EINTR) {        \
  1264 		if (ret < 0 && errno == EINTR) {        \
  1265                     __HANDLE_INTERRUPTS__;              \
  1265 		    __HANDLE_INTERRUPTS__;              \
  1266                     /* refetch */                       \
  1266 		    /* refetch */                       \
  1267                     buf = (char *)(obj);                \
  1267 		    buf = (char *)(obj);                \
  1268                     continue;                           \
  1268 		    continue;                           \
  1269                 }                                       \
  1269 		}                                       \
  1270                 break;                                  \
  1270 		break;                                  \
  1271             }                                           \
  1271 	    }                                           \
  1272             __offs += (ret);                            \
  1272 	    __offs += (ret);                            \
  1273         }                                               \
  1273 	}                                               \
  1274         if (__offs > 0)                                 \
  1274 	if (__offs > 0)                                 \
  1275             (ret) = __offs;                             \
  1275 	    (ret) = __offs;                             \
  1276     }                                                   \
  1276     }                                                   \
  1277   }
  1277   }
  1278 # else /* use STDIO */
  1278 # else /* use STDIO */
  1279 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1279 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1280   {                                                     \
  1280   {                                                     \
  1281     int __ooffs = obj_offs;                             \
  1281     int __ooffs = obj_offs;                             \
  1282     int __offs = 0;                                     \
  1282     int __offs = 0;                                     \
  1283     char *buf = (char *)(obj);                          \
  1283     char *buf = (char *)(obj);                          \
  1284                                                         \
  1284 							\
  1285     (ret) = 0;                                          \
  1285     (ret) = 0;                                          \
  1286     if (isBuffered) {                                   \
  1286     if (isBuffered) {                                   \
  1287         while (__offs < (cnt)) {                        \
  1287 	while (__offs < (cnt)) {                        \
  1288             CLEAR_ERRNO;                                \
  1288 	    CLEAR_ERRNO;                                \
  1289             (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f);  \
  1289 	    (ret) = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f);  \
  1290             if ((ret) <= 0) {                           \
  1290 	    if ((ret) <= 0) {                           \
  1291                 if (ferror(f)) {                        \
  1291 		if (ferror(f)) {                        \
  1292                     if (errno == EINTR) {               \
  1292 		    if (errno == EINTR) {               \
  1293                         __HANDLE_INTERRUPTS__;          \
  1293 			__HANDLE_INTERRUPTS__;          \
  1294                         /* refetch */                   \
  1294 			/* refetch */                   \
  1295                         buf = (char *)(obj);            \
  1295 			buf = (char *)(obj);            \
  1296                         clearerr(f);                    \
  1296 			clearerr(f);                    \
  1297                         continue;                       \
  1297 			continue;                       \
  1298                     }                                   \
  1298 		    }                                   \
  1299                     break;                              \
  1299 		    break;                              \
  1300                 } else {                                \
  1300 		} else {                                \
  1301                     (ret) = 0;                          \
  1301 		    (ret) = 0;                          \
  1302                 }                                       \
  1302 		}                                       \
  1303             }                                           \
  1303 	    }                                           \
  1304             __offs += (ret);                            \
  1304 	    __offs += (ret);                            \
  1305         }                                               \
  1305 	}                                               \
  1306     } else {                                            \
  1306     } else {                                            \
  1307         while (__offs < (cnt)) {                        \
  1307 	while (__offs < (cnt)) {                        \
  1308             CLEAR_ERRNO;                                \
  1308 	    CLEAR_ERRNO;                                \
  1309             (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \
  1309 	    (ret) = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs); \
  1310             if ((ret) <= 0) {                           \
  1310 	    if ((ret) <= 0) {                           \
  1311                 if ((ret) < 0) {                        \
  1311 		if ((ret) < 0) {                        \
  1312                     if (errno == EINTR){                \
  1312 		    if (errno == EINTR){                \
  1313                         __HANDLE_INTERRUPTS__;          \
  1313 			__HANDLE_INTERRUPTS__;          \
  1314                         /* refetch */                   \
  1314 			/* refetch */                   \
  1315                         buf = (char *)(obj);            \
  1315 			buf = (char *)(obj);            \
  1316                         continue;                       \
  1316 			continue;                       \
  1317                     }                                   \
  1317 		    }                                   \
  1318                 }                                       \
  1318 		}                                       \
  1319                 break;                                  \
  1319 		break;                                  \
  1320             }                                           \
  1320 	    }                                           \
  1321             __offs += (ret);                            \
  1321 	    __offs += (ret);                            \
  1322         }                                               \
  1322 	}                                               \
  1323     }                                                   \
  1323     }                                                   \
  1324     if (__offs > 0)                                     \
  1324     if (__offs > 0)                                     \
  1325         (ret) = __offs;                                 \
  1325 	(ret) = __offs;                                 \
  1326   }
  1326   }
  1327 # endif /* use STDIO */
  1327 # endif /* use STDIO */
  1328 #endif /* unix */
  1328 #endif /* unix */
  1329 %}
  1329 %}
  1330 ! !
  1330 ! !
  2029 !
  2029 !
  2030 
  2030 
  2031 eolMode
  2031 eolMode
  2032     "return how end-of-line (EOL) is to be marked.
  2032     "return how end-of-line (EOL) is to be marked.
  2033      Returns one one of:
  2033      Returns one one of:
  2034         #crlf         -> add a CR-NL, as in MSDOS
  2034 	#crlf         -> add a CR-NL, as in MSDOS
  2035         #cr           -> add a CR, as in VMS
  2035 	#cr           -> add a CR, as in VMS
  2036         #nl           -> add a NL, as in Unix
  2036 	#nl           -> add a NL, as in Unix
  2037         nil           -> transparent
  2037 	nil           -> transparent
  2038     "
  2038     "
  2039 
  2039 
  2040     ^ eolMode 
  2040     ^ eolMode
  2041 !
  2041 !
  2042 
  2042 
  2043 eolMode:aSymbolOrNil
  2043 eolMode:aSymbolOrNil
  2044     "specify how end-of-line (EOL) is to be marked.
  2044     "specify how end-of-line (EOL) is to be marked.
  2045      The argument may be one of:
  2045      The argument may be one of:
  2497 finalize
  2497 finalize
  2498     "some Stream has been collected - close the file if not already done"
  2498     "some Stream has been collected - close the file if not already done"
  2499 
  2499 
  2500     "/ with timeout to avoid blocking in a bad pty/socket
  2500     "/ with timeout to avoid blocking in a bad pty/socket
  2501     [
  2501     [
  2502         self closeFile
  2502 	self closeFile
  2503     ] valueWithTimeout:30 seconds.
  2503     ] valueWithTimeout:30 seconds.
  2504 ! !
  2504 ! !
  2505 
  2505 
  2506 !ExternalStream methodsFor:'initialization'!
  2506 !ExternalStream methodsFor:'initialization'!
  2507 
  2507 
  2540     if ((__INST(handleType) == nil)
  2540     if ((__INST(handleType) == nil)
  2541      || (__INST(handleType) == @symbol(filePointer))
  2541      || (__INST(handleType) == @symbol(filePointer))
  2542      || (__INST(handleType) == @symbol(socketFilePointer))
  2542      || (__INST(handleType) == @symbol(socketFilePointer))
  2543      || (__INST(handleType) == @symbol(socketHandle))
  2543      || (__INST(handleType) == @symbol(socketHandle))
  2544      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2544      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2545         if (((fp = __INST(handle)) != nil)
  2545 	if (((fp = __INST(handle)) != nil)
  2546             && (__INST(mode) != @symbol(writeonly))
  2546 	    && (__INST(mode) != @symbol(writeonly))
  2547             && (__INST(binary) != true)
  2547 	    && (__INST(binary) != true)
  2548         ) {
  2548 	) {
  2549             f = __FILEVal(fp);
  2549 	    f = __FILEVal(fp);
  2550             buffer[0] = '\0';
  2550 	    buffer[0] = '\0';
  2551 
  2551 
  2552             _buffered = (__INST(buffered) == true);
  2552 	    _buffered = (__INST(buffered) == true);
  2553             if (_buffered) {
  2553 	    if (_buffered) {
  2554                 __READING__(f);
  2554 		__READING__(f);
  2555             }
  2555 	    }
  2556 
  2556 
  2557             rslt = nextPtr = buffer;
  2557 	    rslt = nextPtr = buffer;
  2558             limit = buffer + sizeof(buffer) - 2;
  2558 	    limit = buffer + sizeof(buffer) - 2;
  2559 
  2559 
  2560             for (;;) {
  2560 	    for (;;) {
  2561                 __READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType));
  2561 		__READBYTE__(ret, f, nextPtr, _buffered, __INST(handleType));
  2562                 if (ret <= 0) {
  2562 		if (ret <= 0) {
  2563                     if (nextPtr == buffer)
  2563 		    if (nextPtr == buffer)
  2564                         rslt = NULL;
  2564 			rslt = NULL;
  2565                     if (ret == 0) {
  2565 		    if (ret == 0) {
  2566                         __INST(hitEOF) = true;
  2566 			__INST(hitEOF) = true;
  2567                         break;
  2567 			break;
  2568                     } else {
  2568 		    } else {
  2569                         error = __mkSmallInteger(__threadErrno);
  2569 			error = __mkSmallInteger(__threadErrno);
  2570                         goto err;
  2570 			goto err;
  2571                     }
  2571 		    }
  2572                 }
  2572 		}
  2573 
  2573 
  2574                 if (*nextPtr == '\n') {
  2574 		if (*nextPtr == '\n') {
  2575                     cutOff = 1;
  2575 		    cutOff = 1;
  2576                     *nextPtr = '\0';
  2576 		    *nextPtr = '\0';
  2577                     break;
  2577 		    break;
  2578                 }
  2578 		}
  2579                 if (*nextPtr == '\r') {
  2579 		if (*nextPtr == '\r') {
  2580                     char peekChar;
  2580 		    char peekChar;
  2581 
  2581 
  2582                     /*
  2582 		    /*
  2583                      * peek ahead for a newLine ...
  2583 		     * peek ahead for a newLine ...
  2584                      */
  2584 		     */
  2585                     __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType));
  2585 		    __READBYTE__(ret, f, &peekChar, _buffered, __INST(handleType));
  2586                     if (ret <= 0) {
  2586 		    if (ret <= 0) {
  2587                         cutOff = 1;
  2587 			cutOff = 1;
  2588                         *nextPtr = '\0';
  2588 			*nextPtr = '\0';
  2589                         if (ret == 0) {
  2589 			if (ret == 0) {
  2590                             __INST(hitEOF) = true;
  2590 			    __INST(hitEOF) = true;
  2591                             break;
  2591 			    break;
  2592                         }
  2592 			}
  2593                         error = __mkSmallInteger(__threadErrno);
  2593 			error = __mkSmallInteger(__threadErrno);
  2594                         goto err;
  2594 			goto err;
  2595                     }
  2595 		    }
  2596 
  2596 
  2597                     if (peekChar == '\n') {
  2597 		    if (peekChar == '\n') {
  2598                         cutOff = 2;
  2598 			cutOff = 2;
  2599                         *nextPtr = '\0';
  2599 			*nextPtr = '\0';
  2600                         break;
  2600 			break;
  2601                     }
  2601 		    }
  2602 
  2602 
  2603                     __UNGETC__(peekChar, f, _buffered);
  2603 		    __UNGETC__(peekChar, f, _buffered);
  2604 
  2604 
  2605                     cutOff = 1;
  2605 		    cutOff = 1;
  2606                     *nextPtr = '\0';
  2606 		    *nextPtr = '\0';
  2607                     break;
  2607 		    break;
  2608                 }
  2608 		}
  2609 
  2609 
  2610                 nextPtr++;
  2610 		nextPtr++;
  2611                 if (nextPtr >= limit) {
  2611 		if (nextPtr >= limit) {
  2612                     *nextPtr = '\0';
  2612 		    *nextPtr = '\0';
  2613                     lineTooLong = 1;
  2613 		    lineTooLong = 1;
  2614                     if (@global(InfoPrinting) == true) {
  2614 		    if (@global(InfoPrinting) == true) {
  2615                         fprintf(stderr, "ExtStream [warning]: line truncated in nextLine\n");
  2615 			fprintf(stderr, "ExtStream [warning]: line truncated in nextLine\n");
  2616                     }
  2616 		    }
  2617                     break;
  2617 		    break;
  2618                 }
  2618 		}
  2619             }
  2619 	    }
  2620 
  2620 
  2621             if (rslt != NULL) {
  2621 	    if (rslt != NULL) {
  2622                 len = nextPtr-buffer;
  2622 		len = nextPtr-buffer;
  2623 
  2623 
  2624                 if (__isSmallInteger(__INST(position))) {
  2624 		if (__isSmallInteger(__INST(position))) {
  2625                     INT np = __intVal(__INST(position)) + len + cutOff;
  2625 		    INT np = __intVal(__INST(position)) + len + cutOff;
  2626                     OBJ t;
  2626 		    OBJ t;
  2627 
  2627 
  2628                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  2628 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  2629                 } else {
  2629 		} else {
  2630                     __INST(position) = nil; /* i.e. do not know */
  2630 		    __INST(position) = nil; /* i.e. do not know */
  2631                 }
  2631 		}
  2632                 /* remove any EOL character */
  2632 		/* remove any EOL character */
  2633                 if (len != 0) {
  2633 		if (len != 0) {
  2634                     if (buffer[len-1] == '\n') {
  2634 		    if (buffer[len-1] == '\n') {
  2635                         buffer[--len] = '\0';
  2635 			buffer[--len] = '\0';
  2636                     }
  2636 		    }
  2637                     if ((len != 0) && (buffer[len-1] == '\r')) {
  2637 		    if ((len != 0) && (buffer[len-1] == '\r')) {
  2638                         buffer[--len] = '\0';
  2638 			buffer[--len] = '\0';
  2639                     }
  2639 		    }
  2640                 }
  2640 		}
  2641                 line = __MKSTRING_L(buffer, len);
  2641 		line = __MKSTRING_L(buffer, len);
  2642                 if (! lineTooLong) {
  2642 		if (! lineTooLong) {
  2643                     RETURN ( line );
  2643 		    RETURN ( line );
  2644                 }
  2644 		}
  2645             }
  2645 	    }
  2646         }
  2646 	}
  2647     }
  2647     }
  2648 err: ;
  2648 err: ;
  2649 %}.
  2649 %}.
  2650     line notNil ifTrue:[
  2650     line notNil ifTrue:[
  2651         "/ the line as read is longer than 32k characters (boy - what a line)
  2651 	"/ the line as read is longer than 32k characters (boy - what a line)
  2652         "/ The exception could be handled by reading more and returning the
  2652 	"/ The exception could be handled by reading more and returning the
  2653         "/ concatenation in your exception handler (the receiver and the partial
  2653 	"/ concatenation in your exception handler (the receiver and the partial
  2654         "/ line are passed as parameter)
  2654 	"/ line are passed as parameter)
  2655 
  2655 
  2656         LineTooLongErrorSignal isHandled ifTrue:[
  2656 	LineTooLongErrorSignal isHandled ifTrue:[
  2657             ^ LineTooLongErrorSignal
  2657 	    ^ LineTooLongErrorSignal
  2658                 raiseRequestWith:(Array with:self with:line)
  2658 		raiseRequestWith:(Array with:self with:line)
  2659                      errorString:('line too long read error')
  2659 		     errorString:('line too long read error')
  2660         ].
  2660 	].
  2661         ^ line , self nextLine
  2661 	^ line , self nextLine
  2662     ].
  2662     ].
  2663 
  2663 
  2664     (hitEOF == true) ifTrue:[^ self pastEndRead].
  2664     (hitEOF == true) ifTrue:[^ self pastEndRead].
  2665     error notNil ifTrue:[
  2665     error notNil ifTrue:[
  2666         lastErrorNumber := error.
  2666 	lastErrorNumber := error.
  2667         ^ self readError:error
  2667 	^ self readError:error
  2668     ].
  2668     ].
  2669     handle isNil ifTrue:[^ self errorNotOpen].
  2669     handle isNil ifTrue:[^ self errorNotOpen].
  2670     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  2670     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  2671     (binary == true) ifTrue:[^ self errorBinary].
  2671     (binary == true) ifTrue:[^ self errorBinary].
  2672     ^ super nextLine
  2672     ^ super nextLine
  4573 	do {
  4573 	do {
  4574 	    __threadErrno = 0;
  4574 	    __threadErrno = 0;
  4575 	    rslt = __STX_C_NOINT_CALL1("fclose", fclose, f);
  4575 	    rslt = __STX_C_NOINT_CALL1("fclose", fclose, f);
  4576 	} while((rslt < 0) && (__threadErrno == EINTR));
  4576 	} while((rslt < 0) && (__threadErrno == EINTR));
  4577 #else
  4577 #else
  4578 	__BEGIN_INTERRUPTABLE__
  4578 	// cg: the pre Nov2014 code always did the fclose interruptable;
  4579 	rslt = fclose(f);
  4579 	// I am not sure, if fclose is actually prepared to do this;
  4580 	__END_INTERRUPTABLE__
  4580 	// at least when only reading, this should not block, and we
       
  4581 	// should be ableto do it without being interruptable.
       
  4582 	// Must watch this - if it leads to blockings, change and think about it.
       
  4583 	if (__INST(mode) != @symbol(readonly)) {
       
  4584 	    __BEGIN_INTERRUPTABLE__
       
  4585 	    rslt = fclose(f);
       
  4586 	    __END_INTERRUPTABLE__
       
  4587 	} else {
       
  4588 	    rslt = fclose(f);
       
  4589 	}
  4581 #endif
  4590 #endif
  4582     } else {
  4591     } else {
  4583 	error = @symbol(badHandleType);
  4592 	error = @symbol(badHandleType);
  4584 	goto out;
  4593 	goto out;
  4585     }
  4594     }
  4597 	error == #errorNotOpen ifTrue:[
  4606 	error == #errorNotOpen ifTrue:[
  4598 	    self errorNotOpen.
  4607 	    self errorNotOpen.
  4599 	].
  4608 	].
  4600 	error isInteger ifTrue:[
  4609 	error isInteger ifTrue:[
  4601 	    lastErrorNumber := error.
  4610 	    lastErrorNumber := error.
  4602 	    self writeError:error.
  4611 	    mode == #readonly ifTrue:[
       
  4612 		self ioError:error.
       
  4613 	    ] ifFalse:[
       
  4614 		self writeError:error.
       
  4615 	    ].
  4603 	    ^ self.
  4616 	    ^ self.
  4604 	].
  4617 	].
  4605 	self primitiveFailed:error.
  4618 	self primitiveFailed:error.
  4606 	^ self.
  4619 	^ self.
  4607     ].
  4620     ].
  4990     if ((__INST(handleType) == nil)
  5003     if ((__INST(handleType) == nil)
  4991      || (__INST(handleType) == @symbol(filePointer))
  5004      || (__INST(handleType) == @symbol(filePointer))
  4992      || (__INST(handleType) == @symbol(socketFilePointer))
  5005      || (__INST(handleType) == @symbol(socketFilePointer))
  4993      || (__INST(handleType) == @symbol(socketHandle))
  5006      || (__INST(handleType) == @symbol(socketHandle))
  4994      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5007      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4995         if (((fp = __INST(handle)) != nil)
  5008 	if (((fp = __INST(handle)) != nil)
  4996             && (__INST(mode) != @symbol(writeonly))
  5009 	    && (__INST(mode) != @symbol(writeonly))
  4997         ) {
  5010 	) {
  4998             f = __FILEVal(fp);
  5011 	    f = __FILEVal(fp);
  4999 
  5012 
  5000             _buffered = (__INST(buffered) == true);
  5013 	    _buffered = (__INST(buffered) == true);
  5001             if (_buffered) {
  5014 	    if (_buffered) {
  5002                 __READING__(f)
  5015 		__READING__(f)
  5003             }
  5016 	    }
  5004             __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5017 	    __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5005 
  5018 
  5006             if (ret > 0) {
  5019 	    if (ret > 0) {
  5007                 pos = __INST(position);
  5020 		pos = __INST(position);
  5008                 if (__isSmallInteger(pos)) {
  5021 		if (__isSmallInteger(pos)) {
  5009                     OBJ t;
  5022 		    OBJ t;
  5010 
  5023 
  5011                     t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5024 		    t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5012                 } else {
  5025 		} else {
  5013                     __INST(position) = nil; /* i.e. do not know */
  5026 		    __INST(position) = nil; /* i.e. do not know */
  5014                 }
  5027 		}
  5015                 if (__INST(binary) == true) {
  5028 		if (__INST(binary) == true) {
  5016                     RETURN ( __mkSmallInteger(ch) );
  5029 		    RETURN ( __mkSmallInteger(ch) );
  5017                 }
  5030 		}
  5018                 RETURN ( __MKCHARACTER(ch) );
  5031 		RETURN ( __MKCHARACTER(ch) );
  5019             }
  5032 	    }
  5020 
  5033 
  5021             __INST(position) = nil;
  5034 	    __INST(position) = nil;
  5022             if (ret < 0) {
  5035 	    if (ret < 0) {
  5023                 error = __mkSmallInteger(__threadErrno);
  5036 		error = __mkSmallInteger(__threadErrno);
  5024             } else /* ret == 0 */ {
  5037 	    } else /* ret == 0 */ {
  5025                 __INST(hitEOF) = true;
  5038 		__INST(hitEOF) = true;
  5026             }
  5039 	    }
  5027         }
  5040 	}
  5028     }
  5041     }
  5029 %}.
  5042 %}.
  5030     hitEOF == true ifTrue:[^ self pastEndRead].
  5043     hitEOF == true ifTrue:[^ self pastEndRead].
  5031     error notNil ifTrue:[
  5044     error notNil ifTrue:[
  5032         lastErrorNumber := error.
  5045 	lastErrorNumber := error.
  5033         ^ self readError:error
  5046 	^ self readError:error
  5034     ].
  5047     ].
  5035     handle isNil ifTrue:[^ self errorNotOpen].
  5048     handle isNil ifTrue:[^ self errorNotOpen].
  5036     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5049     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5037 
  5050 
  5038     readAhead notNil ifTrue:[
  5051     readAhead notNil ifTrue:[
  5039         c := readAhead.
  5052 	c := readAhead.
  5040         readAhead := nil.
  5053 	readAhead := nil.
  5041         ^ c.
  5054 	^ c.
  5042     ].
  5055     ].
  5043     c := self nextByteFromFile:handle.
  5056     c := self nextByteFromFile:handle.
  5044     c isNil ifTrue:[
  5057     c isNil ifTrue:[
  5045         ^ self pastEndRead.
  5058 	^ self pastEndRead.
  5046     ].
  5059     ].
  5047     binary == true ifTrue:[
  5060     binary == true ifTrue:[
  5048         ^ c
  5061 	^ c
  5049     ].
  5062     ].
  5050     ^ Character value:c
  5063     ^ Character value:c
  5051 !
  5064 !
  5052 
  5065 
  5053 next:count
  5066 next:count
  5055      Redefined to return a String or ByteArray instead of the default: Array."
  5068      Redefined to return a String or ByteArray instead of the default: Array."
  5056 
  5069 
  5057     |coll nRead|
  5070     |coll nRead|
  5058 
  5071 
  5059     binary ifTrue:[
  5072     binary ifTrue:[
  5060         coll := ByteArray uninitializedNew:count
  5073 	coll := ByteArray uninitializedNew:count
  5061     ] ifFalse:[
  5074     ] ifFalse:[
  5062         coll := String new:count
  5075 	coll := String new:count
  5063     ].
  5076     ].
  5064     nRead := self nextBytes:count into:coll startingAt:1.
  5077     nRead := self nextBytes:count into:coll startingAt:1.
  5065 
  5078 
  5066     "/ for readStream protocol compatibility,
  5079     "/ for readStream protocol compatibility,
  5067     "/ we must raise an exception here.
  5080     "/ we must raise an exception here.
  5068 
  5081 
  5069     nRead < count ifTrue:[
  5082     nRead < count ifTrue:[
  5070         ^ self pastEndRead
  5083 	^ self pastEndRead
  5071     ].
  5084     ].
  5072     ^ coll
  5085     ^ coll
  5073 
  5086 
  5074     "Modified: 11.1.1997 / 17:44:17 / cg"
  5087     "Modified: 11.1.1997 / 17:44:17 / cg"
  5075 !
  5088 !
  5091     if ((__INST(handleType) == nil)
  5104     if ((__INST(handleType) == nil)
  5092      || (__INST(handleType) == @symbol(filePointer))
  5105      || (__INST(handleType) == @symbol(filePointer))
  5093      || (__INST(handleType) == @symbol(socketFilePointer))
  5106      || (__INST(handleType) == @symbol(socketFilePointer))
  5094      || (__INST(handleType) == @symbol(socketHandle))
  5107      || (__INST(handleType) == @symbol(socketHandle))
  5095      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5108      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5096         if (((fp = __INST(handle)) != nil)
  5109 	if (((fp = __INST(handle)) != nil)
  5097             && (__INST(mode) != @symbol(writeonly))
  5110 	    && (__INST(mode) != @symbol(writeonly))
  5098         ) {
  5111 	) {
  5099             f = __FILEVal(fp);
  5112 	    f = __FILEVal(fp);
  5100 
  5113 
  5101             _buffered = (__INST(buffered) == true);
  5114 	    _buffered = (__INST(buffered) == true);
  5102             if (_buffered) {
  5115 	    if (_buffered) {
  5103                 __READING__(f)
  5116 		__READING__(f)
  5104             }
  5117 	    }
  5105             __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5118 	    __READBYTE__(ret, f, &ch, _buffered, __INST(handleType));
  5106 
  5119 
  5107             if (ret > 0) {
  5120 	    if (ret > 0) {
  5108                 pos = __INST(position);
  5121 		pos = __INST(position);
  5109                 if (__isSmallInteger(pos)) {
  5122 		if (__isSmallInteger(pos)) {
  5110                     OBJ t;
  5123 		    OBJ t;
  5111 
  5124 
  5112                     t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5125 		    t = __MKINT(__intVal(pos) + 1); __INST(position) = t; __STORE(self, t);
  5113                 } else {
  5126 		} else {
  5114                     __INST(position) = nil; /* i.e. do not know */
  5127 		    __INST(position) = nil; /* i.e. do not know */
  5115                 }
  5128 		}
  5116                 if (__INST(binary) == true) {
  5129 		if (__INST(binary) == true) {
  5117                     RETURN ( __mkSmallInteger(ch) );
  5130 		    RETURN ( __mkSmallInteger(ch) );
  5118                 }
  5131 		}
  5119                 RETURN ( __MKCHARACTER(ch) );
  5132 		RETURN ( __MKCHARACTER(ch) );
  5120             }
  5133 	    }
  5121 
  5134 
  5122             __INST(position) = nil;
  5135 	    __INST(position) = nil;
  5123             if (ret < 0) {
  5136 	    if (ret < 0) {
  5124                 error = __mkSmallInteger(__threadErrno);
  5137 		error = __mkSmallInteger(__threadErrno);
  5125             } else /* ret == 0 */ {
  5138 	    } else /* ret == 0 */ {
  5126                 __INST(hitEOF) = true;
  5139 		__INST(hitEOF) = true;
  5127             }
  5140 	    }
  5128         }
  5141 	}
  5129     }
  5142     }
  5130 %}.
  5143 %}.
  5131     hitEOF == true ifTrue:[^ nil].
  5144     hitEOF == true ifTrue:[^ nil].
  5132     error notNil ifTrue:[
  5145     error notNil ifTrue:[
  5133         lastErrorNumber := error.
  5146 	lastErrorNumber := error.
  5134         ^ self readError:error.
  5147 	^ self readError:error.
  5135     ].
  5148     ].
  5136     handle isNil ifTrue:[^ self errorNotOpen].
  5149     handle isNil ifTrue:[^ self errorNotOpen].
  5137     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5150     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5138 
  5151 
  5139     readAhead notNil ifTrue:[
  5152     readAhead notNil ifTrue:[
  5140         c := readAhead.
  5153 	c := readAhead.
  5141         readAhead := nil.
  5154 	readAhead := nil.
  5142         ^ c.
  5155 	^ c.
  5143     ].
  5156     ].
  5144     c := self nextByteFromFile:handle.
  5157     c := self nextByteFromFile:handle.
  5145     c isNil ifTrue:[
  5158     c isNil ifTrue:[
  5146         ^ nil.
  5159 	^ nil.
  5147     ].
  5160     ].
  5148     binary == true ifTrue:[
  5161     binary == true ifTrue:[
  5149         ^ c
  5162 	^ c
  5150     ].
  5163     ].
  5151     ^ Character value:c
  5164     ^ Character value:c
  5152 !
  5165 !
  5153 
  5166 
  5154 peek
  5167 peek
  5164     int ret, _buffered;
  5177     int ret, _buffered;
  5165     OBJ fp;
  5178     OBJ fp;
  5166     OBJ ra;
  5179     OBJ ra;
  5167 
  5180 
  5168     if ((ra = __INST(readAhead)) != nil) {
  5181     if ((ra = __INST(readAhead)) != nil) {
  5169         if (__INST(binary) == true) {
  5182 	if (__INST(binary) == true) {
  5170             RETURN ( ra );
  5183 	    RETURN ( ra );
  5171         }
  5184 	}
  5172         c = __intVal(ra);
  5185 	c = __intVal(ra);
  5173         RETURN ( __MKCHARACTER(c) );
  5186 	RETURN ( __MKCHARACTER(c) );
  5174     }
  5187     }
  5175 
  5188 
  5176     __INST(lastErrorNumber) = nil;
  5189     __INST(lastErrorNumber) = nil;
  5177 
  5190 
  5178     if ((__INST(handleType) == nil)
  5191     if ((__INST(handleType) == nil)
  5179      || (__INST(handleType) == @symbol(filePointer))
  5192      || (__INST(handleType) == @symbol(filePointer))
  5180      || (__INST(handleType) == @symbol(socketFilePointer))
  5193      || (__INST(handleType) == @symbol(socketFilePointer))
  5181      || (__INST(handleType) == @symbol(socketHandle))
  5194      || (__INST(handleType) == @symbol(socketHandle))
  5182      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5195      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5183         if (((fp = __INST(handle)) != nil)
  5196 	if (((fp = __INST(handle)) != nil)
  5184             && (__INST(mode) != @symbol(writeonly))
  5197 	    && (__INST(mode) != @symbol(writeonly))
  5185         ) {
  5198 	) {
  5186             f = __FILEVal(fp);
  5199 	    f = __FILEVal(fp);
  5187             _buffered = (__INST(buffered) == true);
  5200 	    _buffered = (__INST(buffered) == true);
  5188             if (_buffered) {
  5201 	    if (_buffered) {
  5189                 __READING__(f)
  5202 		__READING__(f)
  5190             }
  5203 	    }
  5191             __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5204 	    __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5192 
  5205 
  5193             if (ret > 0) {
  5206 	    if (ret > 0) {
  5194                 __UNGETC__(c, f, _buffered);
  5207 		__UNGETC__(c, f, _buffered);
  5195 
  5208 
  5196                 if (__INST(binary) == true) {
  5209 		if (__INST(binary) == true) {
  5197                     RETURN ( __mkSmallInteger(c) );
  5210 		    RETURN ( __mkSmallInteger(c) );
  5198                 }
  5211 		}
  5199                 RETURN ( __MKCHARACTER(c) );
  5212 		RETURN ( __MKCHARACTER(c) );
  5200             }
  5213 	    }
  5201             if (ret < 0) {
  5214 	    if (ret < 0) {
  5202                 error = __mkSmallInteger(__threadErrno);
  5215 		error = __mkSmallInteger(__threadErrno);
  5203             } else /* ret == 0 */ {
  5216 	    } else /* ret == 0 */ {
  5204                 __INST(hitEOF) = true;
  5217 		__INST(hitEOF) = true;
  5205             }
  5218 	    }
  5206         }
  5219 	}
  5207     }
  5220     }
  5208 %}.
  5221 %}.
  5209     hitEOF == true ifTrue:[^ self pastEndRead].
  5222     hitEOF == true ifTrue:[^ self pastEndRead].
  5210     error notNil ifTrue:[
  5223     error notNil ifTrue:[
  5211         lastErrorNumber := error.
  5224 	lastErrorNumber := error.
  5212         ^ self readError:error.
  5225 	^ self readError:error.
  5213     ].
  5226     ].
  5214     handle isNil ifTrue:[^ self errorNotOpen].
  5227     handle isNil ifTrue:[^ self errorNotOpen].
  5215     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5228     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5216 
  5229 
  5217     readAhead isNil ifTrue:[
  5230     readAhead isNil ifTrue:[
  5218         readAhead := self nextOrNil.
  5231 	readAhead := self nextOrNil.
  5219         readAhead isNil ifTrue:[
  5232 	readAhead isNil ifTrue:[
  5220             ^ self pastEndRead.
  5233 	    ^ self pastEndRead.
  5221         ].
  5234 	].
  5222     ].
  5235     ].
  5223     ^ readAhead
  5236     ^ readAhead
  5224 !
  5237 !
  5225 
  5238 
  5226 peekOrNil
  5239 peekOrNil
  5236     int ret, _buffered;
  5249     int ret, _buffered;
  5237     OBJ fp;
  5250     OBJ fp;
  5238     OBJ ra;
  5251     OBJ ra;
  5239 
  5252 
  5240     if ((ra = __INST(readAhead)) != nil) {
  5253     if ((ra = __INST(readAhead)) != nil) {
  5241         if (__INST(binary) == true) {
  5254 	if (__INST(binary) == true) {
  5242             RETURN ( ra );
  5255 	    RETURN ( ra );
  5243         }
  5256 	}
  5244         c = __intVal(ra);
  5257 	c = __intVal(ra);
  5245         RETURN ( __MKCHARACTER(c) );
  5258 	RETURN ( __MKCHARACTER(c) );
  5246     }
  5259     }
  5247 
  5260 
  5248     __INST(lastErrorNumber) = nil;
  5261     __INST(lastErrorNumber) = nil;
  5249 
  5262 
  5250     if ((__INST(handleType) == nil)
  5263     if ((__INST(handleType) == nil)
  5251      || (__INST(handleType) == @symbol(filePointer))
  5264      || (__INST(handleType) == @symbol(filePointer))
  5252      || (__INST(handleType) == @symbol(socketFilePointer))
  5265      || (__INST(handleType) == @symbol(socketFilePointer))
  5253      || (__INST(handleType) == @symbol(socketHandle))
  5266      || (__INST(handleType) == @symbol(socketHandle))
  5254      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5267      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5255         if (((fp = __INST(handle)) != nil)
  5268 	if (((fp = __INST(handle)) != nil)
  5256             && (__INST(mode) != @symbol(writeonly))
  5269 	    && (__INST(mode) != @symbol(writeonly))
  5257         ) {
  5270 	) {
  5258             f = __FILEVal(fp);
  5271 	    f = __FILEVal(fp);
  5259             _buffered = (__INST(buffered) == true);
  5272 	    _buffered = (__INST(buffered) == true);
  5260             if (_buffered) {
  5273 	    if (_buffered) {
  5261                 __READING__(f)
  5274 		__READING__(f)
  5262             }
  5275 	    }
  5263             __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5276 	    __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5264 
  5277 
  5265             if (ret > 0) {
  5278 	    if (ret > 0) {
  5266                 __UNGETC__(c, f, _buffered);
  5279 		__UNGETC__(c, f, _buffered);
  5267 
  5280 
  5268                 if (__INST(binary) == true) {
  5281 		if (__INST(binary) == true) {
  5269                     RETURN ( __mkSmallInteger(c) );
  5282 		    RETURN ( __mkSmallInteger(c) );
  5270                 }
  5283 		}
  5271                 RETURN ( __MKCHARACTER(c) );
  5284 		RETURN ( __MKCHARACTER(c) );
  5272             }
  5285 	    }
  5273             if (ret < 0) {
  5286 	    if (ret < 0) {
  5274                 error = __mkSmallInteger(__threadErrno);
  5287 		error = __mkSmallInteger(__threadErrno);
  5275             } else /* ret == 0 */ {
  5288 	    } else /* ret == 0 */ {
  5276                 __INST(hitEOF) = true;
  5289 		__INST(hitEOF) = true;
  5277             }
  5290 	    }
  5278         }
  5291 	}
  5279     }
  5292     }
  5280 %}.
  5293 %}.
  5281     hitEOF == true ifTrue:[^ nil].
  5294     hitEOF == true ifTrue:[^ nil].
  5282     error notNil ifTrue:[
  5295     error notNil ifTrue:[
  5283         lastErrorNumber := error.
  5296 	lastErrorNumber := error.
  5284         ^ self readError:error.
  5297 	^ self readError:error.
  5285     ].
  5298     ].
  5286     handle isNil ifTrue:[^ self errorNotOpen].
  5299     handle isNil ifTrue:[^ self errorNotOpen].
  5287     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5300     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  5288 
  5301 
  5289     readAhead isNil ifTrue:[
  5302     readAhead isNil ifTrue:[
  5290         readAhead := self nextOrNil.
  5303 	readAhead := self nextOrNil.
  5291     ].
  5304     ].
  5292     ^ readAhead
  5305     ^ readAhead
  5293 !
  5306 !
  5294 
  5307 
  5295 upToEnd
  5308 upToEnd
  5351     OBJ fp, pos, lim;
  5364     OBJ fp, pos, lim;
  5352     char c;
  5365     char c;
  5353     int ret, _buffered;
  5366     int ret, _buffered;
  5354 
  5367 
  5355     if (__INST(hitEOF) == true) {
  5368     if (__INST(hitEOF) == true) {
  5356         RETURN (true);
  5369 	RETURN (true);
  5357     }
  5370     }
  5358     pos = __INST(position);
  5371     pos = __INST(position);
  5359     lim = __INST(readLimit);
  5372     lim = __INST(readLimit);
  5360     if (lim != nil) {
  5373     if (lim != nil) {
  5361         off_t _pos, _readLimit;
  5374 	off_t _pos, _readLimit;
  5362 
  5375 
  5363         _pos = __signedLongIntVal(pos);
  5376 	_pos = __signedLongIntVal(pos);
  5364         _pos = _pos - __intVal( @global(PositionableStream:ZeroPosition)) + 1;
  5377 	_pos = _pos - __intVal( @global(PositionableStream:ZeroPosition)) + 1;
  5365         _readLimit = __signedLongIntVal(lim);
  5378 	_readLimit = __signedLongIntVal(lim);
  5366         if (_pos > _readLimit) {
  5379 	if (_pos > _readLimit) {
  5367             RETURN (true);
  5380 	    RETURN (true);
  5368         }
  5381 	}
  5369     }
  5382     }
  5370 
  5383 
  5371     __INST(lastErrorNumber) = nil;
  5384     __INST(lastErrorNumber) = nil;
  5372 
  5385 
  5373     if ((__INST(handleType) == nil)
  5386     if ((__INST(handleType) == nil)
  5374      || (__INST(handleType) == @symbol(filePointer))
  5387      || (__INST(handleType) == @symbol(filePointer))
  5375      || (__INST(handleType) == @symbol(socketFilePointer))
  5388      || (__INST(handleType) == @symbol(socketFilePointer))
  5376      || (__INST(handleType) == @symbol(socketHandle))
  5389      || (__INST(handleType) == @symbol(socketHandle))
  5377      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5390      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  5378         if ((fp = __INST(handle)) != nil) {
  5391 	if ((fp = __INST(handle)) != nil) {
  5379             f = __FILEVal(fp);
  5392 	    f = __FILEVal(fp);
  5380             if (_buffered = (__INST(buffered) == true)) {
  5393 	    if (_buffered = (__INST(buffered) == true)) {
  5381                 __READING__(f);
  5394 		__READING__(f);
  5382             } else {
  5395 	    } else {
  5383                 if (__INST(readAhead) != nil) {
  5396 		if (__INST(readAhead) != nil) {
  5384                     RETURN (false);
  5397 		    RETURN (false);
  5385                 }
  5398 		}
  5386             }
  5399 	    }
  5387 
  5400 
  5388             /*
  5401 	    /*
  5389              * read ahead ...
  5402 	     * read ahead ...
  5390              */
  5403 	     */
  5391             do {
  5404 	    do {
  5392 #ifdef WIN32
  5405 #ifdef WIN32
  5393 # if 1
  5406 # if 1
  5394                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5407 		__READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5395 
  5408 
  5396 # else
  5409 # else
  5397                 __BEGIN_INTERRUPTABLE__
  5410 		__BEGIN_INTERRUPTABLE__
  5398                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5411 		__READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5399                 __END_INTERRUPTABLE__
  5412 		__END_INTERRUPTABLE__
  5400 # endif
  5413 # endif
  5401 #else /* not WIN32 */
  5414 #else /* not WIN32 */
  5402                 __BEGIN_INTERRUPTABLE__
  5415 		__BEGIN_INTERRUPTABLE__
  5403                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5416 		__READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5404                 __END_INTERRUPTABLE__
  5417 		__END_INTERRUPTABLE__
  5405 #endif
  5418 #endif
  5406             } while ((ret < 0) && (__threadErrno == EINTR));
  5419 	    } while ((ret < 0) && (__threadErrno == EINTR));
  5407 
  5420 
  5408             if (ret > 0) {
  5421 	    if (ret > 0) {
  5409                 __UNGETC__(c&0xff, f, _buffered);
  5422 		__UNGETC__(c&0xff, f, _buffered);
  5410                 RETURN (false);
  5423 		RETURN (false);
  5411             }
  5424 	    }
  5412             if (ret == 0) {
  5425 	    if (ret == 0) {
  5413                 __INST(hitEOF) = true;
  5426 		__INST(hitEOF) = true;
  5414                 RETURN (true);
  5427 		RETURN (true);
  5415             }
  5428 	    }
  5416 
  5429 
  5417             /* ret < 0 */
  5430 	    /* ret < 0 */
  5418             __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  5431 	    __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  5419         }
  5432 	}
  5420     }
  5433     }
  5421 %}.
  5434 %}.
  5422     lastErrorNumber notNil ifTrue:[^ self readError].
  5435     lastErrorNumber notNil ifTrue:[^ self readError].
  5423     handle isNil ifTrue:[^ self errorNotOpen].
  5436     handle isNil ifTrue:[^ self errorNotOpen].
  5424     mode == #writeonly ifTrue:[^ self errorWriteOnly].
  5437     mode == #writeonly ifTrue:[^ self errorWriteOnly].
  5425     readAhead notNil ifTrue:[^ false].
  5438     readAhead notNil ifTrue:[^ false].
  5426 
  5439 
  5427     "/ migration support
  5440     "/ migration support
  5428     ^ self
  5441     ^ self
  5429         atEndFile:handle
  5442 	atEndFile:handle
  5430 
  5443 
  5431     "Modified: / 30.10.1998 / 20:16:06 / cg"
  5444     "Modified: / 30.10.1998 / 20:16:06 / cg"
  5432 !
  5445 !
  5433 
  5446 
  5434 canReadWithoutBlocking
  5447 canReadWithoutBlocking
  6093 ! !
  6106 ! !
  6094 
  6107 
  6095 !ExternalStream class methodsFor:'documentation'!
  6108 !ExternalStream class methodsFor:'documentation'!
  6096 
  6109 
  6097 version
  6110 version
  6098     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.397 2014-11-18 20:17:17 cg Exp $'
  6111     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.398 2014-11-24 14:37:58 cg Exp $'
  6099 !
  6112 !
  6100 
  6113 
  6101 version_CVS
  6114 version_CVS
  6102     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.397 2014-11-18 20:17:17 cg Exp $'
  6115     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.398 2014-11-24 14:37:58 cg Exp $'
  6103 ! !
  6116 ! !
  6104 
  6117 
  6105 
  6118 
  6106 ExternalStream initialize!
  6119 ExternalStream initialize!