Commit 5d97f4fb7b4c58df7d4170a56d89cf2b4a649c7d
1 parent
08be26b2
Exists in
master
and in
5 other branches
Incluindo timeout de 2 minutos ao tentar conectar com o host para prevenir travamentos
Showing
1 changed file
with
70 additions
and
0 deletions
Show diff stats
src/lib3270/telnet.c
@@ -374,12 +374,82 @@ struct connect_parm | @@ -374,12 +374,82 @@ struct connect_parm | ||
374 | 374 | ||
375 | static int do_connect_sock(H3270 *h, struct connect_parm *p) | 375 | static int do_connect_sock(H3270 *h, struct connect_parm *p) |
376 | { | 376 | { |
377 | +#ifdef WIN32 | ||
377 | 378 | ||
378 | if(connect(p->sockfd, p->addr, p->addrlen) == -1) | 379 | if(connect(p->sockfd, p->addr, p->addrlen) == -1) |
379 | p->err = socket_errno(); | 380 | p->err = socket_errno(); |
380 | else | 381 | else |
381 | p->err = 0; | 382 | p->err = 0; |
382 | 383 | ||
384 | +#else | ||
385 | + | ||
386 | + // Linux, use 120 seconds timeout | ||
387 | + fcntl(p->sockfd, F_SETFL,fcntl(p->sockfd,F_GETFL,0)|O_NONBLOCK); | ||
388 | + | ||
389 | + errno = 0; | ||
390 | + if(connect(p->sockfd, p->addr, p->addrlen)) | ||
391 | + { | ||
392 | + if( errno != EINPROGRESS ) | ||
393 | + { | ||
394 | + p->err = errno; | ||
395 | + lib3270_write_log(h,"lib3270","Error %s on connect",strerror(errno)); | ||
396 | + } | ||
397 | + else | ||
398 | + { | ||
399 | + // Connection in progress, wait | ||
400 | + fd_set wr; | ||
401 | + struct timeval tm; | ||
402 | + int err; | ||
403 | + socklen_t len = sizeof(err); | ||
404 | + | ||
405 | + FD_ZERO(&wr); | ||
406 | + FD_SET(p->sockfd, &wr); | ||
407 | + memset(&tm,0,sizeof(tm)); | ||
408 | + | ||
409 | + tm.tv_sec = 120; // 2 minutes timeout | ||
410 | + | ||
411 | + switch(select(p->sockfd+1, NULL, &wr, NULL, &tm)) | ||
412 | + { | ||
413 | + case 0: | ||
414 | + lib3270_write_log(h,"lib3270","Connect timeout"); | ||
415 | + p->err = ETIMEDOUT; | ||
416 | + break; | ||
417 | + | ||
418 | + case -1: | ||
419 | + lib3270_write_log(h,"lib3270","Select error \"%s while connecting",strerror(errno)); | ||
420 | + p->err = errno; | ||
421 | + break; | ||
422 | + | ||
423 | + default: | ||
424 | + | ||
425 | + // Se o socket nao esta disponivel para gravacao o connect falhou | ||
426 | + if(!FD_ISSET(p->sockfd,&wr)) | ||
427 | + { | ||
428 | + lib3270_write_log(h,"lib3270","Unexpected connection failure, the socket wasn't ready to write"); | ||
429 | + p->err = ENOTCONN; | ||
430 | + } | ||
431 | + else if(getsockopt(p->sockfd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) | ||
432 | + { | ||
433 | + lib3270_write_log(h,"lib3270","Connect error. Error \"%s\" when getting socket state",strerror(errno)); | ||
434 | + p->err = ENOTCONN; | ||
435 | + } | ||
436 | + else if(err) | ||
437 | + { | ||
438 | + lib3270_write_log(h,"lib3270","Connection error \"%s\"",strerror(err)); | ||
439 | + p->err = err; | ||
440 | + } | ||
441 | + else | ||
442 | + { | ||
443 | + lib3270_write_log(h,"lib3270","Connected to host"); | ||
444 | + p->err = 0; | ||
445 | + } | ||
446 | + } | ||
447 | + } | ||
448 | + } | ||
449 | + | ||
450 | + fcntl(p->sockfd, F_SETFL,fcntl(p->sockfd,F_GETFL,0)&(~O_NONBLOCK)); | ||
451 | +#endif // WIN32 | ||
452 | + | ||
383 | return 0; | 453 | return 0; |
384 | } | 454 | } |
385 | 455 |