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