--- socket.c.orig 2002-05-28 12:55:36.000000000 -0400 +++ socket.c 2002-05-28 12:51:29.000000000 -0400 @@ -40,7 +40,7 @@ #include "fetchmail.h" #include "i18n.h" -/* Defines to allow BeOS to play nice... */ +/* Defines to allow BeOS and Cygwin to play nice... */ #ifdef __BEOS__ static char peeked; #define fm_close(a) closesocket(a) @@ -51,7 +51,12 @@ static char peeked; #define fm_close(a) close(a) #define fm_write(a,b,c) write(a,b,c) #define fm_peek(a,b,c) recv(a,b,c, MSG_PEEK) +#ifdef __CYGWIN__ +#define fm_read(a,b,c) cygwin_read(a,b,c) +static ssize_t cygwin_read(int sock, void *buf, size_t count); +#else /* ! __CYGWIN__ */ #define fm_read(a,b,c) read(a,b,c) +#endif /* __CYGWIN__ */ #endif /* We need to define h_errno only if it is not already */ @@ -998,6 +1003,33 @@ int SockClose(int sock) return(fm_close(sock)); /* this is guarded */ } +#ifdef __CYGWIN__ +/* + * Workaround Microsoft Winsock recv/WSARecv(..., MSG_PEEK) bug. + * See http://sources.redhat.com/ml/cygwin/2001-08/msg00628.html + * for more details. + */ +static ssize_t cygwin_read(int sock, void *buf, size_t count) +{ + char *bp = buf; + int n = 0; + + if ((n = read(sock, bp, count)) == -1) + return(-1); + + if (n != count) { + int n2 = 0; + if (outlevel >= O_VERBOSE) + report(stdout, GT_("Cygwin socket read retry\n")); + n2 = read(sock, bp + n, count - n); + if (n2 == -1 || n + n2 != count) { + report(stderr, GT_("Cygwin socket read retry failed!\n")); + return(-1); + } + } +} +#endif /* __CYGWIN__ */ + #ifdef MAIN /* * Use the chargen service to test input buffering directly.