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