--- librpcsecgss-0.14/src/clnt_tcp.c.orig 2008-03-27 16:39:16.000000000 -0700 +++ librpcsecgss-0.14/src/clnt_tcp.c 2008-03-27 16:38:07.000000000 -0700 @@ -60,6 +60,7 @@ static char *rcsid = "$OpenBSD: clnt_tcp #include #include #include +#include #define MCALL_MSG_SIZE 24 @@ -156,14 +157,57 @@ clnttcp_create(raddr, prog, vers, sockp, if (*sockp < 0) { *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); (void)bindresvport(*sockp, (struct sockaddr_in *)0); - if ((*sockp < 0) - || (connect(*sockp, (struct sockaddr *)raddr, - sizeof(*raddr)) < 0)) { + if (*sockp < 0) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; if (*sockp != -1) (void)close(*sockp); goto fooy; + } else if(connect(*sockp, (struct sockaddr *)raddr, + sizeof(*raddr)) < 0) { + struct pollfd sockpoll; + int sockoptval; + socklen_t socklen; + + /* + * Check to see if there was an interrupt and if so, poll until + * either an error occurs or the connect finishes. + */ + if ( errno != EINTR ) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + if (*sockp != -1) + (void)close(*sockp); + goto fooy; + } + sockpoll.fd = *sockp; + sockpoll.events = POLLOUT; + while ( poll (&sockpoll, 1, -1) == -1 ) { + if ( errno != EINTR ) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + if (*sockp != -1) + (void)close(*sockp); + goto fooy; + } + socklen = sizeof(sockoptval); + if ( getsockopt (*sockp, SOL_SOCKET, SO_ERROR, + &sockoptval, + &socklen) == -1 ) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + if (*sockp != -1) + (void)close(*sockp); + goto fooy; + } + if ( sockoptval != 0 ) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = sockoptval; + if (*sockp != -1) + (void)close(*sockp); + goto fooy; + } + } } ct->ct_closeit = TRUE; } else {