Commit ced7f3f3be5b7082fee977910c4775966d3368bc
1 parent
2083e868
Exists in
master
and in
3 other branches
Em windows existem momentos em que ele trava durante a conexão, movi o connect()…
… para um thread separada tentando evitar o problema
Showing
9 changed files
with
124 additions
and
58 deletions
Show diff stats
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); | ... | ... |
... | ... | @@ -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 | ... | ... |