4 extern volatile Sjmp_buf gNetTimeoutJmp
;
5 extern volatile Sjmp_buf gPipeJmp
;
9 SConnect(int sfd
, const struct sockaddr_in
*const addr
, int tlen
)
13 vsio_sigproc_t sigalrm
;
15 if (SSetjmp(gNetTimeoutJmp
) != 0) {
17 (void) SSignal(SIGALRM
, (sio_sigproc_t
) sigalrm
);
22 sigalrm
= (vsio_sigproc_t
) SSignal(SIGALRM
, SIOHandler
);
23 alarm((unsigned int) tlen
);
27 result
= connect(sfd
, (struct sockaddr
*) addr
,
28 (int) sizeof(struct sockaddr_in
));
29 } while ((result
< 0) && (errno
== EINTR
));
32 (void) SSignal(SIGALRM
, (sio_sigproc_t
) sigalrm
);
34 #else /* NO_SIGNALS */
40 #if defined(WIN32) || defined(_WINDOWS)
51 result
= connect(sfd
, (struct sockaddr
*) addr
,
52 (int) sizeof(struct sockaddr_in
));
54 } while ((result
< 0) && (errno
== EINTR
));
60 if (ioctlsocket(sfd
, FIONBIO
, &opt
) != 0) {
65 if (fcntl(sfd
, F_GETFL
, &opt
) < 0) {
68 } else if (fcntl(sfd
, F_SETFL
, opt
| O_NONBLOCK
) < 0) {
75 result
= connect(sfd
, (struct sockaddr
*) addr
,
76 (int) sizeof(struct sockaddr_in
));
78 return 0; /* Already?!? */
81 #if defined(WIN32) || defined(_WINDOWS)
82 && ((wsaErrno
= WSAGetLastError()) != WSAEWOULDBLOCK
)
83 && (wsaErrno
!= WSAEINPROGRESS
)
85 && (errno
!= EWOULDBLOCK
) && (errno
!= EINPROGRESS
)
95 #if defined(WIN32) || defined(_WINDOWS)
103 result
= select(sfd
+ 1, NULL
, SELECT_TYPE_ARG234
&ss
, SELECT_TYPE_ARG234
&xx
, SELECT_TYPE_ARG5
&tv
);
107 } else if (result
== 0) {
111 /* Don't bother turning off FIONBIO */
112 return (kTimeoutErr
);
113 } else if (errno
!= EINTR
) {
114 /* Don't bother turning off FIONBIO */
120 /* Supposedly once the select() returns with a writable
121 * descriptor, it is connected and we don't need to
122 * recall connect(). When select() returns an exception,
123 * the connection failed -- we can get the connect error
124 * doing a write on the socket which will err out.
127 if (FD_ISSET(sfd
, &xx
)) {
128 #if defined(WIN32) || defined(_WINDOWS)
131 soerrsize
= sizeof(soerr
);
132 result
= getsockopt(sfd
, SOL_SOCKET
, SO_ERROR
, (char *) &soerr
, &soerrsize
);
133 if ((result
>= 0) && (soerr
!= 0)) {
137 (void) send(sfd
, "\0", 1, 0);
142 (void) send(sfd
, "\0", 1, 0);
150 #if defined(WIN32) || defined(_WINDOWS)
152 if (cErrno
== EINPROGRESS
) {
154 * [from Linux connect(2) page]
158 * The socket is non-blocking and the connection canĀ
159 * not be completed immediately. It is possible to
160 * select(2) or poll(2) for completion by selecting
161 * the socket for writing. After select indicates
162 * writability, use getsockopt(2) to read the
163 * SO_ERROR option at level SOL_SOCKET to determine
164 * whether connect completed successfully (SO_ERROR
165 * is zero) or unsuccessfully (SO_ERROR is one of the
166 * usual error codes listed above, explaining the
167 * reason for the failure).
170 optlen
= sizeof(optval
);
171 if (getsockopt(sfd
, SOL_SOCKET
, SO_ERROR
, &optval
, &optlen
) == 0) {
181 if (ioctlsocket(sfd
, FIONBIO
, &opt
) != 0) {
187 if (fcntl(sfd
, F_SETFL
, opt
) < 0) {
195 #endif /* NO_SIGNALS */