From ecebe3d051ea1e28155950a9afd925d109f02f58 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 9 Jul 2004 19:29:46 +0000 Subject: [PATCH] basic poll(2) implementation for connect(2) (needs work) Need to deal with selectinfo... --- libraries/libldap/ldap-int.h | 3 ++ libraries/libldap/os-ip.c | 102 +++++++++++++++++++++-------------- libraries/libldap/os-local.c | 34 ++++++++++-- 3 files changed, 94 insertions(+), 45 deletions(-) diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 73b0aa999d..844fd4cdc2 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -42,6 +42,9 @@ #define SASL_MIN_BUFF_SIZE 4096 #endif +#undef TV2MILLISEC +#define TV2MILLISEC(tv) (((tv)->sec * 1000) + ((tv)->tv_usec/1000)) + /* * Support needed if the library is running in the kernel */ diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c index 7399fe5bd2..45b1f9500d 100644 --- a/libraries/libldap/os-ip.c +++ b/libraries/libldap/os-ip.c @@ -210,12 +210,6 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, { int rc; struct timeval tv, *opt_tv=NULL; -#ifndef HAVE_POLL - fd_set wfds, *z=NULL; -#ifdef HAVE_WINSOCK - fd_set efds; -#endif -#endif #ifdef LDAP_CONNECTIONLESS /* We could do a connect() but that would interfere with @@ -259,60 +253,86 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, #endif #ifdef HAVE_POLL - assert(0); + { + struct pollfd fd; + int timeout = INFTIM; + + if( opt_tv != NULL ) timeout = TV2MILLISEC( &tv ); + + fd.fd = s; + fd.events = POLLOUT; + + do { + fd.revents = 0; + rc = poll( &fd, 1, timeout ); + } while( rc == AC_SOCKET_ERROR && errno == EINTR && + LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART )); + + if( rc == AC_SOCKET_ERROR ) return rc; + + if( fd.revents & POLLOUT ) { + if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1; + if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1; + return ( 0 ); + } + } #else - FD_ZERO(&wfds); - FD_SET(s, &wfds ); + { + fd_set wfds, *z=NULL; +#ifdef HAVE_WINSOCK + fd_set efds; +#endif + FD_ZERO(&wfds); + FD_SET(s, &wfds ); #ifdef HAVE_WINSOCK - FD_ZERO(&efds); - FD_SET(s, &efds ); + FD_ZERO(&efds); + FD_SET(s, &efds ); #endif - do { - rc = select(ldap_int_tblsize, z, &wfds, + do { + rc = select(ldap_int_tblsize, z, &wfds, #ifdef HAVE_WINSOCK - &efds, + &efds, #else - z, + z, #endif - opt_tv ? &tv : NULL); - } while( rc == AC_SOCKET_ERROR && errno == EINTR && - LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART )); + opt_tv ? &tv : NULL); + } while( rc == AC_SOCKET_ERROR && errno == EINTR && + LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART )); - if( rc == AC_SOCKET_ERROR ) return rc; + if( rc == AC_SOCKET_ERROR ) return rc; #ifdef HAVE_WINSOCK - /* This means the connection failed */ - if ( FD_ISSET(s, &efds) ) { - int so_errno; - int dummy = sizeof(so_errno); - if ( getsockopt( s, SOL_SOCKET, SO_ERROR, - (char *) &so_errno, &dummy ) == AC_SOCKET_ERROR || !so_errno ) - { - /* impossible */ - so_errno = WSAGetLastError(); - } - ldap_pvt_set_errno(so_errno); - osip_debug(ld, "ldap_pvt_connect: error on socket %d: " - "errno: %d (%s)\n", s, errno, sock_errstr(errno)); - return -1; - } + /* This means the connection failed */ + if ( FD_ISSET(s, &efds) ) { + int so_errno; + int dummy = sizeof(so_errno); + if ( getsockopt( s, SOL_SOCKET, SO_ERROR, + (char *) &so_errno, &dummy ) == AC_SOCKET_ERROR || !so_errno ) + { + /* impossible */ + so_errno = WSAGetLastError(); + } + ldap_pvt_set_errno(so_errno); + osip_debug(ld, "ldap_pvt_connect: error on socket %d: " + "errno: %d (%s)\n", s, errno, sock_errstr(errno)); + return -1; + } #endif - if ( FD_ISSET(s, &wfds) ) { + if ( FD_ISSET(s, &wfds) ) { #ifndef HAVE_WINSOCK - if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) - return ( -1 ); + if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1; #endif - if ( ldap_pvt_ndelay_off(ld, s) == -1 ) - return ( -1 ); - return ( 0 ); + if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1; + return 0; + } } #endif osip_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0); ldap_pvt_set_errno( ETIMEDOUT ); - return ( -1 ); + return -1; } #ifndef HAVE_INET_ATON diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c index 43d55f513d..ee047dc4c2 100644 --- a/libraries/libldap/os-local.c +++ b/libraries/libldap/os-local.c @@ -216,14 +216,40 @@ sendcred: #endif #ifdef HAVE_POLL - assert(0); + { + struct pollfd fd; + int timeout = INFTIM; + + if( opt_tv != NULL ) timeout = TV2MILLISEC( &tv ); + + fd.fd = s; + fd.events = POLLOUT; + + do { + fd.revents = 0; + rc = poll( &fd, 1, timeout ); + } while( rc == AC_SOCKET_ERROR && errno == EINTR && + LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART )); + + if( rc == AC_SOCKET_ERROR ) return rc; + + if( fd.revents & POLLOUT ) { + if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1; + if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1; +#ifdef DO_SENDMSG + goto sendcred; +#else + return ( 0 ); +#endif + } + } #else { - fd_set wfds, *z=NULL; - FD_ZERO(&wfds); - FD_SET(s, &wfds ); + fd_set wfds, *z=NULL; do { + FD_ZERO(&wfds); + FD_SET(s, &wfds ); rc = select( ldap_int_tblsize, z, &wfds, z, opt_tv ? &tv : NULL ); } while( rc == AC_SOCKET_ERROR && errno == EINTR && LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART )); -- 2.39.5