Commit ced7f3f3be5b7082fee977910c4775966d3368bc

Authored by perry.werneck@gmail.com
1 parent 2083e868

Em windows existem momentos em que ele trava durante a conexão, movi o connect()…

… para um thread separada tentando evitar o problema
@@ -979,10 +979,12 @@ LIB3270_EXPORT int lib3270_call_thread(int(*callback)(H3270 *h, void *), H3270 * @@ -979,10 +979,12 @@ LIB3270_EXPORT int lib3270_call_thread(int(*callback)(H3270 *h, void *), H3270 *
979 if(h->set_timer) 979 if(h->set_timer)
980 h->set_timer(h,1); 980 h->set_timer(h,1);
981 981
  982 + lib3270_main_iterate(0);
982 if(callbacks->callthread) 983 if(callbacks->callthread)
983 rc = callbacks->callthread(callback,h,parm); 984 rc = callbacks->callthread(callback,h,parm);
984 else 985 else
985 rc = callback(h,parm); 986 rc = callback(h,parm);
  987 + lib3270_main_iterate(0);
986 988
987 if(h->set_timer) 989 if(h->set_timer)
988 h->set_timer(h,0); 990 h->set_timer(h,0);
@@ -386,7 +386,7 @@ @@ -386,7 +386,7 @@
386 LOCAL_EXTERN SCRIPT_STATE status_script(SCRIPT_STATE state); 386 LOCAL_EXTERN SCRIPT_STATE status_script(SCRIPT_STATE state);
387 387
388 #define Toggled(ix) lib3270_get_toggle(NULL,ix) 388 #define Toggled(ix) lib3270_get_toggle(NULL,ix)
389 - #define CallAndWait(c,h,p) lib3270_call_thread(c,h,p) 389 +// #define CallAndWait(c,h,p) lib3270_call_thread(c,h,p)
390 390
391 // #define RunPendingEvents(x) lib3270_main_iterate(x) 391 // #define RunPendingEvents(x) lib3270_main_iterate(x)
392 // #define Wait(s) lib3270_wait(x) 392 // #define Wait(s) lib3270_wait(x)
@@ -107,6 +107,10 @@ static void update_selection(H3270 *session, int start, int end) @@ -107,6 +107,10 @@ static void update_selection(H3270 *session, int start, int end)
107 { 107 {
108 } 108 }
109 109
  110 +static void *cursor(H3270 *session, LIB3270_CURSOR id)
  111 +{
  112 +}
  113 +
110 static void lib3270_session_init(H3270 *hSession, const char *model) 114 static void lib3270_session_init(H3270 *hSession, const char *model)
111 { 115 {
112 int ovc, ovr; 116 int ovc, ovr;
@@ -131,6 +135,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model) @@ -131,6 +135,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model)
131 hSession->resume = screen_disp; 135 hSession->resume = screen_disp;
132 hSession->update_oia = update_oia; 136 hSession->update_oia = update_oia;
133 hSession->update_selection = update_selection; 137 hSession->update_selection = update_selection;
  138 + hSession->cursor = cursor;
134 139
135 hSession->sock = -1; 140 hSession->sock = -1;
136 hSession->model_num = -1; 141 hSession->model_num = -1;
@@ -688,10 +688,7 @@ proxy_socks5(int fd, char *host, unsigned short port, int force_d) @@ -688,10 +688,7 @@ proxy_socks5(int fd, char *host, unsigned short port, int force_d)
688 int rv; 688 int rv;
689 689
690 /* Resolve the hostname. */ 690 /* Resolve the hostname. */
691 - status_resolving(&h3270,1);  
692 - rv = resolve_host_and_port(host, CN, &rport, &ha.sa, &ha_len,  
693 - errmsg, sizeof(errmsg));  
694 - status_resolving(&h3270,0); 691 + rv = resolve_host_and_port(&h3270,host, CN, &rport, &ha.sa, &ha_len,errmsg, sizeof(errmsg));
695 if (rv == -2) 692 if (rv == -2)
696 use_name = 1; 693 use_name = 1;
697 else if (rv < 0) { 694 else if (rv < 0) {
@@ -86,6 +86,8 @@ struct parms @@ -86,6 +86,8 @@ struct parms
86 */ 86 */
87 static int cresolve_host_and_port(H3270 *h, struct parms *p) 87 static int cresolve_host_and_port(H3270 *h, struct parms *p)
88 { 88 {
  89 +#warning Should use configure to detect getaddrinfo and use it if available.
  90 +
89 #ifdef AF_INET6 91 #ifdef AF_INET6
90 92
91 struct addrinfo hints, *res; 93 struct addrinfo hints, *res;
@@ -126,6 +128,7 @@ static int cresolve_host_and_port(H3270 *h, struct parms *p) @@ -126,6 +128,7 @@ static int cresolve_host_and_port(H3270 *h, struct parms *p)
126 128
127 (void) memcpy(p->sa, res->ai_addr, res->ai_addrlen); 129 (void) memcpy(p->sa, res->ai_addr, res->ai_addrlen);
128 *p->sa_len = res->ai_addrlen; 130 *p->sa_len = res->ai_addrlen;
  131 +
129 freeaddrinfo(res); 132 freeaddrinfo(res);
130 133
131 #else /*][*/ 134 #else /*][*/
@@ -179,16 +182,23 @@ static int cresolve_host_and_port(H3270 *h, struct parms *p) @@ -179,16 +182,23 @@ static int cresolve_host_and_port(H3270 *h, struct parms *p)
179 return 0; 182 return 0;
180 } 183 }
181 184
182 -int resolve_host_and_port(const char *host, char *portname, unsigned short *pport,struct sockaddr *sa, socklen_t *sa_len, char *errmsg, int em_len) 185 +int resolve_host_and_port(H3270 *hSession, const char *host, char *portname, unsigned short *pport,struct sockaddr *sa, socklen_t *sa_len, char *errmsg, int em_len)
183 { 186 {
184 - int rc;  
185 - struct parms p = { sizeof(struct parms), host, portname, pport, sa, sa_len, errmsg, em_len }; 187 + int rc;
  188 + LIB3270_STATUS saved_status = hSession->oia_status;
  189 + struct parms p = { sizeof(struct parms), host, portname, pport, sa, sa_len, errmsg, em_len };
  190 +
  191 + trace("Calling resolver for %s", p.host);
  192 +
  193 + status_changed(hSession,LIB3270_STATUS_RESOLVING);
  194 + hSession->cursor(hSession,CURSOR_MODE_LOCKED);
186 195
187 - Trace("Calling resolver for %s", p.host); 196 + rc = lib3270_call_thread((int (*)(H3270 *, void *)) cresolve_host_and_port,hSession,&p);
188 197
189 - rc = CallAndWait((int (*)(H3270 *, void *)) cresolve_host_and_port,&h3270,&p); 198 + hSession->cursor(hSession,CURSOR_MODE_NORMAL);
  199 + status_changed(hSession,saved_status);
190 200
191 - Trace("Calling resolver for %s exits with %d", p.host, rc); 201 + trace("Calling resolver for %s exits with %d", p.host, rc);
192 202
193 return rc; 203 return rc;
194 204
@@ -17,6 +17,6 @@ @@ -17,6 +17,6 @@
17 * Hostname resolution. 17 * Hostname resolution.
18 */ 18 */
19 19
20 -LIB3270_INTERNAL int resolve_host_and_port(const char *host, char *portname, unsigned short *pport,struct sockaddr *sa, socklen_t *sa_len, char *errmsg, int em_size); 20 +LIB3270_INTERNAL int resolve_host_and_port(H3270 *session, const char *host, char *portname, unsigned short *pport,struct sockaddr *sa, socklen_t *sa_len, char *errmsg, int em_size);
21 21
22 22
@@ -443,14 +443,6 @@ void status_oerr(H3270 *session, int error_type) @@ -443,14 +443,6 @@ void status_oerr(H3270 *session, int error_type)
443 443
444 } 444 }
445 445
446 -void status_resolving(H3270 *session, Boolean on)  
447 -{  
448 - if(session->cursor)  
449 - session->cursor(session, on ? CURSOR_MODE_LOCKED : CURSOR_MODE_NORMAL);  
450 -  
451 - status_changed(session, on ? LIB3270_STATUS_RESOLVING : LIB3270_STATUS_BLANK);  
452 -}  
453 -  
454 void status_connecting(H3270 *session, Boolean on) 446 void status_connecting(H3270 *session, Boolean on)
455 { 447 {
456 if(session->cursor) 448 if(session->cursor)
@@ -21,5 +21,5 @@ LIB3270_INTERNAL int *char_width, *char_height; @@ -21,5 +21,5 @@ LIB3270_INTERNAL int *char_width, *char_height;
21 // LIB3270_INTERNAL void screen_update(H3270 *session, int bstart, int bend); 21 // LIB3270_INTERNAL void screen_update(H3270 *session, int bstart, int bend);
22 22
23 LIB3270_INTERNAL void status_connecting(H3270 *session, Boolean on); 23 LIB3270_INTERNAL void status_connecting(H3270 *session, Boolean on);
24 -LIB3270_INTERNAL void status_resolving(H3270 *session, Boolean on); 24 +// LIB3270_INTERNAL void status_resolving(H3270 *session, Boolean on);
25 25
@@ -417,6 +417,40 @@ void popup_a_sockerr(H3270 *session, char *fmt, ...) @@ -417,6 +417,40 @@ void popup_a_sockerr(H3270 *session, char *fmt, ...)
417 417
418 } 418 }
419 419
  420 +#pragma pack(1)
  421 +struct connect_parm
  422 +{
  423 + unsigned short sz;
  424 + int sockfd;
  425 + const struct sockaddr * addr;
  426 + socklen_t addrlen;
  427 + int err;
  428 +};
  429 +#pragma pack()
  430 +
  431 +static int do_connect_sock(H3270 *h, struct connect_parm *p)
  432 +{
  433 +
  434 + if(connect(p->sockfd, p->addr, p->addrlen) == -1)
  435 + p->err = socket_errno();
  436 + else
  437 + p->err = 0;
  438 +
  439 + return 0;
  440 +}
  441 +
  442 +static int connect_sock(H3270 *hSession, int sockfd, const struct sockaddr *addr, socklen_t addrlen)
  443 +{
  444 + struct connect_parm p = { sizeof(struct connect_parm), sockfd, addr, addrlen, -1 };
  445 +
  446 + trace("%s: Connect begin sock=%d",__FUNCTION__,p.sockfd);
  447 + lib3270_call_thread((int (*)(H3270 *, void *)) do_connect_sock,hSession,&p);
  448 + trace("%s: Connect ends, rc=%d",__FUNCTION__,p.err);
  449 +
  450 + return p.err;
  451 +}
  452 +
  453 +
420 /** 454 /**
421 * Establish a telnet socket to the given host passed as an argument. 455 * Establish a telnet socket to the given host passed as an argument.
422 * 456 *
@@ -425,18 +459,18 @@ void popup_a_sockerr(H3270 *session, char *fmt, ...) @@ -425,18 +459,18 @@ void popup_a_sockerr(H3270 *session, char *fmt, ...)
425 * 459 *
426 * @param session Handle to the session descriptor. 460 * @param session Handle to the session descriptor.
427 * 461 *
428 - *  
429 * @return The file descriptor of the connected socket. 462 * @return The file descriptor of the connected socket.
430 */ 463 */
431 int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Boolean *resolving, Boolean *pending) 464 int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Boolean *resolving, Boolean *pending)
432 { 465 {
433 - struct servent *sp;  
434 - struct hostent *hp;  
435 - char passthru_haddr[8];  
436 - int passthru_len = 0;  
437 - unsigned short passthru_port = 0;  
438 - int on = 1;  
439 - char errmsg[1024]; 466 + struct servent * sp;
  467 + struct hostent * hp;
  468 + char passthru_haddr[8];
  469 + int passthru_len = 0;
  470 + unsigned short passthru_port = 0;
  471 + int on = 1;
  472 + char errmsg[1024];
  473 + int rc;
440 #if defined(OMTU) /*[*/ 474 #if defined(OMTU) /*[*/
441 int mtu = OMTU; 475 int mtu = OMTU;
442 #endif /*]*/ 476 #endif /*]*/
@@ -522,85 +556,109 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo @@ -522,85 +556,109 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
522 haddr.sin.sin_port = passthru_port; 556 haddr.sin.sin_port = passthru_port;
523 ha_len = sizeof(struct sockaddr_in); 557 ha_len = sizeof(struct sockaddr_in);
524 } else if (proxy_type > 0) { 558 } else if (proxy_type > 0) {
525 - status_resolving(session,1);  
526 - if (resolve_host_and_port(proxy_host, proxy_portname, 559 + if (resolve_host_and_port(&h3270,proxy_host, proxy_portname,
527 &proxy_port, &haddr.sa, &ha_len, errmsg, 560 &proxy_port, &haddr.sa, &ha_len, errmsg,
528 sizeof(errmsg)) < 0) { 561 sizeof(errmsg)) < 0) {
529 popup_an_error(session,errmsg); 562 popup_an_error(session,errmsg);
530 - status_resolving(session,0);  
531 return -1; 563 return -1;
532 - status_resolving(session,0);  
533 } 564 }
534 } else { 565 } else {
535 - status_resolving(session,1);  
536 - if (resolve_host_and_port(host, portname, 566 + if (resolve_host_and_port(&h3270,host, portname,
537 &session->current_port, &haddr.sa, &ha_len, 567 &session->current_port, &haddr.sa, &ha_len,
538 errmsg, sizeof(errmsg)) < 0) { 568 errmsg, sizeof(errmsg)) < 0) {
539 popup_an_error(session,errmsg); 569 popup_an_error(session,errmsg);
540 - status_resolving(session,0);  
541 return -1; 570 return -1;
542 - status_resolving(session,0);  
543 } 571 }
544 } 572 }
545 573
546 /* create the socket */ 574 /* create the socket */
547 - if ((session->sock = socket(haddr.sa.sa_family, SOCK_STREAM, 0)) == -1) { 575 + if ((session->sock = socket(haddr.sa.sa_family, SOCK_STREAM, 0)) == -1)
  576 + {
548 popup_a_sockerr(session, N_( "socket" ) ); 577 popup_a_sockerr(session, N_( "socket" ) );
549 return -1; 578 return -1;
550 } 579 }
551 580
552 /* set options for inline out-of-band data and keepalives */ 581 /* set options for inline out-of-band data and keepalives */
553 - if (setsockopt(session->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&on,  
554 - sizeof(on)) < 0) { 582 + if (setsockopt(session->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&on,sizeof(on)) < 0)
  583 + {
555 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_OOBINLINE"); 584 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_OOBINLINE");
556 close_fail; 585 close_fail;
557 } 586 }
558 - if (setsockopt(session->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,  
559 - sizeof(on)) < 0) { 587 +
  588 + if (setsockopt(session->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
  589 + {
560 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_KEEPALIVE"); 590 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_KEEPALIVE");
561 close_fail; 591 close_fail;
562 } 592 }
563 -#if defined(OMTU) /*[*/ 593 +
  594 +#if defined(OMTU)
564 if (setsockopt(session->sock, SOL_SOCKET, SO_SNDBUF, (char *)&mtu,sizeof(mtu)) < 0) 595 if (setsockopt(session->sock, SOL_SOCKET, SO_SNDBUF, (char *)&mtu,sizeof(mtu)) < 0)
565 { 596 {
566 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_SNDBUF"); 597 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_SNDBUF");
567 close_fail; 598 close_fail;
568 } 599 }
569 -#endif /*]*/ 600 +#endif
570 601
571 /* set the socket to be non-delaying */ 602 /* set the socket to be non-delaying */
572 -#if defined(_WIN32) /*[*/ 603 +#if defined(_WIN32)
573 if (non_blocking(False) < 0) 604 if (non_blocking(False) < 0)
574 -#else /*][*/ 605 +#else
575 if (non_blocking(True) < 0) 606 if (non_blocking(True) < 0)
576 -#endif /*]*/ 607 +#endif
577 close_fail; 608 close_fail;
578 609
579 -#if !defined(_WIN32) /*[*/ 610 +#if !defined(_WIN32)
580 /* don't share the socket with our children */ 611 /* don't share the socket with our children */
581 (void) fcntl(session->sock, F_SETFD, 1); 612 (void) fcntl(session->sock, F_SETFD, 1);
582 -#endif /*]*/ 613 +#endif
583 614
584 /* init ssl */ 615 /* init ssl */
585 -#if defined(HAVE_LIBSSL) /*[*/ 616 +#if defined(HAVE_LIBSSL)
586 last_ssl_error = 0; 617 last_ssl_error = 0;
587 if (session->ssl_host) 618 if (session->ssl_host)
588 ssl_init(); 619 ssl_init();
589 -#endif /*]*/ 620 +#endif
590 621
591 /* connect */ 622 /* connect */
592 status_connecting(session,1); 623 status_connecting(session,1);
593 - if (connect(session->sock, &haddr.sa, ha_len) == -1) { 624 +
  625 + switch(connect_sock(session, session->sock, &haddr.sa,ha_len))
  626 + {
  627 + case 0: // Connected
  628 + trace_dsn("Connected.\n");
  629 + if(non_blocking(False) < 0)
  630 + close_fail;
  631 + net_connected(session);
  632 + break;
  633 +
  634 + case SE_EWOULDBLOCK: // Connection in progress
  635 + case SE_EINPROGRESS:
  636 + *pending = True;
  637 + trace_dsn("Connection pending.\n");
  638 +#if !defined(_WIN32)
  639 + output_id = AddOutput(session->sock, session, output_possible);
  640 +#endif
  641 + break;
  642 +
  643 + default:
  644 + popup_a_sockerr(session, N_( "Can't connect to %s:%d" ),session->hostname, session->current_port);
  645 + close_fail;
  646 +
  647 + }
  648 +
  649 +/*
  650 + if (connect(session->sock, &haddr.sa, ha_len) == -1)
  651 + {
594 if (socket_errno() == SE_EWOULDBLOCK 652 if (socket_errno() == SE_EWOULDBLOCK
595 -#if defined(SE_EINPROGRESS) /*[*/ 653 +#if defined(SE_EINPROGRESS)
596 || socket_errno() == SE_EINPROGRESS 654 || socket_errno() == SE_EINPROGRESS
597 -#endif /*]*/ 655 +#endif
598 ) { 656 ) {
599 trace_dsn("Connection pending.\n"); 657 trace_dsn("Connection pending.\n");
600 *pending = True; 658 *pending = True;
601 -#if !defined(_WIN32) /*[*/ 659 +#if !defined(_WIN32)
602 output_id = AddOutput(session->sock, session, output_possible); 660 output_id = AddOutput(session->sock, session, output_possible);
603 -#endif /*]*/ 661 +#endif
604 } else { 662 } else {
605 popup_a_sockerr(session, N_( "Can't connect to %s:%d" ),session->hostname, session->current_port); 663 popup_a_sockerr(session, N_( "Can't connect to %s:%d" ),session->hostname, session->current_port);
606 close_fail; 664 close_fail;
@@ -610,6 +668,7 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo @@ -610,6 +668,7 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
610 close_fail; 668 close_fail;
611 net_connected(session); 669 net_connected(session);
612 } 670 }
  671 + */
