ExternalStream.st
changeset 21066 b7050f50aa94
parent 21037 152fe5102be0
child 21088 6f4535127ce6
child 21097 12cf2700134c
equal deleted inserted replaced
21065:d4735595a002 21066:b7050f50aa94
   222 #else
   222 #else
   223 # define OPT_FSEEK(f, pos, whence)      /* nothing */
   223 # define OPT_FSEEK(f, pos, whence)      /* nothing */
   224 #endif
   224 #endif
   225 
   225 
   226 #ifdef __win32__
   226 #ifdef __win32__
   227 // Win returns from ReadFile() with false and _threadErrno == 0 on end of pipe.
       
   228 // We don't know why
       
   229 #  define READ(ret, f, cp, n, handleType) { \
   227 #  define READ(ret, f, cp, n, handleType) { \
   230         if (handleType == @symbol(socketHandle)) { \
   228         if (handleType == @symbol(socketHandle)) { \
   231           (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \
   229           (ret) = __STX_WSA_NOINT_CALL4("recv", recv, (f), (cp), (n), 0); \
   232         } else { \
   230         } else { \
   233           HANDLE h = _get_osfhandle(fileno(f)); \
   231           HANDLE h = _get_osfhandle(fileno(f)); \
   234           if (handleType == @symbol(socketFilePointer)) { \
   232           if (handleType == @symbol(socketFilePointer)) { \
   235             (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   233             (ret) = __STX_WSA_NOINT_CALL4("recv", recv, h, (cp), (n), 0);\
   236           } else { \
   234           } else { \
   237             int __res; \
   235             int __res; \
   238             (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   236             (ret) = __STX_API_NOINT_CALL5("ReadFile", ReadFile, h, (cp), (n), &__res, 0);\
   239             (ret) = (ret) ? __res : ((__threadErrno == EPIPE || __threadErrno == 0) ? 0 : -1); \
   237             (ret) = (ret) > 0 ? __res : (__threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1); \
   240           } \
   238           } \
   241         } \
   239         } \
   242       }
   240       }
   243 
   241 
   244 #  define WRITE(ret, f, cp, n, handleType) { \
   242 #  define WRITE(ret, f, cp, n, handleType) { \
   407               int res = -1, ok = 0;                     \
   405               int res = -1, ok = 0;                     \
   408               SOCKET sock = 0;                          \
   406               SOCKET sock = 0;                          \
   409               if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   407               if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   410                   || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   408                   || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   411                   || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   409                   || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   412                   if (!ok) { (ret) = -1; break; }       \
   410                    if (!ok) {                                                               \
       
   411                         __threadErrno = sock ? WSAGetLastError() : __WIN32_ERR(GetLastError()); \
       
   412                         (ret) = __threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1;   \
       
   413                         break;                                                              \
       
   414                    }                                \
   413                   if (res > 0) {                        \
   415                   if (res > 0) {                        \
   414                       if (res > ((cnt)-__offs))         \
   416                       if (res > ((cnt)-__offs))         \
   415                           res = (cnt)-__offs;           \
   417                           res = (cnt)-__offs;           \
   416                       READ((ret), f, (buf)+__offs, res, handleType); \
   418                       READ((ret), f, (buf)+__offs, res, handleType); \
   417                   } else {                              \
   419                   } else {                              \
   454             if ((ret) < 0) {                            \
   456             if ((ret) < 0) {                            \
   455                 if (ferror(f)) {                        \
   457                 if (ferror(f)) {                        \
   456                     if (__threadErrno == EINTR) {       \
   458                     if (__threadErrno == EINTR) {       \
   457                         clearerr(f);                    \
   459                         clearerr(f);                    \
   458                         /* refetch */                   \
   460                         /* refetch */                   \
   459                         buf = (char *)(obj);   \
   461                         buf = (char *)(obj);            \
   460                         continue;                       \
   462                         continue;                       \
   461                     }                                   \
   463                     }                                   \
   462                 } else {                                \
   464                 } else {                                \
   463                     (ret) = 0;                          \
   465                     (ret) = 0;                          \
   464                 }                                       \
   466                 }                                       \
   552                 CLEAR_ERRNO;                         \
   554                 CLEAR_ERRNO;                         \
   553                 if (l > IO_BUFFER_SIZE) l = IO_BUFFER_SIZE;              \
   555                 if (l > IO_BUFFER_SIZE) l = IO_BUFFER_SIZE;              \
   554                 if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   556                 if ((handleType == @symbol(socketFilePointer) && ((ok = ioctlsocket(sock = (SOCKET)_get_osfhandle(fileno(f)),FIONREAD,&res) == 0), 1)) \
   555                     || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   557                     || (handleType == @symbol(socketHandle) && ((ok = ioctlsocket(sock = (SOCKET)(f), FIONREAD, &res) == 0), 1)) \
   556                     || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   558                     || (handleType == @symbol(pipeFilePointer) && ((ok = PeekNamedPipe((HANDLE)_get_osfhandle(fileno(f)),0, 0,0,&res,0)), 1))) { \
   557                    if (!ok) { (ret) = -1; break; }       \
   559                    if (!ok) {                                                               \
       
   560                         __threadErrno = sock ? WSAGetLastError() : __WIN32_ERR(GetLastError()); \
       
   561                         (ret) = __threadErrno == __WIN32_ERR(ERROR_BROKEN_PIPE) ? 0 : -1;   \
       
   562                         break;                                                              \
       
   563                    }                                \
   558                    if (res > 0) {                   \
   564                    if (res > 0) {                   \
   559                         if (res > l) res = l;       \
   565                         if (res > l) res = l;       \
   560                         READ((ret), f, __buf, res, handleType); \
   566                         READ((ret), f, __buf, res, handleType); \
   561                    } else {                              \
   567                    } else {                              \
   562                        if (sock && send(sock, NULL, 0, 0) == SOCKET_ERROR) {     \
   568                        if (sock && send(sock, NULL, 0, 0) == SOCKET_ERROR) {     \
   564                        } else {                          \
   570                        } else {                          \
   565                          (ret) = 0;                      \
   571                          (ret) = 0;                      \
   566                        }                                 \
   572                        }                                 \
   567                        break;                            \
   573                        break;                            \
   568                    }                                     \
   574                    }                                     \
   569                 } else {                             \
   575                 } else {                                  \
   570                     READ((ret), f, __buf, l, handleType); \
   576                     READ((ret), f, __buf, l, handleType); \
   571                 }                                     \
   577                 }                                     \
   572                 if ((ret) <= 0) {                     \
   578                 if ((ret) <= 0) {                     \
   573                     if ((ret) < 0 && __threadErrno == EINTR) \
   579                     if ((ret) < 0 && __threadErrno == EINTR) \
   574                         continue;                       \
   580                         continue;                       \
   638     } else {                                            \
   644     } else {                                            \
   639         int __offs = 0;                                 \
   645         int __offs = 0;                                 \
   640         while (__offs < (cnt)) {                        \
   646         while (__offs < (cnt)) {                        \
   641             CLEAR_ERRNO;                                \
   647             CLEAR_ERRNO;                                \
   642             WRITE((ret),f, (buf)+__offs, (cnt)-__offs, handleType);   \
   648             WRITE((ret),f, (buf)+__offs, (cnt)-__offs, handleType);   \
   643             if ((ret) <= 0) {                             \
   649             if ((ret) <= 0) {                           \
   644                 if ((ret) < 0 && __threadErrno == EINTR) { \
   650                 if ((ret) < 0 && __threadErrno == EINTR) { \
   645                     continue;                           \
   651                     continue;                           \
   646                 }                                       \
   652                 }                                       \
   647                 break;                                  \
   653                 break;                                  \
   648             }                                           \
   654             }                                           \
  5623             /*
  5629             /*
  5624              * read ahead ...
  5630              * read ahead ...
  5625              */
  5631              */
  5626             do {
  5632             do {
  5627 #ifdef __win32__
  5633 #ifdef __win32__
  5628 # if 1
       
  5629                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5634                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5630 
       
  5631 # else
       
  5632                 __BEGIN_INTERRUPTABLE__
       
  5633                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
       
  5634                 __END_INTERRUPTABLE__
       
  5635 # endif
       
  5636 #else /* not __win32__ */
  5635 #else /* not __win32__ */
  5637                 __BEGIN_INTERRUPTABLE__
  5636                 __BEGIN_INTERRUPTABLE__
  5638                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5637                 __READBYTE__(ret, f, &c, _buffered, __INST(handleType));
  5639                 __END_INTERRUPTABLE__
  5638                 __END_INTERRUPTABLE__
  5640 #endif
  5639 #endif
  5641             } while ((ret < 0) && (__threadErrno == EINTR));
  5640             } while ((ret < 0) && (__threadErrno == EINTR));
  5642 
       
  5643             if (ret > 0) {
  5641             if (ret > 0) {
  5644                 __UNGETC__(c&0xff, f, _buffered);
  5642                 __UNGETC__(c&0xff, f, _buffered);
  5645                 RETURN (false);
  5643                 RETURN (false);
  5646             }
  5644             }
  5647             if (ret == 0) {
  5645             if (ret == 0) {