/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2005 The OpenLDAP Foundation.
* Portions Copyright 1999 Lars Uffmann.
* All rights reserved.
*
if( opt_tv != NULL ) timeout = TV2MILLISEC( &tv );
fd.fd = s;
- fd.events = POLLOUT;
+ fd.events = POLL_WRITE;
do {
fd.revents = 0;
if( rc == AC_SOCKET_ERROR ) return rc;
- if( fd.revents & POLLOUT ) {
+ if( fd.revents & POLL_WRITE ) {
if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
return ( 0 );
#ifdef HAVE_WINSOCK
fd_set efds;
#endif
+
+#ifdef FD_SETSIZE
+ if ( s >= FD_SETSIZE ) {
+ rc = AC_SOCKET_ERROR;
+ tcp_close( s );
+ ldap_pvt_set_errno( EMFILE );
+ return rc;
+ }
+#endif
FD_ZERO(&wfds);
FD_SET(s, &wfds );
ldap_pvt_inet_aton( const char *host, struct in_addr *in)
{
unsigned long u = inet_addr( host );
- if ( u != 0xffffffff || u != (unsigned long) -1 ) {
- in->s_addr = u;
- return 1;
- }
- return 0;
+
+#ifdef INADDR_NONE
+ if ( u == INADDR_NONE ) return 0;
+#endif
+ if ( u == 0xffffffffUL || u == (unsigned long) -1L ) return 0;
+
+ in->s_addr = u;
+ return 1;
}
#endif
#endif
+struct selectinfo {
#ifdef HAVE_POLL
-/* for UNIX poll(2) */
- /* ??? */
+ /* for UNIX poll(2) */
+ int si_maxfd;
+ struct pollfd si_fds[FD_SETSIZE];
#else
-/* for UNIX select(2) */
-struct selectinfo {
+ /* for UNIX select(2) */
fd_set si_readfds;
fd_set si_writefds;
fd_set si_use_readfds;
fd_set si_use_writefds;
-};
#endif
+};
void
ldap_mark_select_write( LDAP *ld, Sockbuf *sb )
sip = (struct selectinfo *)ld->ld_selectinfo;
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+
+#ifdef HAVE_POLL
+ /* for UNIX poll(2) */
+ {
+ int empty=-1;
+ int i;
+ for(i=0; i < sip->si_maxfd; i++) {
+ if( sip->si_fds[i].fd == sd ) {
+ sip->si_fds[i].events |= POLL_WRITE;
+ return;
+ }
+ if( empty==-1 && sip->si_fds[i].fd == -1 ) {
+ empty=i;
+ }
+ }
+
+ if( empty == -1 ) {
+ if( sip->si_maxfd >= FD_SETSIZE ) {
+ /* FIXME */
+ return;
+ }
+ empty = sip->si_maxfd++;
+ }
+
+ sip->si_fds[empty].fd = sd;
+ sip->si_fds[empty].events = POLL_WRITE;
+ }
+#else
+ /* for UNIX select(2) */
if ( !FD_ISSET( sd, &sip->si_writefds )) {
FD_SET( sd, &sip->si_writefds );
}
+#endif
}
sip = (struct selectinfo *)ld->ld_selectinfo;
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+
+#ifdef HAVE_POLL
+ /* for UNIX poll(2) */
+ {
+ int empty=-1;
+ int i;
+ for(i=0; i < sip->si_maxfd; i++) {
+ if( sip->si_fds[i].fd == sd ) {
+ sip->si_fds[i].events |= POLL_READ;
+ return;
+ }
+ if( empty==-1 && sip->si_fds[i].fd == -1 ) {
+ empty=i;
+ }
+ }
+
+ if( empty == -1 ) {
+ if( sip->si_maxfd >= FD_SETSIZE ) {
+ /* FIXME */
+ return;
+ }
+ empty = sip->si_maxfd++;
+ }
+
+ sip->si_fds[empty].fd = sd;
+ sip->si_fds[empty].events = POLL_READ;
+ }
+#else
+ /* for UNIX select(2) */
if ( !FD_ISSET( sd, &sip->si_readfds )) {
FD_SET( sd, &sip->si_readfds );
}
+#endif
}
sip = (struct selectinfo *)ld->ld_selectinfo;
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+
+#ifdef HAVE_POLL
+ /* for UNIX poll(2) */
+ {
+ int i;
+ for(i=0; i < sip->si_maxfd; i++) {
+ if( sip->si_fds[i].fd == sd ) {
+ sip->si_fds[i].fd = -1;
+ }
+ }
+ }
+#else
+ /* for UNIX select(2) */
FD_CLR( sd, &sip->si_writefds );
FD_CLR( sd, &sip->si_readfds );
+#endif
}
sip = (struct selectinfo *)ld->ld_selectinfo;
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+
+#ifdef HAVE_POLL
+ /* for UNIX poll(2) */
+ {
+ int i;
+ for(i=0; i < sip->si_maxfd; i++) {
+ if( sip->si_fds[i].fd == sd ) {
+ return sip->si_fds[i].revents & POLL_WRITE;
+ }
+ }
+
+ return 0;
+ }
+#else
+ /* for UNIX select(2) */
return( FD_ISSET( sd, &sip->si_use_writefds ));
+#endif
}
sip = (struct selectinfo *)ld->ld_selectinfo;
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+
+#ifdef HAVE_POLL
+ /* for UNIX poll(2) */
+ {
+ int i;
+ for(i=0; i < sip->si_maxfd; i++) {
+ if( sip->si_fds[i].fd == sd ) {
+ return sip->si_fds[i].revents & POLL_READ;
+ }
+ }
+
+ return 0;
+ }
+#else
+ /* for UNIX select(2) */
return( FD_ISSET( sd, &sip->si_use_readfds ));
+#endif
}
{
struct selectinfo *sip;
- if (( sip = (struct selectinfo *)LDAP_CALLOC( 1,
- sizeof( struct selectinfo ))) != NULL ) {
- FD_ZERO( &sip->si_readfds );
- FD_ZERO( &sip->si_writefds );
- }
+ sip = (struct selectinfo *)LDAP_CALLOC( 1, sizeof( struct selectinfo ));
+
+ if ( sip == NULL ) return NULL;
+
+#ifdef HAVE_POLL
+ /* for UNIX poll(2) */
+ /* sip->si_maxfd=0 */
+#else
+ /* for UNIX select(2) */
+ FD_ZERO( &sip->si_readfds );
+ FD_ZERO( &sip->si_writefds );
+#endif
return( (void *)sip );
}
#ifdef FD_SETSIZE
if( tblsize > FD_SETSIZE ) tblsize = FD_SETSIZE;
-#endif /* FD_SETSIZE*/
+#endif /* FD_SETSIZE */
ldap_int_tblsize = tblsize;
}
int
ldap_int_select( LDAP *ld, struct timeval *timeout )
{
+ int rc;
struct selectinfo *sip;
-#ifdef NEW_LOGGING
- LDAP_LOG ( CONNECTION, ENTRY, "ldap_int_select\n", 0, 0, 0 );
-#else
Debug( LDAP_DEBUG_TRACE, "ldap_int_select\n", 0, 0, 0 );
-#endif
#ifndef HAVE_POLL
if ( ldap_int_tblsize == 0 ) ldap_int_ip_init();
#endif
sip = (struct selectinfo *)ld->ld_selectinfo;
+
+#ifdef HAVE_POLL
+ {
+ int to = timeout ? TV2MILLISEC( timeout ) : INFTIM;
+ rc = poll( sip->si_fds, sip->si_maxfd, to );
+ }
+#else
sip->si_use_readfds = sip->si_readfds;
sip->si_use_writefds = sip->si_writefds;
-#ifdef HAVE_POLL
- assert(0);
- return -1;
-#else
- return( select( ldap_int_tblsize,
+ rc = select( ldap_int_tblsize,
&sip->si_use_readfds, &sip->si_use_writefds,
- NULL, timeout ));
+ NULL, timeout );
#endif
+
+ return rc;
}