# HG changeset patch # User Jason Rumney # Date 1020458403 0 # Node ID c9aa2603d1f70dff8e8f55360bd207d196ac70a7 # Parent 3e9cb1567659e2779c3e671b50c0fd8d89b4ddb6 (sys_getpeername, fcntl): New functions. (_sys_read_ahead): Temporarily block on non-blocking sockets. diff -r 3e9cb1567659 -r c9aa2603d1f7 src/w32.c --- a/src/w32.c Fri May 03 20:35:38 2002 +0000 +++ b/src/w32.c Fri May 03 20:40:03 2002 +0000 @@ -84,6 +84,7 @@ #undef gethostname #undef gethostbyname #undef getservbyname +#undef getpeername #undef shutdown #undef setsockopt #undef listen @@ -2424,7 +2425,7 @@ int (PASCAL *pfn_gethostname) (char * name, int namelen); struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto); - +int (PASCAL *pfn_getpeername) (SOCKET s, struct sockaddr *addr, int * namelen); int (PASCAL *pfn_setsockopt) (SOCKET s, int level, int optname, const char * optval, int optlen); int (PASCAL *pfn_listen) (SOCKET s, int backlog); @@ -2504,6 +2505,7 @@ LOAD_PROC( gethostname ); LOAD_PROC( gethostbyname ); LOAD_PROC( getservbyname ); + LOAD_PROC( getpeername ); LOAD_PROC( WSACleanup ); LOAD_PROC( setsockopt ); LOAD_PROC( listen ); @@ -2923,6 +2925,28 @@ } int +sys_getpeername (int s, struct sockaddr *addr, int * namelen) +{ + if (winsock_lib == NULL) + { + h_errno = ENETDOWN; + return SOCKET_ERROR; + } + + check_errno (); + if (fd_info[s].flags & FILE_SOCKET) + { + int rc = pfn_getpeername (SOCK_HANDLE (s), addr, namelen); + if (rc == SOCKET_ERROR) + set_errno (); + return rc; + } + h_errno = ENOTSOCK; + return SOCKET_ERROR; +} + + +int sys_shutdown (int s, int how) { if (winsock_lib == NULL) @@ -3074,6 +3098,40 @@ return SOCKET_ERROR; } +/* Windows does not have an fcntl function. Provide an implementation + solely for making sockets non-blocking. */ +int +fcntl (int s, int cmd, int options) +{ + if (winsock_lib == NULL) + { + h_errno = ENETDOWN; + return -1; + } + + check_errno (); + if (fd_info[s].flags & FILE_SOCKET) + { + if (cmd == F_SETFL && options == O_NDELAY) + { + unsigned long nblock = 1; + int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock); + if (rc == SOCKET_ERROR) + set_errno(); + /* Keep track of the fact that we set this to non-blocking. */ + fd_info[s].flags |= FILE_NDELAY; + return rc; + } + else + { + h_errno = EINVAL; + return SOCKET_ERROR; + } + } + h_errno = ENOTSOCK; + return SOCKET_ERROR; +} + #endif /* HAVE_SOCKETS */ @@ -3257,7 +3315,20 @@ } #ifdef HAVE_SOCKETS else if (fd_info[fd].flags & FILE_SOCKET) - rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0); + { + unsigned long nblock = 0; + /* We always want this to block, so temporarily disable NDELAY. */ + if (fd_info[fd].flags & FILE_NDELAY) + pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock); + + rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0); + + if (fd_info[fd].flags & FILE_NDELAY) + { + nblock = 1; + pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock); + } + } #endif if (rc == sizeof (char))