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 { \ |
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) { \ |
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) { |