ExternalStream.st
changeset 15342 d89884677c76
parent 15304 e61c83d98e52
child 15361 ff526d39bb07
equal deleted inserted replaced
15341:4503c19ab8f9 15342:d89884677c76
   197 #ifdef DEBUGGING
   197 #ifdef DEBUGGING
   198   extern char *__survStartPtr, *__survEndPtr;
   198   extern char *__survStartPtr, *__survEndPtr;
   199 # define DEBUGBUFFER(buf)  \
   199 # define DEBUGBUFFER(buf)  \
   200     if (((char *)(buf) >= __survStartPtr) \
   200     if (((char *)(buf) >= __survStartPtr) \
   201      && ((char *)(buf) < __survEndPtr)) { \
   201      && ((char *)(buf) < __survEndPtr)) { \
   202 	__fatal0("read into survivor\n"); \
   202         __fatal0("read into survivor\n"); \
   203     }
   203     }
   204 
   204 
   205 #else
   205 #else
   206 # define DEBUGBUFFER(buf) /* nothing */
   206 # define DEBUGBUFFER(buf) /* nothing */
   207 #endif
   207 #endif
   224    int _rtl_read();
   224    int _rtl_read();
   225    int _rtl_write();
   225    int _rtl_write();
   226 
   226 
   227 #  define READ(ret,f, cp, n, handleType) \
   227 #  define READ(ret,f, cp, n, handleType) \
   228       { int __res;\
   228       { int __res;\
   229 	HANDLE h; \
   229         HANDLE h; \
   230 	h = _get_osfhandle(fileno(f)); \
   230         h = _get_osfhandle(fileno(f)); \
   231 	if ((handleType == @symbol(socketFilePointer)) \
   231         if ((handleType == @symbol(socketFilePointer)) \
   232 	|| ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   232         || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   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 	  (ret) = __STX_C_NOINT_CALL3("_rtl_read", _rtl_read, fileno(f), (cp), (n));\
   235           (ret) = __STX_C_NOINT_CALL3("_rtl_read", _rtl_read, fileno(f), (cp), (n));\
   236 	} \
   236         } \
   237       }
   237       }
   238 
   238 
   239 #  define WRITE(ret,f, cp, n, handleType) \
   239 #  define WRITE(ret,f, cp, n, handleType) \
   240       { int __res;\
   240       { int __res;\
   241 	HANDLE h; \
   241         HANDLE h; \
   242 	h = _get_osfhandle(fileno(f)); \
   242         h = _get_osfhandle(fileno(f)); \
   243 	if ((handleType == @symbol(socketFilePointer)) \
   243         if ((handleType == @symbol(socketFilePointer)) \
   244 	|| ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   244         || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   245 	  (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   245           (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   246 	} else { \
   246         } else { \
   247 	  (ret) = __STX_C_NOINT_CALL3("_rtl_write", _rtl_write, fileno(f), (cp), (n));\
   247           (ret) = __STX_C_NOINT_CALL3("_rtl_write", _rtl_write, fileno(f), (cp), (n));\
   248 	} \
   248         } \
   249       }
   249       }
   250 
   250 
   251 # else /* MSC */
   251 # else /* MSC */
   252 
   252 
   253 #  define READ(ret,f, cp, n, handleType) \
   253 #  define READ(ret,f, cp, n, handleType) \
   254       { int __res;\
   254       { int __res;\
   255 	int fd; \
   255         int fd; \
   256 	HANDLE h; \
   256         HANDLE h; \
   257 	fd = fileno(f); \
   257         fd = fileno(f); \
   258 	if ((handleType == @symbol(socketFileDescriptor)) \
   258         if ((handleType == @symbol(socketFileDescriptor)) \
   259 	 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \
   259          || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \
   260 	  (ret) = __STX_WSA_NOINT_CALL4("recv", recv, fd, (cp), (n), 0);\
   260           (ret) = __STX_WSA_NOINT_CALL4("recv", recv, fd, (cp), (n), 0);\
   261 	} else { \
   261         } else { \
   262 	  h = _get_osfhandle(fd); \
   262           h = _get_osfhandle(fd); \
   263 	  if ((handleType == @symbol(socketFilePointer)) \
   263           if ((handleType == @symbol(socketFilePointer)) \
   264 	  || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   264           || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   265 	    (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   265             (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   266 	  } else { \
   266           } else { \
   267 	    (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   267             (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   268 	    if (ret) \
   268             if (ret) \
   269 	      ret = __res; \
   269               ret = __res; \
   270 	  } \
   270           } \
   271 	} \
   271         } \
   272       }
   272       }
   273 #  define WRITE(ret,f, cp, n, handleType) \
   273 #  define WRITE(ret,f, cp, n, handleType) \
   274       { int __res;\
   274       { int __res;\
   275 	int fd; \
   275         int fd; \
   276 	HANDLE h; \
   276         HANDLE h; \
   277 	fd = fileno(f); \
   277         fd = fileno(f); \
   278 	if ((handleType == @symbol(socketFileDescriptor)) \
   278         if ((handleType == @symbol(socketFileDescriptor)) \
   279 	 || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \
   279          || ((handleType == nil) && (ioctlsocket((SOCKET)fd,FIONREAD,&__res)==0))) { \
   280 	  (ret) = __STX_WSA_NOINT_CALL4("send", send, fd, (cp), (n), 0);\
   280           (ret) = __STX_WSA_NOINT_CALL4("send", send, fd, (cp), (n), 0);\
   281 	} else {\
   281         } else {\
   282 	  h = _get_osfhandle(fd); \
   282           h = _get_osfhandle(fd); \
   283 	  if ((handleType == @symbol(socketFilePointer)) \
   283           if ((handleType == @symbol(socketFilePointer)) \
   284 	  || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   284           || ((handleType == nil) && (ioctlsocket((SOCKET)h,FIONREAD,&__res)==0))) { \
   285 	    (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   285             (ret) = __STX_WSA_NOINT_CALL4("send", send, h, (cp), (n), 0);\
   286 	  } else {\
   286           } else {\
   287 	    (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\
   287             (ret) = __STX_API_NOINT_CALL5("WriteFile", WriteFile, h, (cp), (n), &__res, 0);\
   288 	    if (ret) \
   288             if (ret) \
   289 	      ret = __res; \
   289               ret = __res; \
   290 	  } \
   290           } \
   291 	} \
   291         } \
   292       }
   292       }
   293 # endif /* MSC */
   293 # endif /* MSC */
   294 
   294 
   295 # define FFLUSH(fp)             fflush(fp)
   295 # define FFLUSH(fp)             fflush(fp)
   296 # undef STDIO_NEEDS_FSEEK
   296 # undef STDIO_NEEDS_FSEEK
   298 # define FILENO(f)              fileno(f)
   298 # define FILENO(f)              fileno(f)
   299 
   299 
   300 # define __READING__(f)                          \
   300 # define __READING__(f)                          \
   301     if ((__INST(didWrite) != false)              \
   301     if ((__INST(didWrite) != false)              \
   302      && (__INST(mode) == @symbol(readwrite))) {  \
   302      && (__INST(mode) == @symbol(readwrite))) {  \
   303 	__INST(didWrite) = false;                \
   303         __INST(didWrite) = false;                \
   304 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   304         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   305     }
   305     }
   306 
   306 
   307 # define __WRITING__(f)                          \
   307 # define __WRITING__(f)                          \
   308     if ((__INST(didWrite) != true)               \
   308     if ((__INST(didWrite) != true)               \
   309      && (__INST(mode) == @symbol(readwrite))) {  \
   309      && (__INST(mode) == @symbol(readwrite))) {  \
   310 	__INST(didWrite) = true;                 \
   310         __INST(didWrite) = true;                 \
   311 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   311         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   312     }
   312     }
   313 
   313 
   314 # define __UNGETC__(c, f, isBuffered)                   \
   314 # define __UNGETC__(c, f, isBuffered)                   \
   315     if (isBuffered) {                                   \
   315     if (isBuffered) {                                   \
   316 	ungetc((c), (f));                               \
   316         ungetc((c), (f));                               \
   317     } else {                                            \
   317     } else {                                            \
   318       __INST(readAhead) = __mkSmallInteger((c));            \
   318       __INST(readAhead) = __mkSmallInteger((c));            \
   319     }
   319     }
   320 
   320 
   321 # define __READBYTE__(ret, f, buf, isBuffered, handleType)          \
   321 # define __READBYTE__(ret, f, buf, isBuffered, handleType)          \
   322     if (isBuffered) {                                   \
   322     if (isBuffered) {                                   \
   323 	for (;;) {                                      \
   323         for (;;) {                                      \
   324 	    CLEAR_ERRNO;                                \
   324             CLEAR_ERRNO;                                \
   325 	    (ret) = getc(f);                            \
   325             (ret) = getc(f);                            \
   326 	    if ((ret) >= 0) {                           \
   326             if ((ret) >= 0) {                           \
   327 		*(buf) = (ret);                         \
   327                 *(buf) = (ret);                         \
   328 		(ret) = 1;                              \
   328                 (ret) = 1;                              \
   329 	    } else if (ferror(f)) {                     \
   329             } else 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     } else {                                            \
   339     } else {                                            \
   340 	OBJ rA = __INST(readAhead);                     \
   340         OBJ rA = __INST(readAhead);                     \
   341 	if (rA != nil) {                                \
   341         if (rA != nil) {                                \
   342 	    *(buf) = (char)__intVal(rA);                \
   342             *(buf) = (char)__intVal(rA);                \
   343 	    __INST(readAhead) = nil;                    \
   343             __INST(readAhead) = nil;                    \
   344 	    (ret) = 1;                                  \
   344             (ret) = 1;                                  \
   345 	} else {                                        \
   345         } else {                                        \
   346 	    for (;;) {                                  \
   346             for (;;) {                                  \
   347 		CLEAR_ERRNO;                            \
   347                 CLEAR_ERRNO;                            \
   348 		READ(ret,f, buf, 1, handleType);                    \
   348                 READ(ret,f, buf, 1, handleType);                    \
   349 		if ((ret) >= 0 || __threadErrno != EINTR)       \
   349                 if ((ret) >= 0 || __threadErrno != EINTR)       \
   350 		    break;                              \
   350                     break;                              \
   351 	    }                                           \
   351             }                                           \
   352 	}                                               \
   352         }                                               \
   353     }
   353     }
   354 
   354 
   355   /*
   355   /*
   356    * read_bytes into a c-buffer
   356    * read_bytes into a c-buffer
   357    * (which may NOT move)
   357    * (which may NOT move)
   358    */
   358    */
   359 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
   359 # define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
   360     (ret) = 0;                                          \
   360     (ret) = 0;                                          \
   361     if (isBuffered) {                                   \
   361     if (isBuffered) {                                   \
   362 	int __offs = 0;                                 \
   362         int __offs = 0;                                 \
   363 	while (__offs < (cnt)) {                        \
   363         while (__offs < (cnt)) {                        \
   364 	    CLEAR_ERRNO;                                \
   364             CLEAR_ERRNO;                                \
   365 	    (ret) = getc(f);                            \
   365             (ret) = getc(f);                            \
   366 	    if ((ret) < 0) {                            \
   366             if ((ret) < 0) {                            \
   367 		if (ferror(f)) {                        \
   367                 if (ferror(f)) {                        \
   368 		    if (__threadErrno == EINTR) {               \
   368                     if (__threadErrno == EINTR) {               \
   369 			clearerr(f);                    \
   369                         clearerr(f);                    \
   370 			continue;                       \
   370                         continue;                       \
   371 		    }                                   \
   371                     }                                   \
   372 		} else {                                \
   372                 } else {                                \
   373 		    (ret) = 0;                          \
   373                     (ret) = 0;                          \
   374 		}                                       \
   374                 }                                       \
   375 		break;                                  \
   375                 break;                                  \
   376 	    }                                           \
   376             }                                           \
   377 	    (buf)[__offs++] = (ret);                    \
   377             (buf)[__offs++] = (ret);                    \
   378 	}                                               \
   378         }                                               \
   379 	if (__offs > 0)                                 \
   379         if (__offs > 0)                                 \
   380 	    (ret) = __offs;                             \
   380             (ret) = __offs;                             \
   381     } else {                                            \
   381     } else {                                            \
   382 	int __offs = 0;                                 \
   382         int __offs = 0;                                 \
   383 							\
   383                                                         \
   384 	while (__offs < (cnt)) {                        \
   384         while (__offs < (cnt)) {                        \
   385 	    OBJ rA = __INST(readAhead);                 \
   385             OBJ rA = __INST(readAhead);                 \
   386 	    if (rA != nil) {                            \
   386             if (rA != nil) {                            \
   387 		(buf)[__offs] = __intVal(rA);           \
   387                 (buf)[__offs] = __intVal(rA);           \
   388 		__INST(readAhead) = nil;                \
   388                 __INST(readAhead) = nil;                \
   389 		(ret) = 1;                              \
   389                 (ret) = 1;                              \
   390 	    } else {                                    \
   390             } else {                                    \
   391 		CLEAR_ERRNO;                            \
   391                 CLEAR_ERRNO;                            \
   392 		READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \
   392                 READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \
   393 		if ((ret) <= 0) {                       \
   393                 if ((ret) <= 0) {                       \
   394 		    if ((ret) < 0 && __threadErrno == EINTR) {  \
   394                     if ((ret) < 0 && __threadErrno == EINTR) {  \
   395 			continue;                       \
   395                         continue;                       \
   396 		    }                                   \
   396                     }                                   \
   397 		    break;                              \
   397                     break;                              \
   398 		}                                       \
   398                 }                                       \
   399 	    }                                           \
   399             }                                           \
   400 	    __offs += (ret);                            \
   400             __offs += (ret);                            \
   401 	}                                               \
   401         }                                               \
   402 	if (__offs > 0)                                 \
   402         if (__offs > 0)                                 \
   403 	    (ret) = __offs;                             \
   403             (ret) = __offs;                             \
   404    }
   404    }
   405 
   405 
   406 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   406 # define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   407   {                                                     \
   407   {                                                     \
   408     int __offs = 0;                                     \
   408     int __offs = 0;                                     \
   409     int oldFlags;                                       \
   409     int oldFlags;                                       \
   410 							\
   410                                                         \
   411     (ret) = 0;                                          \
   411     (ret) = 0;                                          \
   412     if (isBuffered) {                                   \
   412     if (isBuffered) {                                   \
   413 	while (__offs < (cnt)) {                        \
   413         while (__offs < (cnt)) {                        \
   414 	    CLEAR_ERRNO;                                \
   414             CLEAR_ERRNO;                                \
   415 	    (ret) = getc(f);                            \
   415             (ret) = getc(f);                            \
   416 	    if ((ret) < 0) {                            \
   416             if ((ret) < 0) {                            \
   417 		if (ferror(f)) {                        \
   417                 if (ferror(f)) {                        \
   418 		    if (__threadErrno == EINTR) {               \
   418                     if (__threadErrno == EINTR) {               \
   419 			clearerr(f);                    \
   419                         clearerr(f);                    \
   420 			continue;                       \
   420                         continue;                       \
   421 		    }                                   \
   421                     }                                   \
   422 		} else {                                \
   422                 } else {                                \
   423 		    (ret) = 0;                          \
   423                     (ret) = 0;                          \
   424 		}                                       \
   424                 }                                       \
   425 		break;                                  \
   425                 break;                                  \
   426 	    }                                           \
   426             }                                           \
   427 	    (buf)[__offs++] = (ret);                    \
   427             (buf)[__offs++] = (ret);                    \
   428 	}                                               \
   428         }                                               \
   429 	if (__offs > 0)                                 \
   429         if (__offs > 0)                                 \
   430 	    (ret) = __offs;                             \
   430             (ret) = __offs;                             \
   431     } else {                                            \
   431     } else {                                            \
   432 	while (__offs < (cnt)) {                        \
   432         while (__offs < (cnt)) {                        \
   433 	    OBJ rA = __INST(readAhead);                 \
   433             OBJ rA = __INST(readAhead);                 \
   434 	    if (rA != nil) {                            \
   434             if (rA != nil) {                            \
   435 		(buf)[__offs] = __intVal(rA);           \
   435                 (buf)[__offs] = __intVal(rA);           \
   436 		__INST(readAhead) = nil;                \
   436                 __INST(readAhead) = nil;                \
   437 		(ret) = 1;                              \
   437                 (ret) = 1;                              \
   438 		__offs += (ret);                        \
   438                 __offs += (ret);                        \
   439 		continue;                               \
   439                 continue;                               \
   440 	    }                                           \
   440             }                                           \
   441 	    CLEAR_ERRNO;                                \
   441             CLEAR_ERRNO;                                \
   442 	    {                                           \
   442             {                                           \
   443 	      int res;                                  \
   443               int res;                                  \
   444 	      if ((handleType == @symbol(socketFilePointer)) \
   444               if ((handleType == @symbol(socketFilePointer)) \
   445 	       || ((handleType == nil) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0))) { \
   445                || ((handleType == nil) && (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0))) { \
   446 		  if (res > 0) {                        \
   446                   if (res > 0) {                        \
   447 		      if (res > ((cnt)-__offs))         \
   447                       if (res > ((cnt)-__offs))         \
   448 			res = (cnt)-__offs;             \
   448                         res = (cnt)-__offs;             \
   449 		      READ(ret,f, (buf)+__offs, res, handleType);   \
   449                       READ(ret,f, (buf)+__offs, res, handleType);   \
   450 		  } else {                              \
   450                   } else {                              \
   451 		      (ret) = 0;                        \
   451                       (ret) = 0;                        \
   452 		  }                                     \
   452                   }                                     \
   453 	      } else if ((handleType == @symbol(pipeFilePointer)) \
   453               } else if ((handleType == @symbol(pipeFilePointer)) \
   454 			 || ((handleType == nil) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)))) { \
   454                          || ((handleType == nil) && (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)))) { \
   455 		  if (res > 0) {                        \
   455                   if (res > 0) {                        \
   456 		      if (res > ((cnt)-__offs))         \
   456                       if (res > ((cnt)-__offs))         \
   457 			res = (cnt)-__offs;             \
   457                         res = (cnt)-__offs;             \
   458 		      READ(ret,f, (buf)+__offs, res, handleType);   \
   458                       READ(ret,f, (buf)+__offs, res, handleType);   \
   459 		  } else                                \
   459                   } else                                \
   460 		      ret = 0;                          \
   460                       ret = 0;                          \
   461 	      } else {                                  \
   461               } else {                                  \
   462 		  READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \
   462                   READ(ret,f, (buf)+__offs, (cnt)-__offs, handleType); \
   463 	      }                                         \
   463               }                                         \
   464 	    }                                           \
   464             }                                           \
   465 	    if ((ret) < 0) {                            \
   465             if ((ret) < 0) {                            \
   466 		if (__threadErrno == EINTR) {                   \
   466                 if (__threadErrno == EINTR) {                   \
   467 		    continue;                           \
   467                     continue;                           \
   468 		}                                       \
   468                 }                                       \
   469 		break;                                  \
   469                 break;                                  \
   470 	    }                                           \
   470             }                                           \
   471 	    __offs += (ret);                            \
   471             __offs += (ret);                            \
   472 	    break;                                      \
   472             break;                                      \
   473 	}                                               \
   473         }                                               \
   474 	if (__offs > 0)                                 \
   474         if (__offs > 0)                                 \
   475 	    (ret) = __offs;                             \
   475             (ret) = __offs;                             \
   476     }                                                   \
   476     }                                                   \
   477   }
   477   }
   478 
   478 
   479 # define IO_BUFFER_SIZE        (8*1024)
   479 # define IO_BUFFER_SIZE        (8*1024)
   480 
   480 
   481 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   481 # define __READBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   482   {                                                     \
   482   {                                                     \
   483     int __ooffs = obj_offs;                             \
   483     int __ooffs = obj_offs;                             \
   484     int __offs = 0;                                     \
   484     int __offs = 0;                                     \
   485     char *buf = (char *)(obj);                          \
   485     char *buf = (char *)(obj);                          \
   486 							\
   486                                                         \
   487     (ret) = 0;                                          \
   487     (ret) = 0;                                          \
   488     if (isBuffered) {                                   \
   488     if (isBuffered) {                                   \
   489 	while (__offs < (cnt)) {                        \
   489         while (__offs < (cnt)) {                        \
   490 	    CLEAR_ERRNO;                                \
   490             CLEAR_ERRNO;                                \
   491 	    (ret) = getc(f);                            \
   491             (ret) = getc(f);                            \
   492 	    if ((ret) < 0) {                            \
   492             if ((ret) < 0) {                            \
   493 		if (ferror(f)) {                        \
   493                 if (ferror(f)) {                        \
   494 		    if (__threadErrno == EINTR) {       \
   494                     if (__threadErrno == EINTR) {       \
   495 			clearerr(f);                    \
   495                         clearerr(f);                    \
   496 			/* refetch */                   \
   496                         /* refetch */                   \
   497 			buf = (char *)(obj);   \
   497                         buf = (char *)(obj);   \
   498 			continue;                       \
   498                         continue;                       \
   499 		    }                                   \
   499                     }                                   \
   500 		} else {                                \
   500                 } else {                                \
   501 		    (ret) = 0;                          \
   501                     (ret) = 0;                          \
   502 		}                                       \
   502                 }                                       \
   503 		break;                                  \
   503                 break;                                  \
   504 	    }                                           \
   504             }                                           \
   505 	    (buf)[__ooffs+__offs] = (ret);              \
   505             (buf)[__ooffs+__offs] = (ret);              \
   506 	    __offs++;                                   \
   506             __offs++;                                   \
   507 	}                                               \
   507         }                                               \
   508 	if (__offs > 0)                                 \
   508         if (__offs > 0)                                 \
   509 	    (ret) = __offs;                             \
   509             (ret) = __offs;                             \
   510     } else {                                            \
   510     } else {                                            \
   511 	while (__offs < (cnt)) {                        \
   511         while (__offs < (cnt)) {                        \
   512 	    char __buf[IO_BUFFER_SIZE];                 \
   512             char __buf[IO_BUFFER_SIZE];                 \
   513 	    OBJ rA = __INST(readAhead);                 \
   513             OBJ rA = __INST(readAhead);                 \
   514 	    if (rA != nil) {                            \
   514             if (rA != nil) {                            \
   515 		(buf)[__ooffs+__offs] = __intVal(rA);   \
   515                 (buf)[__ooffs+__offs] = __intVal(rA);   \
   516 		__INST(readAhead) = nil;                \
   516                 __INST(readAhead) = nil;                \
   517 		(ret) = 1;                              \
   517                 (ret) = 1;                              \
   518 	    } else {                                    \
   518             } else {                                    \
   519 		int l;                                  \
   519                 int l;                                  \
   520 		CLEAR_ERRNO;                            \
   520                 CLEAR_ERRNO;                            \
   521 		l = (cnt)-__offs;                       \
   521                 l = (cnt)-__offs;                       \
   522 		if ( l > IO_BUFFER_SIZE)                \
   522                 if ( l > IO_BUFFER_SIZE)                \
   523 		  l = IO_BUFFER_SIZE;                   \
   523                   l = IO_BUFFER_SIZE;                   \
   524 		READ(ret,f, __buf, l, handleType);                  \
   524                 READ(ret,f, __buf, l, handleType);                  \
   525 		if ((ret) <= 0) {                       \
   525                 if ((ret) <= 0) {                       \
   526 		    if ((ret) < 0 && __threadErrno == EINTR) {  \
   526                     if ((ret) < 0 && __threadErrno == EINTR) {  \
   527 			continue;                       \
   527                         continue;                       \
   528 		    }                                   \
   528                     }                                   \
   529 		    break;                              \
   529                     break;                              \
   530 		}                                       \
   530                 }                                       \
   531 	    }                                           \
   531             }                                           \
   532 	    if( (ret) > 0 ) {                               \
   532             if( (ret) > 0 ) {                               \
   533 		/* refetch */                               \
   533                 /* refetch */                               \
   534 		buf = (char *)(obj);               \
   534                 buf = (char *)(obj);               \
   535 		memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   535                 memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   536 		__offs += (ret);                            \
   536                 __offs += (ret);                            \
   537 	    } else {                                        \
   537             } else {                                        \
   538 		(ret) = 0;                                  \
   538                 (ret) = 0;                                  \
   539 	    }                                               \
   539             }                                               \
   540 	}                                               \
   540         }                                               \
   541 	if (__offs > 0)                                 \
   541         if (__offs > 0)                                 \
   542 	    (ret) = __offs;                             \
   542             (ret) = __offs;                             \
   543     }                                                   \
   543     }                                                   \
   544   }
   544   }
   545 
   545 
   546 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)\
   546 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)\
   547   {                                                  \
   547   {                                                  \
   548     int __ooffs = obj_offs;                          \
   548     int __ooffs = obj_offs;                          \
   549     int __offs = 0;                                  \
   549     int __offs = 0;                                  \
   550     char *buf = (char *)(obj);                       \
   550     char *buf = (char *)(obj);                       \
   551 						     \
   551                                                      \
   552     (ret) = 0;                                       \
   552     (ret) = 0;                                       \
   553     if (isBuffered) {                                \
   553     if (isBuffered) {                                \
   554 	while (__offs < (cnt)) {                     \
   554         while (__offs < (cnt)) {                     \
   555 	    CLEAR_ERRNO;                             \
   555             CLEAR_ERRNO;                             \
   556 	    (ret) = getc(f);                         \
   556             (ret) = getc(f);                         \
   557 	    if ((ret) < 0) {                         \
   557             if ((ret) < 0) {                         \
   558 		if (ferror(f)) {                     \
   558                 if (ferror(f)) {                     \
   559 		    if (__threadErrno == EINTR) {    \
   559                     if (__threadErrno == EINTR) {    \
   560 			clearerr(f);                 \
   560                         clearerr(f);                 \
   561 			/* refetch */                \
   561                         /* refetch */                \
   562 			buf = (char *)(obj);\
   562                         buf = (char *)(obj);\
   563 			continue;                    \
   563                         continue;                    \
   564 		    }                                \
   564                     }                                \
   565 		} else {                             \
   565                 } else {                             \
   566 		    (ret) = 0;                       \
   566                     (ret) = 0;                       \
   567 		}                                    \
   567                 }                                    \
   568 		break;                               \
   568                 break;                               \
   569 	    }                                        \
   569             }                                        \
   570 	    (buf)[__ooffs+__offs] = (ret);           \
   570             (buf)[__ooffs+__offs] = (ret);           \
   571 	    __offs++;                                \
   571             __offs++;                                \
   572 	}                                            \
   572         }                                            \
   573 	if (__offs > 0)                              \
   573         if (__offs > 0)                              \
   574 	    (ret) = __offs;                          \
   574             (ret) = __offs;                          \
   575     } else {                                         \
   575     } else {                                         \
   576 	while (__offs < (cnt)) {                     \
   576         while (__offs < (cnt)) {                     \
   577 	    char __buf[IO_BUFFER_SIZE];              \
   577             char __buf[IO_BUFFER_SIZE];              \
   578 	    OBJ rA = __INST(readAhead);              \
   578             OBJ rA = __INST(readAhead);              \
   579 	    if (rA != nil) {                         \
   579             if (rA != nil) {                         \
   580 		(buf)[__ooffs+__offs] = __intVal(rA);\
   580                 (buf)[__ooffs+__offs] = __intVal(rA);\
   581 		__INST(readAhead) = nil;             \
   581                 __INST(readAhead) = nil;             \
   582 		(ret) = 1;                           \
   582                 (ret) = 1;                           \
   583 		__offs += (ret);                     \
   583                 __offs += (ret);                     \
   584 		continue;                            \
   584                 continue;                            \
   585 	    }                                        \
   585             }                                        \
   586 	    {                                        \
   586             {                                        \
   587 		int l;                               \
   587                 int l;                               \
   588 		int res;                             \
   588                 int res;                             \
   589 		CLEAR_ERRNO;                         \
   589                 CLEAR_ERRNO;                         \
   590 		l = (cnt)-__offs;                    \
   590                 l = (cnt)-__offs;                    \
   591 		if ( l > IO_BUFFER_SIZE)             \
   591                 if ( l > IO_BUFFER_SIZE)             \
   592 		    l = IO_BUFFER_SIZE;              \
   592                     l = IO_BUFFER_SIZE;              \
   593 		if (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0) { \
   593                 if (ioctlsocket((SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res)==0) { \
   594 		    if (res > 0) {                   \
   594                     if (res > 0) {                   \
   595 			if (res > l)                 \
   595                         if (res > l)                 \
   596 			    res = l;                 \
   596                             res = l;                 \
   597 			READ(ret,f, __buf, res, handleType);     \
   597                         READ(ret,f, __buf, res, handleType);     \
   598 		    } else {                         \
   598                     } else {                         \
   599 			(ret) = 0;                   \
   599                         (ret) = 0;                   \
   600 		    }                                \
   600                     }                                \
   601 		} else if (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)) { \
   601                 } else if (PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)) { \
   602 		    if (res > 0) {                   \
   602                     if (res > 0) {                   \
   603 			if (res > l)                 \
   603                         if (res > l)                 \
   604 			    res = l;                 \
   604                             res = l;                 \
   605 			READ(ret,f, __buf, res, handleType);     \
   605                         READ(ret,f, __buf, res, handleType);     \
   606 		    } else                           \
   606                     } else                           \
   607 			(ret) = 0;                   \
   607                         (ret) = 0;                   \
   608 		} else {                             \
   608                 } else {                             \
   609 		    READ(ret,f, __buf, l, handleType);           \
   609                     READ(ret,f, __buf, l, handleType);           \
   610 		}                                    \
   610                 }                                    \
   611 		if ((ret) < 0 && __threadErrno == EINTR) {   \
   611                 if ((ret) < 0 && __threadErrno == EINTR) {   \
   612 		    continue;                        \
   612                     continue;                        \
   613 		}                                    \
   613                 }                                    \
   614 	    }                                        \
   614             }                                        \
   615 	    if( (ret) > 0 ) {                               \
   615             if( (ret) > 0 ) {                               \
   616 		/* refetch */                               \
   616                 /* refetch */                               \
   617 		buf = (char *)(obj);               \
   617                 buf = (char *)(obj);               \
   618 		memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   618                 memcpy((buf)+__ooffs+__offs,__buf,(ret));   \
   619 		__offs += (ret);                            \
   619                 __offs += (ret);                            \
   620 	    } else {                                        \
   620             } else {                                        \
   621 		(ret) = 0;                                  \
   621                 (ret) = 0;                                  \
   622 	    }                                               \
   622             }                                               \
   623 	    break;                                      \
   623             break;                                      \
   624 	}                                               \
   624         }                                               \
   625 	if (__offs > 0)                                 \
   625         if (__offs > 0)                                 \
   626 	    (ret) = __offs;                             \
   626             (ret) = __offs;                             \
   627     }                                                   \
   627     }                                                   \
   628   }
   628   }
   629 
   629 
   630 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)         \
   630 # define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)         \
   631     if (isBuffered) {                                   \
   631     if (isBuffered) {                                   \
   632 	for (;;) {                                      \
   632         for (;;) {                                      \
   633 	    CLEAR_ERRNO;                                \
   633             CLEAR_ERRNO;                                \
   634 	    ret = putc(*(buf), f);                      \
   634             ret = putc(*(buf), f);                      \
   635 	    if ((ret) >= 0) {                           \
   635             if ((ret) >= 0) {                           \
   636 		(ret) = 1;                              \
   636                 (ret) = 1;                              \
   637 	    } else if (ferror(f)) {                     \
   637             } else if (ferror(f)) {                     \
   638 		if (__threadErrno == EINTR) {                   \
   638                 if (__threadErrno == EINTR) {                   \
   639 		    clearerr(f);                        \
   639                     clearerr(f);                        \
   640 		    continue;                           \
   640                     continue;                           \
   641 		}                                       \
   641                 }                                       \
   642 	    } else                                      \
   642             } else                                      \
   643 		(ret) = 0;                              \
   643                 (ret) = 0;                              \
   644 	    break;                                      \
   644             break;                                      \
   645 	}                                               \
   645         }                                               \
   646     } else {                                            \
   646     } else {                                            \
   647 	for (;;) {                                      \
   647         for (;;) {                                      \
   648 	    CLEAR_ERRNO;                                \
   648             CLEAR_ERRNO;                                \
   649 	    WRITE(ret,f, buf, 1, handleType);                       \
   649             WRITE(ret,f, buf, 1, handleType);                       \
   650 	    if ((ret) >= 0 || __threadErrno != EINTR)           \
   650             if ((ret) >= 0 || __threadErrno != EINTR)           \
   651 		break;                                  \
   651                 break;                                  \
   652 	}                                               \
   652         }                                               \
   653    }
   653    }
   654 
   654 
   655 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   655 # define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   656     (ret) = 0;                                          \
   656     (ret) = 0;                                          \
   657     if (isBuffered) {                                   \
   657     if (isBuffered) {                                   \
   658 	int __offs = 0;                                 \
   658         int __offs = 0;                                 \
   659 	while (__offs < (cnt)) {                        \
   659         while (__offs < (cnt)) {                        \
   660 	    CLEAR_ERRNO;                                \
   660             CLEAR_ERRNO;                                \
   661 	    ret = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
   661             ret = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
   662 	    if ((ret) <= 0) {                           \
   662             if ((ret) <= 0) {                           \
   663 		if (ferror(f)) {                        \
   663                 if (ferror(f)) {                        \
   664 		    if (__threadErrno == EINTR) {               \
   664                     if (__threadErrno == EINTR) {               \
   665 			clearerr(f);                    \
   665                         clearerr(f);                    \
   666 			continue;                       \
   666                         continue;                       \
   667 		    }                                   \
   667                     }                                   \
   668 		    break;                              \
   668                     break;                              \
   669 		} else {                                \
   669                 } else {                                \
   670 		    (ret) = 0;                          \
   670                     (ret) = 0;                          \
   671 		}                                       \
   671                 }                                       \
   672 	    }                                           \
   672             }                                           \
   673 	    __offs += (ret);                            \
   673             __offs += (ret);                            \
   674 	}                                               \
   674         }                                               \
   675 	if (__offs > 0)                                 \
   675         if (__offs > 0)                                 \
   676 	    (ret) = __offs;                             \
   676             (ret) = __offs;                             \
   677     } else {                                            \
   677     } else {                                            \
   678 	int __offs = 0;                                 \
   678         int __offs = 0;                                 \
   679 	while (__offs < (cnt)) {                        \
   679         while (__offs < (cnt)) {                        \
   680 	    CLEAR_ERRNO;                                \
   680             CLEAR_ERRNO;                                \
   681 	    WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType);   \
   681             WRITE(ret,f, (buf)+__offs, (cnt)-__offs, handleType);   \
   682 	    if (ret <= 0) {                             \
   682             if (ret <= 0) {                             \
   683 		if (ret < 0 && __threadErrno == EINTR) {        \
   683                 if (ret < 0 && __threadErrno == EINTR) {        \
   684 		    continue;                           \
   684                     continue;                           \
   685 		}                                       \
   685                 }                                       \
   686 		break;                                  \
   686                 break;                                  \
   687 	    }                                           \
   687             }                                           \
   688 	    __offs += (ret);                            \
   688             __offs += (ret);                            \
   689 	}                                               \
   689         }                                               \
   690 	if (__offs > 0)                                 \
   690         if (__offs > 0)                                 \
   691 	    (ret) = __offs;                             \
   691             (ret) = __offs;                             \
   692    }
   692    }
   693 
   693 
   694 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   694 # define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType) \
   695   {                                                     \
   695   {                                                     \
   696     int __ooffs = obj_offs;                             \
   696     int __ooffs = obj_offs;                             \
   697     int __offs = 0;                                     \
   697     int __offs = 0;                                     \
   698     char *buf = (char *)(obj);                          \
   698     char *buf = (char *)(obj);                          \
   699 							\
   699                                                         \
   700     (ret) = 0;                                          \
   700     (ret) = 0;                                          \
   701     if (isBuffered) {                                   \
   701     if (isBuffered) {                                   \
   702 	while (__offs < (cnt)) {                        \
   702         while (__offs < (cnt)) {                        \
   703 	    CLEAR_ERRNO;                                \
   703             CLEAR_ERRNO;                                \
   704 	    ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \
   704             ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f); \
   705 	    if ((ret) <= 0) {                           \
   705             if ((ret) <= 0) {                           \
   706 		if (ferror(f)) {                        \
   706                 if (ferror(f)) {                        \
   707 		    if (__threadErrno == EINTR) {       \
   707                     if (__threadErrno == EINTR) {       \
   708 			/* refetch */                   \
   708                         /* refetch */                   \
   709 			buf = (char *)(obj);   \
   709                         buf = (char *)(obj);   \
   710 			clearerr(f);                    \
   710                         clearerr(f);                    \
   711 			continue;                       \
   711                         continue;                       \
   712 		    }                                   \
   712                     }                                   \
   713 		    break;                              \
   713                     break;                              \
   714 		} else {                                \
   714                 } else {                                \
   715 		    (ret) = 0;                          \
   715                     (ret) = 0;                          \
   716 		}                                       \
   716                 }                                       \
   717 	    }                                           \
   717             }                                           \
   718 	    __offs += (ret);                            \
   718             __offs += (ret);                            \
   719 	}                                               \
   719         }                                               \
   720 	if (__offs > 0)                                 \
   720         if (__offs > 0)                                 \
   721 	    (ret) = __offs;                             \
   721             (ret) = __offs;                             \
   722     } else {                                            \
   722     } else {                                            \
   723 	while (__offs < (cnt)) {                        \
   723         while (__offs < (cnt)) {                        \
   724 	    char __buf[IO_BUFFER_SIZE];                 \
   724             char __buf[IO_BUFFER_SIZE];                 \
   725 	    int l;                                      \
   725             int l;                                      \
   726 	    CLEAR_ERRNO;                                \
   726             CLEAR_ERRNO;                                \
   727 	    l = (cnt)-__offs;                           \
   727             l = (cnt)-__offs;                           \
   728 	    if ( l > IO_BUFFER_SIZE)                    \
   728             if ( l > IO_BUFFER_SIZE)                    \
   729 	      l = IO_BUFFER_SIZE;                       \
   729               l = IO_BUFFER_SIZE;                       \
   730 	    /* refetch */                               \
   730             /* refetch */                               \
   731 	    buf = (char *)(obj);               \
   731             buf = (char *)(obj);               \
   732 	    memcpy(__buf,(buf)+__ooffs+__offs,l);       \
   732             memcpy(__buf,(buf)+__ooffs+__offs,l);       \
   733 	    WRITE(ret,f, __buf, l, handleType);                     \
   733             WRITE(ret,f, __buf, l, handleType);                     \
   734 	    if (ret <= 0) {                             \
   734             if (ret <= 0) {                             \
   735 		if (ret < 0 && __threadErrno == EINTR) {        \
   735                 if (ret < 0 && __threadErrno == EINTR) {        \
   736 		    continue;                           \
   736                     continue;                           \
   737 		}                                       \
   737                 }                                       \
   738 		break;                                  \
   738                 break;                                  \
   739 	    }                                           \
   739             }                                           \
   740 	    __offs += (ret);                            \
   740             __offs += (ret);                            \
   741 	}                                               \
   741         }                                               \
   742 	if (__offs > 0)                                 \
   742         if (__offs > 0)                                 \
   743 	    (ret) = __offs;                             \
   743             (ret) = __offs;                             \
   744     }                                                   \
   744     }                                                   \
   745   }
   745   }
   746 
   746 
   747 #else /* no WIN32 */
   747 #else /* no WIN32 */
   748 
   748 
   749 # define __READING__(f)                          \
   749 # define __READING__(f)                          \
   750     if ((__INST(didWrite) != false)              \
   750     if ((__INST(didWrite) != false)              \
   751      && (__INST(mode) == @symbol(readwrite))) {  \
   751      && (__INST(mode) == @symbol(readwrite))) {  \
   752 	__INST(didWrite) = false;                \
   752         __INST(didWrite) = false;                \
   753 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   753         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   754     }
   754     }
   755 
   755 
   756 # define __WRITING__(f)                          \
   756 # define __WRITING__(f)                          \
   757     if ((__INST(didWrite) != true)               \
   757     if ((__INST(didWrite) != true)               \
   758      && (__INST(mode) == @symbol(readwrite))) {  \
   758      && (__INST(mode) == @symbol(readwrite))) {  \
   759 	__INST(didWrite) = true;                 \
   759         __INST(didWrite) = true;                 \
   760 	OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   760         OPT_FSEEK(f, 0L, SEEK_CUR); /* needed in stdio */  \
   761     }
   761     }
   762 
   762 
   763 
   763 
   764 # ifdef NO_STDIO
   764 # ifdef NO_STDIO
   765 #  define __UNGETC__(c, f, isBuffered)                  \
   765 #  define __UNGETC__(c, f, isBuffered)                  \
   766     __INST(readAhead) = __mkSmallInteger((c));
   766     __INST(readAhead) = __mkSmallInteger((c));
   767 # else /* use STDIO */
   767 # else /* use STDIO */
   768 #  define __UNGETC__(c, f, isBuffered)                  \
   768 #  define __UNGETC__(c, f, isBuffered)                  \
   769     if (isBuffered) {                                   \
   769     if (isBuffered) {                                   \
   770 	ungetc((c), (f));                               \
   770         ungetc((c), (f));                               \
   771     } else {                                            \
   771     } else {                                            \
   772 	__INST(readAhead) = __mkSmallInteger((c));          \
   772         __INST(readAhead) = __mkSmallInteger((c));          \
   773     }
   773     }
   774 # endif /* use STDIO */
   774 # endif /* use STDIO */
   775 
   775 
   776 # ifdef NO_STDIO
   776 # ifdef NO_STDIO
   777 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   777 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   778     {                                                   \
   778     {                                                   \
   779 	OBJ rA = __INST(readAhead);                     \
   779         OBJ rA = __INST(readAhead);                     \
   780 	if (rA != nil) {                                \
   780         if (rA != nil) {                                \
   781 	    *(buf) = __intVal(rA);                      \
   781             *(buf) = __intVal(rA);                      \
   782 	    DEBUGBUFFER(buf);                           \
   782             DEBUGBUFFER(buf);                           \
   783 	    __INST(readAhead) = nil;                    \
   783             __INST(readAhead) = nil;                    \
   784 	    (ret) = 1;                                  \
   784             (ret) = 1;                                  \
   785 	} else {                                        \
   785         } else {                                        \
   786 	    for (;;) {                                  \
   786             for (;;) {                                  \
   787 		CLEAR_ERRNO;                            \
   787                 CLEAR_ERRNO;                            \
   788 		(ret) = READ(f, buf, 1, handleType);                \
   788                 (ret) = READ(f, buf, 1, handleType);                \
   789 		DEBUGBUFFER(buf);                       \
   789                 DEBUGBUFFER(buf);                       \
   790 		if ((ret) >= 0 || __threadErrno != EINTR)       \
   790                 if ((ret) >= 0 || __threadErrno != EINTR)       \
   791 		    break;                              \
   791                     break;                              \
   792 		__HANDLE_INTERRUPTS__;                  \
   792                 __HANDLE_INTERRUPTS__;                  \
   793 	    }                                           \
   793             }                                           \
   794 	}                                               \
   794         }                                               \
   795     }
   795     }
   796 # else /* use STDIO */
   796 # else /* use STDIO */
   797 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   797 #  define __READBYTE__(ret, f, buf, isBuffered, handleType)         \
   798     if (isBuffered) {                                   \
   798     if (isBuffered) {                                   \
   799 	for (;;) {                                      \
   799         for (;;) {                                      \
   800 	    CLEAR_ERRNO;                                \
   800             CLEAR_ERRNO;                                \
   801 	    (ret) = getc(f);                            \
   801             (ret) = getc(f);                            \
   802 	    if ((ret) >= 0) {                           \
   802             if ((ret) >= 0) {                           \
   803 		DEBUGBUFFER(buf);                       \
   803                 DEBUGBUFFER(buf);                       \
   804 		*(buf) = (ret);                         \
   804                 *(buf) = (ret);                         \
   805 		(ret) = 1;                              \
   805                 (ret) = 1;                              \
   806 	    } else if (ferror(f)) {                     \
   806             } else if (ferror(f)) {                     \
   807 		if (__threadErrno == EINTR) {                   \
   807                 if (__threadErrno == EINTR) {                   \
   808 		    __HANDLE_INTERRUPTS__;              \
   808                     __HANDLE_INTERRUPTS__;              \
   809 		    clearerr(f);                        \
   809                     clearerr(f);                        \
   810 		    continue;                           \
   810                     continue;                           \
   811 		}                                       \
   811                 }                                       \
   812 	    } else                                      \
   812             } else                                      \
   813 		(ret) = 0;                              \
   813                 (ret) = 0;                              \
   814 	    break;                                      \
   814             break;                                      \
   815 	}                                               \
   815         }                                               \
   816     } else {                                            \
   816     } else {                                            \
   817 	OBJ rA = __INST(readAhead);                     \
   817         OBJ rA = __INST(readAhead);                     \
   818 	if (rA != nil) {                                \
   818         if (rA != nil) {                                \
   819 	    *(buf) = __intVal(rA);                      \
   819             *(buf) = __intVal(rA);                      \
   820 	    DEBUGBUFFER(buf);                           \
   820             DEBUGBUFFER(buf);                           \
   821 	    __INST(readAhead) = nil;                    \
   821             __INST(readAhead) = nil;                    \
   822 	    (ret) = 1;                                  \
   822             (ret) = 1;                                  \
   823 	} else {                                        \
   823         } else {                                        \
   824 	    for (;;) {                                  \
   824             for (;;) {                                  \
   825 		CLEAR_ERRNO;                            \
   825                 CLEAR_ERRNO;                            \
   826 		(ret) = read(fileno(f), buf, 1);        \
   826                 (ret) = read(fileno(f), buf, 1);        \
   827 		DEBUGBUFFER(buf);                       \
   827                 DEBUGBUFFER(buf);                       \
   828 		if ((ret) >= 0 || __threadErrno != EINTR)       \
   828                 if ((ret) >= 0 || __threadErrno != EINTR)       \
   829 		    break;                              \
   829                     break;                              \
   830 		__HANDLE_INTERRUPTS__;                  \
   830                 __HANDLE_INTERRUPTS__;                  \
   831 	    }                                           \
   831             }                                           \
   832 	}                                               \
   832         }                                               \
   833    }
   833    }
   834 # endif /* use STDIO */
   834 # endif /* use STDIO */
   835 
   835 
   836 /*
   836 /*
   837  * read_bytes into a c-buffer
   837  * read_bytes into a c-buffer
   838  * (which may NOT move)
   838  * (which may NOT move)
   839  */
   839  */
   840 # ifdef NO_STDIO
   840 # ifdef NO_STDIO
   841 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   841 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)   \
   842     {                                                   \
   842     {                                                   \
   843 	int __offs = 0, __cnt;                                 \
   843         int __offs = 0, __cnt;                                 \
   844 							\
   844                                                         \
   845 	while (__offs < (cnt)) {                        \
   845         while (__offs < (cnt)) {                        \
   846 	    OBJ rA = __INST(readAhead);                 \
   846             OBJ rA = __INST(readAhead);                 \
   847 	    if (rA != nil) {                            \
   847             if (rA != nil) {                            \
   848 		(buf)[__offs] = __intVal(rA);           \
   848                 (buf)[__offs] = __intVal(rA);           \
   849 		DEBUGBUFFER(buf);                       \
   849                 DEBUGBUFFER(buf);                       \
   850 		__INST(readAhead) = nil;                \
   850                 __INST(readAhead) = nil;                \
   851 		__offs++;                               \
   851                 __offs++;                               \
   852 	    } else {                                    \
   852             } else {                                    \
   853 		CLEAR_ERRNO;                            \
   853                 CLEAR_ERRNO;                            \
   854 		__cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \
   854                 __cnt = READ(f, (buf)+__offs, (cnt)-__offs, handleType); \
   855 		DEBUGBUFFER(buf);                       \
   855                 DEBUGBUFFER(buf);                       \
   856 		if (__cnt <= 0) {                       \
   856                 if (__cnt <= 0) {                       \
   857 		    if (__cnt < 0 && __threadErrno == EINTR) {  \
   857                     if (__cnt < 0 && __threadErrno == EINTR) {  \
   858 			__HANDLE_INTERRUPTS__;          \
   858                         __HANDLE_INTERRUPTS__;          \
   859 			continue;                       \
   859                         continue;                       \
   860 		    }                                   \
   860                     }                                   \
   861 		    break;                              \
   861                     break;                              \
   862 		}                                       \
   862                 }                                       \
   863 		__offs += __cnt;                        \
   863                 __offs += __cnt;                        \
   864 	    }                                           \
   864             }                                           \
   865 	}                                               \
   865         }                                               \
   866 	if (__offs > 0)                                 \
   866         if (__offs > 0)                                 \
   867 	    (ret) = __offs;                             \
   867             (ret) = __offs;                             \
   868    }
   868    }
   869 # else /* use STDIO */
   869 # else /* use STDIO */
   870 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)     \
   870 #  define __READBYTES__(ret, f, buf, cnt, isBuffered, handleType)     \
   871     (ret) = 0;                                          \
   871     (ret) = 0;                                          \
   872     if (isBuffered) {                                   \
   872     if (isBuffered) {                                   \
   873 	int __offs = 0;                                 \
   873         int __offs = 0;                                 \
   874 	while (__offs < (cnt)) {                        \
   874         while (__offs < (cnt)) {                        \
   875 	    CLEAR_ERRNO;                                \
   875             CLEAR_ERRNO;                                \
   876 	    (ret) = getc(f);                            \
   876             (ret) = getc(f);                            \
   877 	    if ((ret) < 0) {                            \
   877             if ((ret) < 0) {                            \
   878 		if (ferror(f)) {                        \
   878                 if (ferror(f)) {                        \
   879 		    if (__threadErrno == EINTR) {               \
   879                     if (__threadErrno == EINTR) {               \
   880 			__HANDLE_INTERRUPTS__;          \
   880                         __HANDLE_INTERRUPTS__;          \
   881 			clearerr(f);                    \
   881                         clearerr(f);                    \
   882 			continue;                       \
   882                         continue;                       \
   883 		    }                                   \
   883                     }                                   \
   884 		} else {                                \
   884                 } else {                                \
   885 		    (ret) = 0;                          \
   885                     (ret) = 0;                          \
   886 		}                                       \
   886                 }                                       \
   887 		break;                                  \
   887                 break;                                  \
   888 	    }                                           \
   888             }                                           \
   889 	    DEBUGBUFFER(buf);                           \
   889             DEBUGBUFFER(buf);                           \
   890 	    (buf)[__offs++] = (ret);                    \
   890             (buf)[__offs++] = (ret);                    \
   891 	}                                               \
   891         }                                               \
   892 	if (__offs > 0)                                 \
   892         if (__offs > 0)                                 \
   893 	    (ret) = __offs;                             \
   893             (ret) = __offs;                             \
   894     } else {                                            \
   894     } else {                                            \
   895 	int __offs = 0, __cnt;                                 \
   895         int __offs = 0, __cnt;                                 \
   896 	int fd = fileno(f);                             \
   896         int fd = fileno(f);                             \
   897 							\
   897                                                         \
   898 	while (__offs < (cnt)) {                        \
   898         while (__offs < (cnt)) {                        \
   899 	    OBJ rA = __INST(readAhead);                 \
   899             OBJ rA = __INST(readAhead);                 \
   900 	    if (rA != nil) {                            \
   900             if (rA != nil) {                            \
   901 		DEBUGBUFFER(buf);                       \
   901                 DEBUGBUFFER(buf);                       \
   902 		(buf)[__offs] = __intVal(rA);           \
   902                 (buf)[__offs] = __intVal(rA);           \
   903 		__INST(readAhead) = nil;                \
   903                 __INST(readAhead) = nil;                \
   904 		__offs++;                               \
   904                 __offs++;                               \
   905 	    } else {                                    \
   905             } else {                                    \
   906 		CLEAR_ERRNO;                            \
   906                 CLEAR_ERRNO;                            \
   907 		__cnt = read(fd, (buf)+__offs, (cnt)-__offs);                 \
   907                 __cnt = read(fd, (buf)+__offs, (cnt)-__offs);                 \
   908 		DEBUGBUFFER(buf);                       \
   908                 DEBUGBUFFER(buf);                       \
   909 		if (__cnt <= 0) {                       \
   909                 if (__cnt <= 0) {                       \
   910 		    if (__cnt < 0 && __threadErrno == EINTR) {  \
   910                     if (__cnt < 0 && __threadErrno == EINTR) {  \
   911 			__HANDLE_INTERRUPTS__;          \
   911                         __HANDLE_INTERRUPTS__;          \
   912 			continue;                       \
   912                         continue;                       \
   913 		    }                                   \
   913                     }                                   \
   914 		    break;                              \
   914                     break;                              \
   915 		}                                       \
   915                 }                                       \
   916 		__offs += __cnt;                        \
   916                 __offs += __cnt;                        \
   917 	    }                                           \
   917             }                                           \
   918 	}                                               \
   918         }                                               \
   919 	if (__offs > 0)                                 \
   919         if (__offs > 0)                                 \
   920 	    (ret) = __offs;                             \
   920             (ret) = __offs;                             \
   921    }
   921    }
   922 
   922 
   923 
   923 
   924 /*
   924 /*
   925  * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc...
   925  * FNDELAY and O_NDELAY is deprecated, O_NONBLOCK is used in POSIX, XPG, etc...
   926  */
   926  */
   927 
   927 
   928 #  if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY))
   928 #  if defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(O_NDELAY) || defined(FNDELAY))
   929 #   define GETFLAGS(fd) \
       
   930 	fcntl(fd, F_GETFL, 0);
       
   931 
       
   932 #   define SETFLAGS(fd, flags) \
   929 #   define SETFLAGS(fd, flags) \
   933 	fcntl(fd, F_SETFL, flags)
   930         fcntl(fd, F_SETFL, flags)
   934 
   931 
   935 #   if defined(O_NONBLOCK)
   932 #   if defined(O_NONBLOCK)
   936 #    define __STX_NONBLOCK_FLAG O_NONBLOCK
   933 #    define __STX_NONBLOCK_FLAG O_NONBLOCK
   937 #   else
   934 #   else
   938 #    if defined(O_NDELAY)
   935 #    if defined(O_NDELAY)
   940 #    else
   937 #    else
   941 #     define __STX_NONBLOCK_FLAG FNDELAY
   938 #     define __STX_NONBLOCK_FLAG FNDELAY
   942 #    endif
   939 #    endif
   943 #   endif
   940 #   endif
   944 
   941 
   945 #   define SETNONBLOCKING(fd) \
   942 #   define SETNONBLOCKING(fd, oldFlags) \
   946 	{ \
   943         { \
   947 	    int flags; \
   944             int flags = fcntl(fd, F_GETFL, 0); \
   948 	    flags = fcntl(fd, F_GETFL, 0); \
   945             if (flags >= 0) { \
   949 	    if (flags >= 0) { \
   946                 fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \
   950 		fcntl(fd, F_SETFL, flags | __STX_NONBLOCK_FLAG); \
   947             } \
   951 	    } \
   948             oldFlags = flags; \
   952 	}
   949         }
   953 #  else
   950 #  else
   954 #   define GETFLAGS(fd) 0
       
   955 #   define SETFLAGS(fd, flags) /* nothing */
   951 #   define SETFLAGS(fd, flags) /* nothing */
   956 #   define SETNONBLOCKING(fd) /* nothing */
   952 #   define SETNONBLOCKING(fd, oldFlags) /* nothing */
   957 #  endif
   953 #  endif
   958 
   954 
   959 #  define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   955 #  define __READAVAILBYTES__(ret, f, buf, cnt, isBuffered, handleType) \
   960   {                                                     \
   956   {                                                     \
   961     int __offs = 0, __cnt;                                     \
   957     int __offs = 0, __cnt;                              \
   962     int oldFlags;                                       \
   958     int oldFlags;                                       \
   963 							\
   959                                                         \
   964     (ret) = 0;                                          \
   960     (ret) = 0;                                          \
   965     oldFlags = GETFLAGS(fileno(f));                     \
   961     SETNONBLOCKING(fileno(f), oldFlags);                \
   966     SETNONBLOCKING(fileno(f));                          \
       
   967     if (isBuffered) {                                   \
   962     if (isBuffered) {                                   \
   968 	while (__offs < (cnt)) {                        \
   963         while (__offs < (cnt)) {                        \
   969 	    CLEAR_ERRNO;                                \
   964             CLEAR_ERRNO;                                \
   970 	    (ret) = getc(f);                            \
   965             (ret) = getc(f);                            \
   971 	    if ((ret) < 0) {                            \
   966             if ((ret) < 0) {                            \
   972 		if (ferror(f)) {                        \
   967                 if (ferror(f)) {                        \
   973 		    if (__threadErrno == EINTR) {               \
   968                     if (__threadErrno == EINTR) {       \
   974 			(ret) = 0;                      \
   969                         (ret) = 0;                      \
   975 			clearerr(f);                    \
   970                         clearerr(f);                    \
   976 			break;                          \
   971                         break;                          \
   977 		    }                                   \
   972                     }                                   \
   978 		} else {                                \
   973                 } else {                                \
   979 		    (ret) = 0;                          \
   974                     (ret) = 0;                          \
   980 		}                                       \
   975                 }                                       \
   981 		break;                                  \
   976                 break;                                  \
   982 	    }                                           \
   977             }                                           \
   983 	    (buf)[__offs++] = (ret);                    \
   978             (buf)[__offs++] = (ret);                    \
   984 	    DEBUGBUFFER(buf);                           \
   979             DEBUGBUFFER(buf);                           \
   985 	}                                               \
   980         }                                               \
   986 	if (__offs > 0)                                 \
   981         if (__offs > 0)                                 \
   987 	    (ret) = __offs;                             \
   982             (ret) = __offs;                             \
   988     } else {                                            \
   983     } else {                                            \
   989 	int fd = fileno(f);                             \
   984         int fd = fileno(f);                             \
   990 							\
   985                                                         \
   991 	while (__offs < (cnt)) {                        \
   986         while (__offs < (cnt)) {                        \
   992 	    OBJ rA = __INST(readAhead);                 \
   987             OBJ rA = __INST(readAhead);                 \
   993 	    if (rA != nil) {                            \
   988             if (rA != nil) {                            \
   994 		(buf)[__offs] = __intVal(rA);           \
   989                 (buf)[__offs] = __intVal(rA);           \
   995 		DEBUGBUFFER(buf);                       \
   990                 DEBUGBUFFER(buf);                       \
   996 		__INST(readAhead) = nil;                \
   991                 __INST(readAhead) = nil;                \
   997 		__offs++;                               \
   992                 __offs++;                               \
   998 		continue;                               \
   993                 continue;                               \
   999 	    }                                           \
   994             }                                           \
  1000 	    CLEAR_ERRNO;                                \
   995             CLEAR_ERRNO;                                \
  1001 	    __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \
   996             __cnt = read(fd, (buf)+__offs, (cnt)-__offs); \
  1002 	    DEBUGBUFFER(buf);                           \
   997             DEBUGBUFFER(buf);                           \
  1003 	    if (__cnt > 0) {                            \
   998             if (__cnt > 0) {                            \
  1004 		__offs += __cnt;                        \
   999                 __offs += __cnt;                        \
  1005 	    }                                           \
  1000             }                                           \
  1006 	    break;                                      \
  1001             break;                                      \
  1007 	}                                               \
  1002         }                                               \
  1008 	if (__offs > 0)                                 \
  1003         if (__offs > 0)                                 \
  1009 	    (ret) = __offs;                             \
  1004             (ret) = __offs;                             \
  1010     }                                                   \
  1005     }                                                   \
  1011     SETFLAGS(fileno(f), oldFlags);                      \
  1006     SETFLAGS(fileno(f), oldFlags);                      \
  1012   }
  1007   }
  1013 
  1008 
  1014 # endif /* use STDIO */
  1009 # endif /* use STDIO */
  1022   {                                                     \
  1017   {                                                     \
  1023     int __ooffs = obj_offs;                             \
  1018     int __ooffs = obj_offs;                             \
  1024     int __offs = 0;                                     \
  1019     int __offs = 0;                                     \
  1025     int __cnt;                                          \
  1020     int __cnt;                                          \
  1026     char *buf = (char *)(obj);                          \
  1021     char *buf = (char *)(obj);                          \
  1027 							\
  1022                                                         \
  1028     (ret) = 0;                                          \
  1023     (ret) = 0;                                          \
  1029     {                                                   \
  1024     {                                                   \
  1030 	while (__offs < (cnt)) {                        \
  1025         while (__offs < (cnt)) {                        \
  1031 	    OBJ rA = __INST(readAhead);                 \
  1026             OBJ rA = __INST(readAhead);                 \
  1032 	    if (rA != nil) {                            \
  1027             if (rA != nil) {                            \
  1033 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1028                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1034 		DEBUGBUFFER(buf);                       \
  1029                 DEBUGBUFFER(buf);                       \
  1035 		__INST(readAhead) = nil;                \
  1030                 __INST(readAhead) = nil;                \
  1036 		__offs++;                               \
  1031                 __offs++;                               \
  1037 	    } else {                                    \
  1032             } else {                                    \
  1038 		CLEAR_ERRNO;                            \
  1033                 CLEAR_ERRNO;                            \
  1039 		__cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1034                 __cnt = READ(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1040 		DEBUGBUFFER(buf);                       \
  1035                 DEBUGBUFFER(buf);                       \
  1041 		if (__cnt <= 0) {                       \
  1036                 if (__cnt <= 0) {                       \
  1042 		    if (__cnt < 0 && __threadErrno == EINTR) {  \
  1037                     if (__cnt < 0 && __threadErrno == EINTR) {  \
  1043 			__HANDLE_INTERRUPTS__;          \
  1038                         __HANDLE_INTERRUPTS__;          \
  1044 			/* refetch */                   \
  1039                         /* refetch */                   \
  1045 			buf = (char *)(obj);   \
  1040                         buf = (char *)(obj);   \
  1046 			continue;                       \
  1041                         continue;                       \
  1047 		    }                                   \
  1042                     }                                   \
  1048 		    break;                              \
  1043                     break;                              \
  1049 		}                                       \
  1044                 }                                       \
  1050 		__offs += __cnt;                        \
  1045                 __offs += __cnt;                        \
  1051 	    }                                           \
  1046             }                                           \
  1052 	}                                               \
  1047         }                                               \
  1053 	if (__offs > 0)                                 \
  1048         if (__offs > 0)                                 \
  1054 	    (ret) = __offs;                             \
  1049             (ret) = __offs;                             \
  1055     }                                                   \
  1050     }                                                   \
  1056   }
  1051   }
  1057 
  1052 
  1058 # else /* use STDIO */
  1053 # else /* use STDIO */
  1059 
  1054 
  1061   {                                                     \
  1056   {                                                     \
  1062     int __ooffs = obj_offs;                             \
  1057     int __ooffs = obj_offs;                             \
  1063     int __offs = 0;                                     \
  1058     int __offs = 0;                                     \
  1064     int __cnt;                                          \
  1059     int __cnt;                                          \
  1065     char *buf = (char *)(obj);                          \
  1060     char *buf = (char *)(obj);                          \
  1066 							\
  1061                                                         \
  1067     (ret) = 0;                                          \
  1062     (ret) = 0;                                          \
  1068     if (isBuffered) {                                   \
  1063     if (isBuffered) {                                   \
  1069 	while (__offs < (cnt)) {                        \
  1064         while (__offs < (cnt)) {                        \
  1070 	    CLEAR_ERRNO;                                \
  1065             CLEAR_ERRNO;                                \
  1071 	    (ret) = getc(f);                            \
  1066             (ret) = getc(f);                            \
  1072 	    if ((ret) < 0) {                            \
  1067             if ((ret) < 0) {                            \
  1073 		if (ferror(f)) {                        \
  1068                 if (ferror(f)) {                        \
  1074 		    if (__threadErrno == EINTR) {       \
  1069                     if (__threadErrno == EINTR) {       \
  1075 			__HANDLE_INTERRUPTS__;          \
  1070                         __HANDLE_INTERRUPTS__;          \
  1076 			clearerr(f);                    \
  1071                         clearerr(f);                    \
  1077 			/* refetch */                   \
  1072                         /* refetch */                   \
  1078 			buf = (char *)(obj);   \
  1073                         buf = (char *)(obj);   \
  1079 			DEBUGBUFFER(buf);               \
  1074                         DEBUGBUFFER(buf);               \
  1080 			continue;                       \
  1075                         continue;                       \
  1081 		    }                                   \
  1076                     }                                   \
  1082 		} else {                                \
  1077                 } else {                                \
  1083 		    (ret) = 0;                          \
  1078                     (ret) = 0;                          \
  1084 		}                                       \
  1079                 }                                       \
  1085 		break;                                  \
  1080                 break;                                  \
  1086 	    }                                           \
  1081             }                                           \
  1087 	    (buf)[__ooffs+__offs] = (ret);              \
  1082             (buf)[__ooffs+__offs] = (ret);              \
  1088 	    DEBUGBUFFER(buf);                           \
  1083             DEBUGBUFFER(buf);                           \
  1089 	    __offs++;                                   \
  1084             __offs++;                                   \
  1090 	}                                               \
  1085         }                                               \
  1091 	if (__offs > 0)                                 \
  1086         if (__offs > 0)                                 \
  1092 	    (ret) = __offs;                             \
  1087             (ret) = __offs;                             \
  1093     } else {                                            \
  1088     } else {                                            \
  1094 	int fd = fileno(f);                             \
  1089         int fd = fileno(f);                             \
  1095 							\
  1090                                                         \
  1096 	while (__offs < (cnt)) {                        \
  1091         while (__offs < (cnt)) {                        \
  1097 	    OBJ rA = __INST(readAhead);                 \
  1092             OBJ rA = __INST(readAhead);                 \
  1098 	    if (rA != nil) {                            \
  1093             if (rA != nil) {                            \
  1099 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1094                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1100 		DEBUGBUFFER(buf);                       \
  1095                 DEBUGBUFFER(buf);                       \
  1101 		__INST(readAhead) = nil;                \
  1096                 __INST(readAhead) = nil;                \
  1102 		__offs++;                               \
  1097                 __offs++;                               \
  1103 	    } else {                                    \
  1098             } else {                                    \
  1104 		CLEAR_ERRNO;                            \
  1099                 CLEAR_ERRNO;                            \
  1105 		__cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1100                 __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1106 		DEBUGBUFFER(buf);                       \
  1101                 DEBUGBUFFER(buf);                       \
  1107 		if (__cnt <= 0) {                       \
  1102                 if (__cnt <= 0) {                       \
  1108 		    if (__cnt < 0 && __threadErrno == EINTR) {  \
  1103                     if (__cnt < 0 && __threadErrno == EINTR) {  \
  1109 			__HANDLE_INTERRUPTS__;          \
  1104                         __HANDLE_INTERRUPTS__;          \
  1110 			/* refetch */                   \
  1105                         /* refetch */                   \
  1111 			buf = (char *)(obj);   \
  1106                         buf = (char *)(obj);   \
  1112 			continue;                       \
  1107                         continue;                       \
  1113 		    }                                   \
  1108                     }                                   \
  1114 		    break;                              \
  1109                     break;                              \
  1115 		}                                       \
  1110                 }                                       \
  1116 		__offs += __cnt;                        \
  1111                 __offs += __cnt;                        \
  1117 	    }                                           \
  1112             }                                           \
  1118 	}                                               \
  1113         }                                               \
  1119 	if (__offs > 0)                                 \
  1114         if (__offs > 0)                                 \
  1120 	    (ret) = __offs;                             \
  1115             (ret) = __offs;                             \
  1121     }                                                   \
  1116     }                                                   \
  1122   }
  1117   }
  1123 
  1118 
  1124 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)     \
  1119 # define __READAVAILBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)     \
  1125   {                                                     \
  1120   {                                                     \
  1126     int __ooffs = obj_offs;                             \
  1121     int __ooffs = obj_offs;                             \
  1127     int __offs = 0;                                     \
  1122     int __offs = 0;                                     \
  1128     int __cnt;                                          \
  1123     int __cnt;                                          \
  1129     char *buf = (char *)(obj);                          \
  1124     char *buf = (char *)(obj);                          \
  1130 							\
  1125     int oldFlags;                                       \
       
  1126                                                         \
  1131     (ret) = 0;                                          \
  1127     (ret) = 0;                                          \
       
  1128     SETNONBLOCKING(fileno(f), oldFlags);                \
       
  1129                                                         \
  1132     if (isBuffered) {                                   \
  1130     if (isBuffered) {                                   \
  1133 	while (__offs < (cnt)) {                        \
  1131         while (__offs < (cnt)) {                        \
  1134 	    CLEAR_ERRNO;                                \
  1132             CLEAR_ERRNO;                                \
  1135 	    (ret) = getc(f);                            \
  1133             (ret) = getc(f);                            \
  1136 	    if ((ret) < 0) {                            \
  1134             if ((ret) < 0) {                            \
  1137 		if (ferror(f)) {                        \
  1135                 if (ferror(f)) {                        \
  1138 		    if (__threadErrno == EINTR) {       \
  1136                     if (__threadErrno == EINTR) {       \
  1139 			clearerr(f);                    \
  1137                         clearerr(f);                    \
  1140 			/* refetch */                   \
  1138                         /* refetch */                   \
  1141 			buf = (char *)(obj);   \
  1139                         buf = (char *)(obj);   \
  1142 			(ret) = 0;                      \
  1140                         (ret) = 0;                      \
  1143 			break;                          \
  1141                         break;                          \
  1144 		    }                                   \
  1142                     }                                   \
  1145 		} else {                                \
  1143                 } else {                                \
  1146 		    (ret) = 0;                          \
  1144                     (ret) = 0;                          \
  1147 		}                                       \
  1145                 }                                       \
  1148 		break;                                  \
  1146                 break;                                  \
  1149 	    }                                           \
  1147             }                                           \
  1150 	    (buf)[__ooffs+__offs] = (ret);              \
  1148             (buf)[__ooffs+__offs] = (ret);              \
  1151 	    DEBUGBUFFER(buf);                           \
  1149             DEBUGBUFFER(buf);                           \
  1152 	    __offs++;                                   \
  1150             __offs++;                                   \
  1153 	}                                               \
  1151         }                                               \
  1154 	if (__offs > 0)                                 \
  1152         if (__offs > 0)                                 \
  1155 	    (ret) = __offs;                             \
  1153             (ret) = __offs;                             \
  1156     } else {                                            \
  1154     } else {                                            \
  1157 	int fd = fileno(f);                             \
  1155         int fd = fileno(f);                             \
  1158 							\
  1156                                                         \
  1159 	while (__offs < (cnt)) {                        \
  1157         while (__offs < (cnt)) {                        \
  1160 	    OBJ rA = __INST(readAhead);                 \
  1158             OBJ rA = __INST(readAhead);                 \
  1161 	    if (rA != nil) {                            \
  1159             if (rA != nil) {                            \
  1162 		(buf)[__ooffs+__offs] = __intVal(rA);   \
  1160                 (buf)[__ooffs+__offs] = __intVal(rA);   \
  1163 		DEBUGBUFFER(buf);                       \
  1161                 DEBUGBUFFER(buf);                       \
  1164 		__INST(readAhead) = nil;                \
  1162                 __INST(readAhead) = nil;                \
  1165 		__offs++;                               \
  1163                 __offs++;                               \
  1166 		continue;                               \
  1164                 continue;                               \
  1167 	    }                                           \
  1165             }                                           \
  1168 	    CLEAR_ERRNO;                                \
  1166             CLEAR_ERRNO;                                \
  1169 	    __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1167             __cnt = read(fd, (buf)+__ooffs+__offs, (cnt)-__offs); \
  1170 	    DEBUGBUFFER(buf);                           \
  1168             DEBUGBUFFER(buf);                           \
  1171 	    if (__cnt > 0) {                            \
  1169             if (__cnt > 0) {                            \
  1172 		__offs += __cnt;                        \
  1170                 __offs += __cnt;                        \
  1173 	    }                                           \
  1171             }                                           \
  1174 	    break;                                      \
  1172             break;                                      \
  1175 	}                                               \
  1173         }                                               \
  1176 	if (__offs > 0)                                 \
  1174         if (__offs > 0)                                 \
  1177 	    (ret) = __offs;                             \
  1175             (ret) = __offs;                             \
  1178     }                                                   \
  1176     }                                                   \
       
  1177     SETFLAGS(fileno(f), oldFlags);                      \
  1179   }
  1178   }
  1180 
  1179 
  1181 
  1180 
  1182 # endif /* use STDIO */
  1181 # endif /* use STDIO */
  1183 
  1182 
  1184 # ifdef NO_STDIO
  1183 # ifdef NO_STDIO
  1185 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)          \
  1184 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)          \
  1186 	for (;;) {                                      \
  1185         for (;;) {                                      \
  1187 	    CLEAR_ERRNO;                                \
  1186             CLEAR_ERRNO;                                \
  1188 	    (ret) = WRITE(f, buf, 1, handleType);                   \
  1187             (ret) = WRITE(f, buf, 1, handleType);                   \
  1189 	    if ((ret) >= 0 || __threadErrno != EINTR)           \
  1188             if ((ret) >= 0 || __threadErrno != EINTR)           \
  1190 		break;                                  \
  1189                 break;                                  \
  1191 	    __HANDLE_INTERRUPTS__;                      \
  1190             __HANDLE_INTERRUPTS__;                      \
  1192 	}
  1191         }
  1193 # else /* use STDIO */
  1192 # else /* use STDIO */
  1194 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)        \
  1193 #  define __WRITEBYTE__(ret, f, buf, isBuffered, handleType)        \
  1195     if (isBuffered) {                                   \
  1194     if (isBuffered) {                                   \
  1196 	for (;;) {                                      \
  1195         for (;;) {                                      \
  1197 	    CLEAR_ERRNO;                                \
  1196             CLEAR_ERRNO;                                \
  1198 	    ret = putc(*(buf), f);                      \
  1197             ret = putc(*(buf), f);                      \
  1199 	    if ((ret) >= 0) {                           \
  1198             if ((ret) >= 0) {                           \
  1200 		(ret) = 1;                              \
  1199                 (ret) = 1;                              \
  1201 	    } else if (ferror(f)) {                     \
  1200             } else if (ferror(f)) {                     \
  1202 		/* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \
  1201                 /* SOLARIS/SPARC (2.6) generates spurious errors with errno = 0 */ \
  1203 		if (__threadErrno == EINTR || __threadErrno == 0) {     \
  1202                 if (__threadErrno == EINTR || __threadErrno == 0) {     \
  1204 		    __HANDLE_INTERRUPTS__;              \
  1203                     __HANDLE_INTERRUPTS__;              \
  1205 		    clearerr(f);                        \
  1204                     clearerr(f);                        \
  1206 		    continue;                           \
  1205                     continue;                           \
  1207 		}                                       \
  1206                 }                                       \
  1208 	    } else                                      \
  1207             } else                                      \
  1209 		(ret) = 0;                              \
  1208                 (ret) = 0;                              \
  1210 	    break;                                      \
  1209             break;                                      \
  1211 	}                                               \
  1210         }                                               \
  1212     } else {                                            \
  1211     } else {                                            \
  1213 	for (;;) {                                      \
  1212         for (;;) {                                      \
  1214 	    CLEAR_ERRNO;                                \
  1213             CLEAR_ERRNO;                                \
  1215 	    (ret) = write(fileno(f), buf, 1);           \
  1214             (ret) = write(fileno(f), buf, 1);           \
  1216 	    if ((ret) >= 0 || __threadErrno != EINTR)           \
  1215             if ((ret) >= 0 || __threadErrno != EINTR)           \
  1217 		break;                                  \
  1216                 break;                                  \
  1218 	    __HANDLE_INTERRUPTS__;                      \
  1217             __HANDLE_INTERRUPTS__;                      \
  1219 	}                                               \
  1218         }                                               \
  1220    }
  1219    }
  1221 # endif /* use STDIO */
  1220 # endif /* use STDIO */
  1222 
  1221 
  1223 /*
  1222 /*
  1224  * write_bytes from a c-buffer
  1223  * write_bytes from a c-buffer
  1226  */
  1225  */
  1227 # ifdef NO_STDIO
  1226 # ifdef NO_STDIO
  1228 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1227 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1229     (ret) = 0;                                          \
  1228     (ret) = 0;                                          \
  1230     {                                                   \
  1229     {                                                   \
  1231 	int __offs = 0;                                 \
  1230         int __offs = 0;                                 \
  1232 	while (__offs < (cnt)) {                        \
  1231         while (__offs < (cnt)) {                        \
  1233 	    CLEAR_ERRNO;                                \
  1232             CLEAR_ERRNO;                                \
  1234 	    ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \
  1233             ret = WRITE(f, (buf)+__offs, (cnt)-__offs, handleType); \
  1235 	    if (ret <= 0) {                             \
  1234             if (ret <= 0) {                             \
  1236 		if (ret < 0 && __threadErrno == EINTR) {        \
  1235                 if (ret < 0 && __threadErrno == EINTR) {        \
  1237 		    __HANDLE_INTERRUPTS__;              \
  1236                     __HANDLE_INTERRUPTS__;              \
  1238 		    continue;                           \
  1237                     continue;                           \
  1239 		}                                       \
  1238                 }                                       \
  1240 		break;                                  \
  1239                 break;                                  \
  1241 	    }                                           \
  1240             }                                           \
  1242 	    __offs += (ret);                            \
  1241             __offs += (ret);                            \
  1243 	}                                               \
  1242         }                                               \
  1244 	if (__offs > 0)                                 \
  1243         if (__offs > 0)                                 \
  1245 	    (ret) = __offs;                             \
  1244             (ret) = __offs;                             \
  1246    }
  1245    }
  1247 # else /* use STDIO */
  1246 # else /* use STDIO */
  1248 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1247 #  define __WRITEBYTES__(ret, f, buf, cnt, isBuffered, handleType)    \
  1249     (ret) = 0;                                          \
  1248     (ret) = 0;                                          \
  1250     if (isBuffered) {                                   \
  1249     if (isBuffered) {                                   \
  1251 	int __offs = 0;                                 \
  1250         int __offs = 0;                                 \
  1252 	while (__offs < (cnt)) {                        \
  1251         while (__offs < (cnt)) {                        \
  1253 	    CLEAR_ERRNO;                                \
  1252             CLEAR_ERRNO;                                \
  1254 	    ret = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
  1253             ret = fwrite((buf)+__offs, 1, (cnt)-__offs, f);\
  1255 	    if ((ret) <= 0) {                            \
  1254             if ((ret) <= 0) {                            \
  1256 		if (ferror(f)) {                        \
  1255                 if (ferror(f)) {                        \
  1257 		    if (__threadErrno == EINTR) {               \
  1256                     if (__threadErrno == EINTR) {               \
  1258 			__HANDLE_INTERRUPTS__;          \
  1257                         __HANDLE_INTERRUPTS__;          \
  1259 			clearerr(f);                    \
  1258                         clearerr(f);                    \
  1260 			continue;                       \
  1259                         continue;                       \
  1261 		    }                                   \
  1260                     }                                   \
  1262 		    break;                              \
  1261                     break;                              \
  1263 		} else {                                \
  1262                 } else {                                \
  1264 		    (ret) = 0;                          \
  1263                     (ret) = 0;                          \
  1265 		}                                       \
  1264                 }                                       \
  1266 	    }                                           \
  1265             }                                           \
  1267 	    __offs += (ret);                            \
  1266             __offs += (ret);                            \
  1268 	}                                               \
  1267         }                                               \
  1269 	if (__offs > 0)                                 \
  1268         if (__offs > 0)                                 \
  1270 	    (ret) = __offs;                             \
  1269             (ret) = __offs;                             \
  1271     } else {                                            \
  1270     } else {                                            \
  1272 	int __offs = 0;                                 \
  1271         int __offs = 0;                                 \
  1273 	while (__offs < (cnt)) {                        \
  1272         while (__offs < (cnt)) {                        \
  1274 	    CLEAR_ERRNO;                                \
  1273             CLEAR_ERRNO;                                \
  1275 	    ret = write(fileno(f), (buf)+__offs, (cnt)-__offs);\
  1274             ret = write(fileno(f), (buf)+__offs, (cnt)-__offs);\
  1276 	    if (ret <= 0) {                             \
  1275             if (ret <= 0) {                             \
  1277 		if (ret < 0 && __threadErrno == EINTR) {        \
  1276                 if (ret < 0 && __threadErrno == EINTR) {        \
  1278 		    __HANDLE_INTERRUPTS__;              \
  1277                     __HANDLE_INTERRUPTS__;              \
  1279 		    continue;                           \
  1278                     continue;                           \
  1280 		}                                       \
  1279                 }                                       \
  1281 		break;                                  \
  1280                 break;                                  \
  1282 	    }                                           \
  1281             }                                           \
  1283 	    __offs += (ret);                            \
  1282             __offs += (ret);                            \
  1284 	}                                               \
  1283         }                                               \
  1285 	if (__offs > 0)                                 \
  1284         if (__offs > 0)                                 \
  1286 	    (ret) = __offs;                             \
  1285             (ret) = __offs;                             \
  1287    }
  1286    }
  1288 # endif /* use STDIO */
  1287 # endif /* use STDIO */
  1289 
  1288 
  1290 /*
  1289 /*
  1291  * write_bytes from an object
  1290  * write_bytes from an object
  1295 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1294 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1296   {                                                     \
  1295   {                                                     \
  1297     int __ooffs = obj_offs;                             \
  1296     int __ooffs = obj_offs;                             \
  1298     int __offs = 0;                                     \
  1297     int __offs = 0;                                     \
  1299     char *buf = (char *)(obj);                          \
  1298     char *buf = (char *)(obj);                          \
  1300 							\
  1299                                                         \
  1301     (ret) = 0;                                          \
  1300     (ret) = 0;                                          \
  1302     {                                                   \
  1301     {                                                   \
  1303 	while (__offs < (cnt)) {                        \
  1302         while (__offs < (cnt)) {                        \
  1304 	    CLEAR_ERRNO;                                \
  1303             CLEAR_ERRNO;                                \
  1305 	    ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1304             ret = WRITE(f, (buf)+__ooffs+__offs, (cnt)-__offs, handleType); \
  1306 	    if (ret <= 0) {                             \
  1305             if (ret <= 0) {                             \
  1307 		if (ret < 0 && __threadErrno == EINTR) { \
  1306                 if (ret < 0 && __threadErrno == EINTR) { \
  1308 		    __HANDLE_INTERRUPTS__;              \
  1307                     __HANDLE_INTERRUPTS__;              \
  1309 		    /* refetch */                       \
  1308                     /* refetch */                       \
  1310 		    buf = (char *)(obj);       \
  1309                     buf = (char *)(obj);       \
  1311 		    continue;                           \
  1310                     continue;                           \
  1312 		}                                       \
  1311                 }                                       \
  1313 		break;                                  \
  1312                 break;                                  \
  1314 	    }                                           \
  1313             }                                           \
  1315 	    __offs += (ret);                            \
  1314             __offs += (ret);                            \
  1316 	}                                               \
  1315         }                                               \
  1317 	if (__offs > 0)                                 \
  1316         if (__offs > 0)                                 \
  1318 	    (ret) = __offs;                             \
  1317             (ret) = __offs;                             \
  1319     }                                                   \
  1318     }                                                   \
  1320   }
  1319   }
  1321 # else /* use STDIO */
  1320 # else /* use STDIO */
  1322 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1321 #  define __WRITEBYTES_OBJ__(ret, f, obj, obj_offs, cnt, isBuffered, handleType)            \
  1323   {                                                     \
  1322   {                                                     \
  1324     int __ooffs = obj_offs;                             \
  1323     int __ooffs = obj_offs;                             \
  1325     int __offs = 0;                                     \
  1324     int __offs = 0;                                     \
  1326     char *buf = (char *)(obj);                          \
  1325     char *buf = (char *)(obj);                          \
  1327 							\
  1326                                                         \
  1328     (ret) = 0;                                          \
  1327     (ret) = 0;                                          \
  1329     if (isBuffered) {                                   \
  1328     if (isBuffered) {                                   \
  1330 	while (__offs < (cnt)) {                        \
  1329         while (__offs < (cnt)) {                        \
  1331 	    CLEAR_ERRNO;                                \
  1330             CLEAR_ERRNO;                                \
  1332 	    ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f);           \
  1331             ret = fwrite((buf)+__ooffs+__offs, 1, (cnt)-__offs, f);           \
  1333 	    if ((ret) <= 0) {                           \
  1332             if ((ret) <= 0) {                           \
  1334 		if (ferror(f)) {                        \
  1333                 if (ferror(f)) {                        \
  1335 		    if (__threadErrno == EINTR) {       \
  1334                     if (__threadErrno == EINTR) {       \
  1336 			__HANDLE_INTERRUPTS__;          \
  1335                         __HANDLE_INTERRUPTS__;          \
  1337 			/* refetch */                   \
  1336                         /* refetch */                   \
  1338 			buf = (char *)(obj);   \
  1337                         buf = (char *)(obj);   \
  1339 			clearerr(f);                    \
  1338                         clearerr(f);                    \
  1340 			continue;                       \
  1339                         continue;                       \
  1341 		    }                                   \
  1340                     }                                   \
  1342 		    break;                              \
  1341                     break;                              \
  1343 		} else {                                \
  1342                 } else {                                \
  1344 		    (ret) = 0;                          \
  1343                     (ret) = 0;                          \
  1345 		}                                       \
  1344                 }                                       \
  1346 	    }                                           \
  1345             }                                           \
  1347 	    __offs += (ret);                            \
  1346             __offs += (ret);                            \
  1348 	}                                               \
  1347         }                                               \
  1349 	if (__offs > 0)                                 \
  1348         if (__offs > 0)                                 \
  1350 	    (ret) = __offs;                             \
  1349             (ret) = __offs;                             \
  1351     } else {                                            \
  1350     } else {                                            \
  1352 	while (__offs < (cnt)) {                        \
  1351         while (__offs < (cnt)) {                        \
  1353 	    CLEAR_ERRNO;                                \
  1352             CLEAR_ERRNO;                                \
  1354 	    ret = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs);       \
  1353             ret = write(fileno(f), (buf)+__ooffs+__offs, (cnt)-__offs);       \
  1355 	    if (ret <= 0) {                             \
  1354             if (ret <= 0) {                             \
  1356 		if (ret < 0 && __threadErrno == EINTR){ \
  1355                 if (ret < 0 && __threadErrno == EINTR){ \
  1357 		    __HANDLE_INTERRUPTS__;              \
  1356                     __HANDLE_INTERRUPTS__;              \
  1358 		    /* refetch */                       \
  1357                     /* refetch */                       \
  1359 		    buf = (char *)(obj);       \
  1358                     buf = (char *)(obj);       \
  1360 		    continue;                           \
  1359                     continue;                           \
  1361 		}                                       \
  1360                 }                                       \
  1362 		break;                                  \
  1361                 break;                                  \
  1363 	    }                                           \
  1362             }                                           \
  1364 	    __offs += (ret);                            \
  1363             __offs += (ret);                            \
  1365 	}                                               \
  1364         }                                               \
  1366 	if (__offs > 0)                                 \
  1365         if (__offs > 0)                                 \
  1367 	    (ret) = __offs;                             \
  1366             (ret) = __offs;                             \
  1368     }                                                   \
  1367     }                                                   \
  1369   }
  1368   }
  1370 # endif /* use STDIO */
  1369 # endif /* use STDIO */
  1371 #endif /* unix */
  1370 #endif /* unix */
  1372 
  1371 
  3301     __INST(lastErrorNumber) = nil;
  3300     __INST(lastErrorNumber) = nil;
  3302     if ((__INST(handleType) == nil)
  3301     if ((__INST(handleType) == nil)
  3303      || (__INST(handleType) == @symbol(filePointer))
  3302      || (__INST(handleType) == @symbol(filePointer))
  3304      || (__INST(handleType) == @symbol(socketFilePointer))
  3303      || (__INST(handleType) == @symbol(socketFilePointer))
  3305      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3304      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3306 	if (((fp = __INST(handle)) != nil)
  3305         if (((fp = __INST(handle)) != nil)
  3307 	    && (__INST(mode) != @symbol(writeonly))
  3306             && (__INST(mode) != @symbol(writeonly))
  3308 	    && __bothSmallInteger(count, start)
  3307             && __bothSmallInteger(count, start)
  3309 	) {
  3308         ) {
  3310 	    f = __FILEVal(fp);
  3309             f = __FILEVal(fp);
  3311 
  3310 
  3312 	    cnt = __intVal(count);
  3311             cnt = __intVal(count);
  3313 	    offs = __intVal(start) - 1;
  3312             offs = __intVal(start) - 1;
  3314 
  3313 
  3315 	    if (__isExternalBytesLike(anObject)) {
  3314             if (__isExternalBytesLike(anObject)) {
  3316 		OBJ sz;
  3315                 OBJ sz;
  3317 
  3316 
  3318 		nInstBytes = 0;
  3317                 nInstBytes = 0;
  3319 		extPtr = (char *)(__externalBytesAddress(anObject));
  3318                 extPtr = (char *)(__externalBytesAddress(anObject));
  3320 		if (extPtr == NULL) goto bad;
  3319                 if (extPtr == NULL) goto bad;
  3321 		sz = __externalBytesSize(anObject);
  3320                 sz = __externalBytesSize(anObject);
  3322 		if (__isSmallInteger(sz)) {
  3321                 if (__isSmallInteger(sz)) {
  3323 		    objSize = __intVal(sz);
  3322                     objSize = __intVal(sz);
  3324 		} else {
  3323                 } else {
  3325 		    objSize = 0; /* unknown */
  3324                     objSize = 0; /* unknown */
  3326 		}
  3325                 }
  3327 	    } else {
  3326             } else {
  3328 		OBJ oClass;
  3327                 OBJ oClass;
  3329 
  3328 
  3330 		oClass = __Class(anObject);
  3329                 oClass = __Class(anObject);
  3331 		switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3330                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3332 		    case BYTEARRAY:
  3331                     case BYTEARRAY:
  3333 		    case WORDARRAY:
  3332                     case WORDARRAY:
  3334 		    case LONGARRAY:
  3333                     case LONGARRAY:
  3335 		    case SWORDARRAY:
  3334                     case SWORDARRAY:
  3336 		    case SLONGARRAY:
  3335                     case SLONGARRAY:
  3337 		    case FLOATARRAY:
  3336                     case FLOATARRAY:
  3338 		    case DOUBLEARRAY:
  3337                     case DOUBLEARRAY:
  3339 			break;
  3338                         break;
  3340 		    default:
  3339                     default:
  3341 			goto bad;
  3340                         goto bad;
  3342 		}
  3341                 }
  3343 		extPtr = (char *)0;
  3342                 extPtr = (char *)0;
  3344 		nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3343                 nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3345 		nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3344                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3346 		objSize = __Size(anObject) - nInstBytes;
  3345                 objSize = __Size(anObject) - nInstBytes;
  3347 	    }
  3346             }
  3348 
  3347 
  3349 	    if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3348             if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3350 		_buffered = (__INST(buffered) == true);
  3349                 _buffered = (__INST(buffered) == true);
  3351 		if (_buffered) {
  3350                 if (_buffered) {
  3352 		    __READING__(f);
  3351                     __READING__(f);
  3353 		}
  3352                 }
  3354 
  3353 
  3355 		if (extPtr) {
  3354                 if (extPtr) {
  3356 		    __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3355                     __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3357 		} else {
  3356                 } else {
  3358 		    /*
  3357                     /*
  3359 		     * on interrupt, anObject may be moved to another location.
  3358                      * on interrupt, anObject may be moved to another location.
  3360 		     * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  3359                      * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  3361 		     * to get a new address.
  3360                      * to get a new address.
  3362 		     */
  3361                      */
  3363 		    offs += nInstBytes;
  3362                     offs += nInstBytes;
  3364 		    __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3363                     __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3365 		}
  3364                 }
  3366 #ifdef PRE_22_jan_2000
  3365 #ifdef PRE_22_jan_2000
  3367 		if (ret > 0)
  3366                 if (ret > 0)
  3368 #else
  3367 #else
  3369 		/* 0 is NOT an EOF condition here ... */
  3368                 /* 0 is NOT an EOF condition here ... */
  3370 		if (ret >= 0)
  3369                 if (ret >= 0)
  3371 #endif
  3370 #endif
  3372 		{
  3371                 {
  3373 		    if (__isSmallInteger(__INST(position))) {
  3372                     if (__isSmallInteger(__INST(position))) {
  3374 			INT np = __intVal(__INST(position)) + ret;
  3373                         INT np = __intVal(__INST(position)) + ret;
  3375 			OBJ t;
  3374                         OBJ t;
  3376 
  3375 
  3377 			t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3376                         t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3378 		    } else {
  3377                     } else {
  3379 			__INST(position) = nil; /* i.e. do not know */
  3378                         __INST(position) = nil; /* i.e. do not know */
  3380 		    }
  3379                     }
  3381 		    RETURN (__mkSmallInteger(ret));
  3380                     RETURN (__mkSmallInteger(ret));
  3382 		}
  3381                 }
  3383 #ifdef PRE_22_jan_2000
  3382 #ifdef PRE_22_jan_2000
  3384 		if (ret == 0) {
  3383                 if (ret == 0) {
  3385 		    __INST(hitEOF) = true;
  3384                     __INST(hitEOF) = true;
  3386 		} else /* ret < 0 */
  3385                 } else /* ret < 0 */
  3387 #endif
  3386 #endif
  3388 		{
  3387                 {
  3389 		    __INST(position) = nil;
  3388                     __INST(position) = nil;
  3390 		    __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  3389                     __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  3391 		}
  3390                 }
  3392 	    }
  3391             }
  3393 	}
  3392         }
  3394     }
  3393     }
  3395 bad: ;
  3394 bad: ;
  3396 %}.
  3395 %}.
  3397     (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0].
  3396     (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0].
  3398     lastErrorNumber notNil ifTrue:[^ self readError].
  3397     lastErrorNumber notNil ifTrue:[^ self readError].
  5761 ! !
  5760 ! !
  5762 
  5761 
  5763 !ExternalStream class methodsFor:'documentation'!
  5762 !ExternalStream class methodsFor:'documentation'!
  5764 
  5763 
  5765 version
  5764 version
  5766     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.362 2013-05-15 21:49:08 cg Exp $'
  5765     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.363 2013-05-31 12:50:39 stefan Exp $'
  5767 !
  5766 !
  5768 
  5767 
  5769 version_CVS
  5768 version_CVS
  5770     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.362 2013-05-15 21:49:08 cg Exp $'
  5769     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.363 2013-05-31 12:50:39 stefan Exp $'
  5771 ! !
  5770 ! !
  5772 
  5771 
  5773 
  5772 
  5774 ExternalStream initialize!
  5773 ExternalStream initialize!