613 672
614 /* set up temporary termtype */ 673 /* set up temporary termtype */
615 if (appres.termname == CN && session->std_ds_host) { 674 if (appres.termname == CN && session->std_ds_host) {
@@ -821,10 +880,12 @@ connection_complete(void) @@ -821,10 +880,12 @@ connection_complete(void)
821 */ 880 */
822 static void output_possible(H3270 *session) 881 static void output_possible(H3270 *session)
823 { 882 {
  883 + trace("%s: %s",HALF_CONNECTED ? "Half connected" : "Connected");
824 if (HALF_CONNECTED) 884 if (HALF_CONNECTED)
825 { 885 {
826 connection_complete(); 886 connection_complete();
827 } 887 }
  888 +
828 if (output_id) 889 if (output_id)
829 { 890 {
830 RemoveInput(output_id); 891 RemoveInput(output_id);
@@ -3163,8 +3224,7 @@ non_blocking(Boolean on) @@ -3163,8 +3224,7 @@ non_blocking(Boolean on)
3163 #if defined(HAVE_LIBSSL) /*[*/ 3224 #if defined(HAVE_LIBSSL) /*[*/
3164 3225
3165 /* Initialize the OpenSSL library. */ 3226 /* Initialize the OpenSSL library. */
3166 -static void  
3167 -ssl_init(void) 3227 +static void ssl_init(void)
3168 { 3228 {
3169 static Boolean ssl_initted = False; 3229 static Boolean ssl_initted = False;
3170 3230