diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /soxwrap/sconnect.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'soxwrap/sconnect.c')
| -rw-r--r-- | soxwrap/sconnect.c | 98 | 
1 files changed, 98 insertions, 0 deletions
| diff --git a/soxwrap/sconnect.c b/soxwrap/sconnect.c new file mode 100644 index 0000000..7d933bf --- /dev/null +++ b/soxwrap/sconnect.c @@ -0,0 +1,98 @@ +/* +** Copyright 2001 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#include	"sconnect.h" + +#if HAVE_UNISTD_H +#include	<unistd.h> +#endif +#if HAVE_FCNTL_H +#include	<fcntl.h> +#endif +#include	<stdio.h> +#include	<errno.h> +#include	<string.h> + +#include	"soxwrap.h" + + +int s_connect(int sockfd, const struct sockaddr *addr, size_t addr_s, +	      time_t connect_timeout) +{ +	fd_set fdr; +	struct timeval tv; +	int	rc; + +#ifdef SOL_KEEPALIVE +	setsockopt(sockfd, SOL_SOCKET, SOL_KEEPALIVE, +		   (const char *)&dummy, sizeof(dummy)); +#endif + +#ifdef  SOL_LINGER +        { +		struct linger l; + +                l.l_onoff=0; +                l.l_linger=0; + +                setsockopt(sockfd, SOL_SOCKET, SOL_LINGER, +			   (const char *)&l, sizeof(l)); +        } +#endif + +        /* +        ** If configuration says to use the kernel's timeout settings, +        ** just call connect, and be done with it. +        */ + +        if (connect_timeout == 0) +                return ( sox_connect(sockfd, addr, addr_s)); + +        /* Asynchronous connect with timeout. */ + +        if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)     return (-1); + +        if ( sox_connect(sockfd, addr, addr_s) == 0) +        { +                /* That was easy, we're done. */ + +                if (fcntl(sockfd, F_SETFL, 0) < 0)      return (-1); +                return (0); +        } +        else +                if (errno != EINPROGRESS) return (-1); + +	/* Wait for the connection to go through, until the timeout expires */ + +        FD_ZERO(&fdr); +        FD_SET(sockfd, &fdr); +        tv.tv_sec=connect_timeout; +        tv.tv_usec=0; + +        rc=sox_select(sockfd+1, 0, &fdr, 0, &tv); +        if (rc < 0)     return (-1); + +        if (!FD_ISSET(sockfd, &fdr)) +        { +                errno=ETIMEDOUT; +                return (-1); +        } + +	{ +		int     gserr; +		socklen_t gslen = sizeof(gserr); + +		if (sox_getsockopt(sockfd, SOL_SOCKET, +				   SO_ERROR, +				   (char *)&gserr, &gslen)==0) +		{ +			if (gserr == 0) +				return 0; + +			errno=gserr; +		} +	} +	return (-1); +} | 
