Index: ossp-pkg/l2/l2_ut_sa.ac RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.ac,v rcsdiff -q -kk '-r1.8' '-r1.9' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.ac,v' 2>/dev/null --- l2_ut_sa.ac 2004/03/26 17:14:48 1.8 +++ l2_ut_sa.ac 2004/04/21 12:02:12 1.9 @@ -1,8 +1,8 @@ dnl ## dnl ## OSSP sa - Socket Abstraction -dnl ## Copyright (c) 2001-2003 Ralf S. Engelschall -dnl ## Copyright (c) 2001-2003 The OSSP Project -dnl ## Copyright (c) 2001-2003 Cable & Wireless Deutschland +dnl ## Copyright (c) 2001-2004 Ralf S. Engelschall +dnl ## Copyright (c) 2001-2004 The OSSP Project +dnl ## Copyright (c) 2001-2004 Cable & Wireless dnl ## dnl ## This file is part of OSSP sa, a socket abstraction library which dnl ## can be found at http://www.ossp.org/pkg/lib/sa/. Index: ossp-pkg/l2/l2_ut_sa.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.c,v rcsdiff -q -kk '-r1.24' '-r1.25' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.c,v' 2>/dev/null --- l2_ut_sa.c 2004/04/02 12:27:32 1.24 +++ l2_ut_sa.c 2004/04/21 12:02:12 1.25 @@ -1,8 +1,8 @@ /* ** OSSP sa - Socket Abstraction -** Copyright (c) 2001-2003 Ralf S. Engelschall -** Copyright (c) 2001-2003 The OSSP Project -** Copyright (c) 2001-2003 Cable & Wireless Deutschland +** Copyright (c) 2001-2004 Ralf S. Engelschall +** Copyright (c) 2001-2004 The OSSP Project +** Copyright (c) 2001-2004 Cable & Wireless ** ** This file is part of OSSP sa, a socket abstraction library which ** can be found at http://www.ossp.org/pkg/lib/sa/. @@ -1452,6 +1452,7 @@ fd_set rset, wset; socklen_t len; sa_rc_t rv; + struct timeval *tv; /* argument sanity check(s) */ if (sa == NULL || raddr == NULL) @@ -1466,72 +1467,88 @@ if ((rv = sa_socket_init(sa, raddr->nFamily)) != SA_OK) return SA_RC(rv); + /* prepare return code decision */ rv = SA_OK; - if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) { - /* standard/non-timeout-aware connect operation */ - if (SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf) < 0) - rv = SA_ERR_SYS; - } - else { - /* emulated/timeout-aware connect operation */ - error = 0; + error = 0; - /* temporarily switch underlying socket to non-blocking mode */ + /* temporarily switch underlying socket to non-blocking mode + (necessary under timeout-aware operation only) */ + flags = 0; + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) { flags = fcntl(sa->fdSocket, F_GETFL, 0); (void)fcntl(sa->fdSocket, F_SETFL, flags|O_NONBLOCK); + } - /* perform the connect operation */ - if ((n = SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf)) < 0) { - if (errno != EINPROGRESS) { - error = errno; - goto done; - } - } - - /* ok if connect completed immediately */ - if (n == 0) - goto done; - - /* wait for read or write possibility */ - FD_ZERO(&rset); - FD_ZERO(&wset); - FD_SET(sa->fdSocket, &rset); - FD_SET(sa->fdSocket, &wset); - do { - n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &rset, &wset, NULL, - &sa->tvTimeout[SA_TIMEOUT_CONNECT]); - } while (n == -1 && errno == EINTR); - - /* decide on return semantic */ - if (n < 0) { + /* perform the connect operation */ + if ((n = SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf)) < 0) { + if (errno != EINTR && errno != EINPROGRESS) { + /* we have to perform the following post-processing under + EINPROGRESS anway, but actually also for EINTR according + to Unix Network Programming, volume 1, section 5.9, W. + Richard Stevens: "What we are doing [] is restarting + the interrupted system call ourself. This is fine for + accept, along with the functions such as read, write, + select and open. But there is one function that we cannot + restart ourself: connect. If this function returns EINTR, + we cannot call it again, as doing so will return an + immediate error. When connect is interrupted by a caught + signal and is not automatically restarted, we must call + select to wait for the connection to complete, as we + describe in section 15.3." */ error = errno; goto done; } - else if (n == 0) { - (void)close(sa->fdSocket); /* stop TCP three-way handshake */ - sa->fdSocket = -1; - rv = SA_ERR_TMT; - goto done; - } - - /* fetch pending error */ - len = (socklen_t)sizeof(error); - if (getsockopt(sa->fdSocket, SOL_SOCKET, SO_ERROR, (void *)&error, &len) < 0) - error = errno; - - done: + } - /* reset socket flags */ + /* ok if connect completed immediately */ + if (n == 0) + goto done; + + /* wait for read or write possibility */ + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_SET(sa->fdSocket, &rset); + FD_SET(sa->fdSocket, &wset); + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) + tv = &sa->tvTimeout[SA_TIMEOUT_CONNECT]; + else + tv = NULL; + do { + n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &rset, &wset, NULL, tv); + } while (n == -1 && errno == EINTR); + + /* decide on return semantic */ + if (n < 0) { + error = errno; + goto done; + } + else if (n == 0) { + (void)close(sa->fdSocket); /* stop TCP three-way handshake */ + sa->fdSocket = -1; + rv = SA_ERR_TMT; + goto done; + } + + /* fetch pending error */ + len = (socklen_t)sizeof(error); + if (getsockopt(sa->fdSocket, SOL_SOCKET, SO_ERROR, (void *)&error, &len) < 0) + error = errno; + + done: + + /* reset socket flags + (necessary under timeout-aware operation only) */ + if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) (void)fcntl(sa->fdSocket, F_SETFL, flags); - /* optionally set errno */ - if (error != 0) { - (void)close(sa->fdSocket); /* just in case */ - sa->fdSocket = -1; - errno = error; - rv = SA_ERR_SYS; - } + /* optionally set errno */ + if (error != 0) { + (void)close(sa->fdSocket); /* just in case */ + sa->fdSocket = -1; + errno = error; + rv = SA_ERR_SYS; } + return SA_RC(rv); } Index: ossp-pkg/l2/l2_ut_sa.h RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.h,v rcsdiff -q -kk '-r1.20' '-r1.21' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.h,v' 2>/dev/null --- l2_ut_sa.h 2004/03/26 17:14:48 1.20 +++ l2_ut_sa.h 2004/04/21 12:02:12 1.21 @@ -1,8 +1,8 @@ /* ** OSSP sa - Socket Abstraction -** Copyright (c) 2001-2003 Ralf S. Engelschall -** Copyright (c) 2001-2003 The OSSP Project -** Copyright (c) 2001-2003 Cable & Wireless Deutschland +** Copyright (c) 2001-2004 Ralf S. Engelschall +** Copyright (c) 2001-2004 The OSSP Project +** Copyright (c) 2001-2004 Cable & Wireless ** ** This file is part of OSSP sa, a socket abstraction library which ** can be found at http://www.ossp.org/pkg/lib/sa/.