Mercurial > dropbear
comparison common-channel.c @ 1192:af940cefdba1
Fix "Avoid queueing into circbuffer when the channel is about to close"
which broken handling EAGAIN/EINTR
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 27 Nov 2015 22:19:08 +0800 |
parents | b370b4b172d0 |
children | 750ec4ec4cbe |
comparison
equal
deleted
inserted
replaced
1191:b370b4b172d0 | 1192:af940cefdba1 |
---|---|
443 if (errno != EINTR && errno != EAGAIN) { | 443 if (errno != EINTR && errno != EAGAIN) { |
444 TRACE(("channel IO write error fd %d %s", fd, strerror(errno))) | 444 TRACE(("channel IO write error fd %d %s", fd, strerror(errno))) |
445 close_chan_fd(channel, fd, SHUT_WR); | 445 close_chan_fd(channel, fd, SHUT_WR); |
446 return DROPBEAR_FAILURE; | 446 return DROPBEAR_FAILURE; |
447 } | 447 } |
448 } | 448 } else { |
449 cbuf_incrread(cbuf, written); | 449 cbuf_incrread(cbuf, written); |
450 channel->recvdonelen += written; | 450 channel->recvdonelen += written; |
451 } | |
451 return DROPBEAR_SUCCESS; | 452 return DROPBEAR_SUCCESS; |
452 } | 453 } |
453 #endif /* !HAVE_WRITEV */ | 454 #endif /* !HAVE_WRITEV */ |
454 | 455 |
455 #ifdef HAVE_WRITEV | 456 #ifdef HAVE_WRITEV |
458 | 459 |
459 struct iovec iov[3]; | 460 struct iovec iov[3]; |
460 unsigned char *circ_p1, *circ_p2; | 461 unsigned char *circ_p1, *circ_p2; |
461 unsigned int circ_len1, circ_len2; | 462 unsigned int circ_len1, circ_len2; |
462 int io_count = 0; | 463 int io_count = 0; |
463 int cbuf_written; | 464 |
464 ssize_t written; | 465 ssize_t written; |
465 | 466 |
466 cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2); | 467 cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2); |
467 | 468 |
468 if (circ_len1 > 0) { | 469 if (circ_len1 > 0) { |
506 if (errno != EINTR && errno != EAGAIN) { | 507 if (errno != EINTR && errno != EAGAIN) { |
507 TRACE(("channel IO write error fd %d %s", fd, strerror(errno))) | 508 TRACE(("channel IO write error fd %d %s", fd, strerror(errno))) |
508 close_chan_fd(channel, fd, SHUT_WR); | 509 close_chan_fd(channel, fd, SHUT_WR); |
509 return DROPBEAR_FAILURE; | 510 return DROPBEAR_FAILURE; |
510 } | 511 } |
511 } | 512 } else { |
512 | 513 int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written); |
513 cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written); | 514 cbuf_incrread(cbuf, cbuf_written); |
514 cbuf_incrread(cbuf, cbuf_written); | 515 if (morelen) { |
515 if (morelen) { | 516 *morelen = written - cbuf_written; |
516 *morelen = written - cbuf_written; | 517 } |
517 } | 518 channel->recvdonelen += written; |
518 channel->recvdonelen += written; | 519 } |
519 return DROPBEAR_SUCCESS; | 520 return DROPBEAR_SUCCESS; |
520 } | 521 } |
521 #endif /* HAVE_WRITEV */ | 522 #endif /* HAVE_WRITEV */ |
522 | 523 |
523 /* Called to write data out to the local side of the channel. | 524 /* Called to write data out to the local side of the channel. |