Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Date: Tue, 28 May 2002 13:26:54 -0400 From: Jason Tishler Subject: Cygwin Winsock recv/WSARecv(..., MSG_PEEK) patch (Take 2) In-reply-to: <20020524032941.B1462@thyrsus.com> To: fetchmail-friends AT lists DOT ccil DOT org, Cygwin Mail-followup-to: fetchmail-friends AT lists DOT ccil DOT org, Cygwin Message-id: <20020528172653.GE3272@tishler.net> MIME-version: 1.0 Content-type: multipart/mixed; boundary="Boundary_(ID_pkFno0uKpwCSm8Dutn8/Yw)" User-Agent: Mutt/1.3.24i References: <20020429120347 DOT GA1152 AT tishler DOT net> <20020524032941 DOT B1462 AT thyrsus DOT com> --Boundary_(ID_pkFno0uKpwCSm8Dutn8/Yw) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline Eric, On Fri, May 24, 2002 at 03:29:41AM -0400, Eric S. Raymond wrote: > Jason Tishler : > > Would you consider accepting this patch into fetchmail CVS? > > Taken, thanks. Attached is (two versions of) "take 2" of my patch that applies the Winsock recv/WSARecv(..., MSG_PEEK) workaround to socket.c -- this time to both the non-SSL *and* SSL #ifdef code sections. The first patch, socket.c-2.diff, assumes that my previous patch has been applied. The second one, socket.c-3.diff, is against the original 5.9.11 source. Please choose the one that is most convenient for you to use. I apologize for the gyrations, but I didn't realize the need to patch SockRead() for both the non-SSL and SSL cases. If interested, see the following Cygwin mailing list thread for the details: http://cygwin.com/ml/cygwin/2002-05/msg01554.html Note that I have re-factored my patch to handle both cases in a way which I think is less intrusive than my first attempt. Would you consider accepting this new version into fetchmail CVS? Thanks, Jason --Boundary_(ID_pkFno0uKpwCSm8Dutn8/Yw) Content-type: text/plain; charset=us-ascii; NAME=socket.c-2.diff Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=socket.c-2.diff --- ../fetchmail-5.9.11-1/socket.c 2002-05-16 15:14:28.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 */ @@ -536,7 +541,7 @@ int SockWrite(int sock, char *buf, int l int SockRead(int sock, char *buf, int len) { char *newline, *bp = buf; - int n, n2; + int n; #ifdef SSL_ENABLE SSL *ssl; #endif @@ -627,25 +632,8 @@ int SockRead(int sock, char *buf, int le if ((newline = memchr(bp, '\n', n)) != NULL) n = newline - bp + 1; #ifndef __BEOS__ - if ((n2 = fm_read(sock, bp, n)) == -1) + if ((n = fm_read(sock, bp, n)) == -1) return(-1); -#ifdef __CYGWIN__ - /* - * Workaround Microsoft Winsock recv/WSARecv(..., MSG_PEEK) bug. - * See http://sources.redhat.com/ml/cygwin/2001-08/msg00628.html - * for more details. - */ - if (n2 != n) { - int n3; - if (outlevel >= O_VERBOSE) - report(stdout, GT_("Cygwin socket read retry\n")); - n3 = fm_read(sock, bp + n2, n - n2); - if (n3 == -1 || n2 + n3 != n) { - report(stderr, GT_("Cygwin socket read retry failed!\n")); - return(-1); - } - } -#endif /* __CYGWIN__ */ #endif /* __BEOS__ */ #endif bp += n; @@ -1015,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. --Boundary_(ID_pkFno0uKpwCSm8Dutn8/Yw) Content-type: text/plain; charset=us-ascii; NAME=socket.c-3.diff Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=socket.c-3.diff --- 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. --Boundary_(ID_pkFno0uKpwCSm8Dutn8/Yw) Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --Boundary_(ID_pkFno0uKpwCSm8Dutn8/Yw)--