Another attempt at this; still probably completely ineffective but still less incorrect than the previous attempt, and still prevents error returns. See further comments on wine-devel. -gmt P.S., trying yet another mail client; I tested and theoretically this won't wrap... if it does, sorry, don't use and I'll resend as an attachment. -- "Waiting periods are only a step. Registration is only a step. The prohibition of private firearms is the goal." -U.S. Attorney General Janet Reno, December 1993 CHANGELOG: * dlls/winsock/socket.c: Greg Turner <gmturner007@ameritech.net> - fixed up some semantic misunderstandings using the helpful advice of Rein Klazes <rklazes@xs4all.nl> - added SO_SNDTIMEO support - added ifdef's for consistency with rest of socket.c Index: dlls/winsock/socket.c =================================================================== RCS file: /home/wine/wine/dlls/winsock/socket.c,v retrieving revision 1.107 diff -u -r1.107 socket.c --- dlls/winsock/socket.c 25 Sep 2002 00:15:43 -0000 1.107 +++ dlls/winsock/socket.c 25 Sep 2002 23:31:03 -0000 @@ -2705,21 +2705,44 @@ optval= (char*) &woptval; optlen=sizeof(int); } - if (level == SOL_SOCKET && optname == SO_RCVTIMEO && optlen < sizeof(struct timeval)) { - if (optlen == sizeof(time_t)) { - /* Apparently WinSock will accept a shortened struct timeval. - FIXME: should we do the same for SO_SNDTIMEO? */ - WARN("Short struct timeval in SO_RCVTIMEO: assuming time_t\n"); - tval.tv_sec = *(time_t*)optval; - tval.tv_usec = 0; +#ifdef SO_RCVTIMEO + if (level == SOL_SOCKET && optname == SO_RCVTIMEO) { + if (optlen == sizeof(UINT32)) { + /* WinSock passes miliseconds instead of struct timeval */ + tval.tv_usec = *(PUINT32)optval % 1000; + tval.tv_sec = *(PUINT32)optval / 1000; + /* min of 500 milisec */ + if (tval.tv_sec == 0 && tval.tv_usec < 500) tval.tv_usec = 500; optlen = sizeof(struct timeval); optval = (char*)&tval; + } else if (optlen == sizeof(struct timeval)) { + WARN("SO_RCVTIMEO for %d bytes: assuming unixism\n", optlen); } else { - WARN("SO_RCVTIMEO for %d bytes is too small: ignored\n", optlen); + WARN("SO_RCVTIMEO for %d bytes is weird: ignored\n", optlen); close(fd); return 0; } } +#endif +#ifdef SO_SNDTIMEO + if (level == SOL_SOCKET && optname == SO_SNDTIMEO) { + if (optlen == sizeof(UINT32)) { + /* WinSock passes miliseconds instead of struct timeval */ + tval.tv_usec = *(PUINT32)optval % 1000; + tval.tv_sec = *(PUINT32)optval / 1000; + /* min of 500 milisec */ + if (tval.tv_sec == 0 && tval.tv_usec < 500) tval.tv_usec = 500; + optlen = sizeof(struct timeval); + optval = (char*)&tval; + } else if (optlen == sizeof(struct timeval)) { + WARN("SO_SNDTIMEO for %d bytes: assuming unixism\n", optlen); + } else { + WARN("SO_SNDTIMEO for %d bytes is weird: ignored\n", optlen); + close(fd); + return 0; + } + } +#endif } if(optname == SO_RCVBUF && *(int*)optval < 2048) { WARN("SO_RCVBF for %d bytes is too small: ignored\n", *(int*)optval );