From c092d84ebb23c7377973f52e387c050faa1486f6 Mon Sep 17 00:00:00 2001 From: perry.werneck@gmail.com Date: Fri, 6 Dec 2013 10:04:51 +0000 Subject: [PATCH] Ainda implementando novo mecanismo de conexão sem threads e com mensagems melhores em caso de erro --- src/lib3270/connect.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ src/lib3270/iocalls.c | 101 +++++++++-------------------------------------------------------------------------------------------- src/lib3270/lib3270.cbp | 3 --- src/lib3270/testprogram.c | 7 +++++-- 4 files changed, 94 insertions(+), 109 deletions(-) diff --git a/src/lib3270/connect.c b/src/lib3270/connect.c index f39c45f..9ea422f 100644 --- a/src/lib3270/connect.c +++ b/src/lib3270/connect.c @@ -99,7 +99,7 @@ static void net_connected(H3270 *hSession) lib3270_popup_dialog( hSession, LIB3270_NOTIFY_ERROR, _( "Network error" ), - _( "Unable to connect to server." ), + _( "Unable to connect to host." ), #ifdef _WIN32 _( "%s"), lib3270_win32_strerror(err) #else @@ -176,6 +176,7 @@ static void net_connected(H3270 *hSession) LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc, LIB3270_CONNECT_OPTION opt) { int s; + int optval; struct addrinfo hints; struct addrinfo * result = NULL; struct addrinfo * rp = NULL; @@ -366,6 +367,39 @@ static void net_connected(H3270 *hSession) } } + optval = 1; + if (setsockopt(hSession->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&optval,sizeof(optval)) < 0) + { + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Connection error" ), + _( "setsockopt(SO_OOBINLINE) has failed" ), + "%s", + strerror(errno)); + SOCK_CLOSE(hSession); + } + + optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0; + if (setsockopt(hSession->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0) + { + char buffer[4096]; + snprintf(buffer,4095,N_( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" )); + + popup_a_sockerr(session, ); + + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Connection error" ), + buffer, + "%s", + strerror(errno)); + SOCK_CLOSE(hSession); + } + else + { + trace_dsn(hSession,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" ); + } + #else fcntl(hSession->sock, F_SETFL,fcntl(hSession->sock,F_GETFL,0)|O_NONBLOCK); @@ -387,6 +421,37 @@ static void net_connected(H3270 *hSession) } } + optval = 1; + if (setsockopt(hSession->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&optval,sizeof(optval)) < 0) + { + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Connection error" ), + _( "setsockopt(SO_OOBINLINE) has failed" ), + "%s", + strerror(errno)); + SOCK_CLOSE(hSession); + } + + optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0; + if (setsockopt(hSession->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0) + { + char buffer[4096]; + snprintf(buffer,4095,N_( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" )); + + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Connection error" ), + buffer, + "%s", + strerror(errno)); + SOCK_CLOSE(hSession); + } + else + { + trace_dsn(hSession,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" ); + } + #endif // WIN32 } @@ -395,13 +460,6 @@ static void net_connected(H3270 *hSession) // set options for inline out-of-band data and keepalives /* - int on = 1; - if (setsockopt(hSession->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&on,sizeof(on)) < 0) - { - popup_a_sockerr(hSession, N_( "setsockopt(%s)" ), "SO_OOBINLINE"); - SOCK_CLOSE(hSession); - } - #if defined(OMTU) else if (setsockopt(hSession->sock, SOL_SOCKET, SO_SNDBUF, (char *)&mtu,sizeof(mtu)) < 0) { @@ -433,7 +491,7 @@ static void net_connected(H3270 *hSession) if(opt&LIB3270_CONNECT_OPTION_WAIT) { - time_t end = time(0)+120; + time_t end = time(0)+120; while(time(0) < end) { @@ -442,18 +500,28 @@ static void net_connected(H3270 *hSession) switch(hSession->cstate) { case LIB3270_PENDING: + case LIB3270_CONNECTED_INITIAL: + case LIB3270_CONNECTED_ANSI: + case LIB3270_CONNECTED_3270: + case LIB3270_CONNECTED_INITIAL_E: + case LIB3270_CONNECTED_NVT: + case LIB3270_CONNECTED_SSCP: break; - case CONNECTED_INITIAL: - trace("%s: Connected, exiting wait",__FUNCTION__); + case LIB3270_NOT_CONNECTED: + return ENOTCONN; + + case LIB3270_CONNECTED_TN3270E: return 0; default: - trace("%s: State changed to %d",__FUNCTION__,hSession->cstate); + lib3270_write_log(hSession,"connect", "%s: State changed to unexpected state %d",__FUNCTION__,hSession->cstate); return -1; } } + + lib3270_disconnect(hSession); return ETIMEDOUT; } diff --git a/src/lib3270/iocalls.c b/src/lib3270/iocalls.c index 5dceec6..2360651 100644 --- a/src/lib3270/iocalls.c +++ b/src/lib3270/iocalls.c @@ -373,100 +373,14 @@ static int internal_event_dispatcher(H3270 *hSession, int block) retry: + inputs_changed = 0; + // If we've processed any input, then don't block again. if(processed_any) block = 0; events = 0; -/* -#if defined(_WIN32) - nha = 0; -#else - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); -#endif - - for (ip = inputs; ip != (input_t *)NULL; ip = ip->next) - { - if ((unsigned long)ip->condition & InputReadMask) - { -#if defined(_WIN32) - ha[nha++] = ip->source; -#else - FD_SET(ip->source, &rfds); -#endif - any_events = True; - } - if ((unsigned long)ip->condition & InputWriteMask) - { -#if defined(_WIN32) - ha[nha++] = ip->source; -#else - FD_SET(ip->source, &wfds); -#endif - any_events = True; - } -#if !defined(_WIN32) - if ((unsigned long)ip->condition & InputExceptMask) - { - FD_SET(ip->source, &xfds); - any_events = True; - } -#endif - } - - if (block) - { - if (timeouts != TN) - { -#if defined(_WIN32) - ms_ts(&now); - if (now > timeouts->ts) - tmo = 0; - else - tmo = timeouts->ts - now; -#else - (void) gettimeofday(&now, (void *)NULL); - twait.tv_sec = timeouts->tv.tv_sec - now.tv_sec; - twait.tv_usec = timeouts->tv.tv_usec - now.tv_usec; - if (twait.tv_usec < 0L) { - twait.tv_sec--; - twait.tv_usec += MILLION; - } - if (twait.tv_sec < 0L) - twait.tv_sec = twait.tv_usec = 0L; - tp = &twait; -#endif - any_events = True; - } - else - { - // Block for 1 second (at maximal) -#if defined(_WIN32) - tmo = 1; -#else - twait.tv_sec = 1; - twait.tv_usec = 0L; - tp = &twait; -#endif - } - } - else - { -#if defined(_WIN32) - tmo = 1; -#else - twait.tv_sec = twait.tv_usec = 0L; - tp = &twait; -#endif - } - - if (!any_events) - return processed_any; -*/ - #if defined(_WIN32) for (ip = inputs; ip != (input_t *)NULL; ip = ip->next) @@ -589,7 +503,8 @@ retry: } else { - twait.tv_sec = twait.tv_usec = 0L; + twait.tv_sec = 1; + twait.tv_usec = 0L; tp = &twait; if(!events) @@ -597,6 +512,7 @@ retry: } ns = select(FD_SETSIZE, &rfds, &wfds, &xfds, tp); + if (ns < 0 && errno != EINTR) { lib3270_popup_dialog( hSession, @@ -639,7 +555,8 @@ retry: #endif // See what's expired. - if (timeouts != TN) { + if (timeouts != TN) + { #if defined(_WIN32) ms_ts(&now); #else @@ -649,11 +566,11 @@ retry: while ((t = timeouts) != TN) { #if defined(_WIN32) - if (t->ts <= now) { + if (t->ts <= now) #else if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec)) - { #endif + { timeouts = t->next; t->in_play = True; (*t->proc)(t->session); diff --git a/src/lib3270/lib3270.cbp b/src/lib3270/lib3270.cbp index 73ba00d..0088feb 100644 --- a/src/lib3270/lib3270.cbp +++ b/src/lib3270/lib3270.cbp @@ -96,9 +96,6 @@