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
XtGlue.c
... ... @@ -979,10 +979,12 @@ LIB3270_EXPORT int lib3270_call_thread(int(*callback)(H3270 *h, void *), H3270 *
979 979 if(h->set_timer)
980 980 h->set_timer(h,1);
981 981  
  982 + lib3270_main_iterate(0);
982 983 if(callbacks->callthread)
983 984 rc = callbacks->callthread(callback,h,parm);
984 985 else
985 986 rc = callback(h,parm);
  987 + lib3270_main_iterate(0);
986 988  
987 989 if(h->set_timer)
988 990 h->set_timer(h,0);
... ...
api.h
... ... @@ -386,7 +386,7 @@
386 386 LOCAL_EXTERN SCRIPT_STATE status_script(SCRIPT_STATE state);
387 387  
388 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 391 // #define RunPendingEvents(x) lib3270_main_iterate(x)
392 392 // #define Wait(s) lib3270_wait(x)
... ...
init.c
... ... @@ -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 114 static void lib3270_session_init(H3270 *hSession, const char *model)
111 115 {
112 116 int ovc, ovr;
... ... @@ -131,6 +135,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model)
131 135 hSession->resume = screen_disp;
132 136 hSession->update_oia = update_oia;
133 137 hSession->update_selection = update_selection;
  138 + hSession->cursor = cursor;
134 139  
135 140 hSession->sock = -1;
136 141 hSession->model_num = -1;
... ...
proxy.c
... ... @@ -688,10 +688,7 @@ proxy_socks5(int fd, char *host, unsigned short port, int force_d)
688 688 int rv;
689 689  
690 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 692 if (rv == -2)
696 693 use_name = 1;
697 694 else if (rv < 0) {
... ...
resolver.c
... ... @@ -86,6 +86,8 @@ struct parms
86 86 */
87 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 91 #ifdef AF_INET6
90 92  
91 93 struct addrinfo hints, *res;
... ... @@ -126,6 +128,7 @@ static int cresolve_host_and_port(H3270 *h, struct parms *p)
126 128  
127 129 (void) memcpy(p->sa, res->ai_addr, res->ai_addrlen);
128 130 *p->sa_len = res->ai_addrlen;
  131 +
129 132 freeaddrinfo(res);
130 133  
131 134 #else /*][*/
... ... @@ -179,16 +182,23 @@ static int cresolve_host_and_port(H3270 *h, struct parms *p)
179 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 203 return rc;
194 204  
... ...
resolverc.h
... ... @@ -17,6 +17,6 @@
17 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  
... ...
screen.c
... ... @@ -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 446 void status_connecting(H3270 *session, Boolean on)
455 447 {
456 448 if(session->cursor)
... ...
screen.h
... ... @@ -21,5 +21,5 @@ LIB3270_INTERNAL int *char_width, *char_height;
21 21 // LIB3270_INTERNAL void screen_update(H3270 *session, int bstart, int bend);
22 22  
23 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  
... ...
telnet.c
... ... @@ -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 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 459 *
426 460 * @param session Handle to the session descriptor.
427 461 *
428   - *
429 462 * @return The file descriptor of the connected socket.
430 463 */
431 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 474 #if defined(OMTU) /*[*/
441 475 int mtu = OMTU;
442 476 #endif /*]*/
... ... @@ -522,85 +556,109 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
522 556 haddr.sin.sin_port = passthru_port;
523 557 ha_len = sizeof(struct sockaddr_in);
524 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 560 &proxy_port, &haddr.sa, &ha_len, errmsg,
528 561 sizeof(errmsg)) < 0) {
529 562 popup_an_error(session,errmsg);
530   - status_resolving(session,0);
531 563 return -1;
532   - status_resolving(session,0);
533 564 }
534 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 567 &session->current_port, &haddr.sa, &ha_len,
538 568 errmsg, sizeof(errmsg)) < 0) {
539 569 popup_an_error(session,errmsg);
540   - status_resolving(session,0);
541 570 return -1;
542   - status_resolving(session,0);
543 571 }
544 572 }
545 573  
546 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 577 popup_a_sockerr(session, N_( "socket" ) );
549 578 return -1;
550 579 }
551 580  
552 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 584 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_OOBINLINE");
556 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 590 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_KEEPALIVE");
561 591 close_fail;
562 592 }
563   -#if defined(OMTU) /*[*/
  593 +
  594 +#if defined(OMTU)
564 595 if (setsockopt(session->sock, SOL_SOCKET, SO_SNDBUF, (char *)&mtu,sizeof(mtu)) < 0)
565 596 {
566 597 popup_a_sockerr(session, N_( "setsockopt(%s)" ), "SO_SNDBUF");
567 598 close_fail;
568 599 }
569   -#endif /*]*/
  600 +#endif
570 601  
571 602 /* set the socket to be non-delaying */
572   -#if defined(_WIN32) /*[*/
  603 +#if defined(_WIN32)
573 604 if (non_blocking(False) < 0)
574   -#else /*][*/
  605 +#else
575 606 if (non_blocking(True) < 0)
576   -#endif /*]*/
  607 +#endif
577 608 close_fail;
578 609  
579   -#if !defined(_WIN32) /*[*/
  610 +#if !defined(_WIN32)
580 611 /* don't share the socket with our children */
581 612 (void) fcntl(session->sock, F_SETFD, 1);
582   -#endif /*]*/
  613 +#endif
583 614  
584 615 /* init ssl */
585   -#if defined(HAVE_LIBSSL) /*[*/
  616 +#if defined(HAVE_LIBSSL)
586 617 last_ssl_error = 0;
587 618 if (session->ssl_host)
588 619 ssl_init();
589   -#endif /*]*/
  620 +#endif
590 621  
591 622 /* connect */
592 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 652 if (socket_errno() == SE_EWOULDBLOCK
595   -#if defined(SE_EINPROGRESS) /*[*/
  653 +#if defined(SE_EINPROGRESS)
596 654 || socket_errno() == SE_EINPROGRESS
597   -#endif /*]*/
  655 +#endif
598 656 ) {
599 657 trace_dsn("Connection pending.\n");
600 658 *pending = True;
601   -#if !defined(_WIN32) /*[*/
  659 +#if !defined(_WIN32)
602 660 output_id = AddOutput(session->sock, session, output_possible);
603   -#endif /*]*/
  661 +#endif
604 662 } else {
605 663 popup_a_sockerr(session, N_( "Can't connect to %s:%d" ),session->hostname, session->current_port);
606 664 close_fail;
... ... @@ -610,6 +668,7 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo
610 668 close_fail;
611 669 net_connected(session);
612 670 }
  671 + */
613 672  
614 673 /* set up temporary termtype */
615 674 if (appres.termname == CN && session->std_ds_host) {
... ... @@ -821,10 +880,12 @@ connection_complete(void)
821 880 */
822 881 static void output_possible(H3270 *session)
823 882 {
  883 + trace("%s: %s",HALF_CONNECTED ? "Half connected" : "Connected");
824 884 if (HALF_CONNECTED)
825 885 {
826 886 connection_complete();
827 887 }
  888 +
828 889 if (output_id)
829 890 {
830 891 RemoveInput(output_id);
... ... @@ -3163,8 +3224,7 @@ non_blocking(Boolean on)
3163 3224 #if defined(HAVE_LIBSSL) /*[*/
3164 3225  
3165 3226 /* Initialize the OpenSSL library. */
3166   -static void
3167   -ssl_init(void)
  3227 +static void ssl_init(void)
3168 3228 {
3169 3229 static Boolean ssl_initted = False;
3170 3230  
... ...