comparison common-channel.c @ 1079:acf444bcb115

Fix no-writev fallback
author Matt Johnston <matt@ucc.asn.au>
date Sat, 02 May 2015 22:47:25 +0800
parents cc6116cc0b5c
children c45d65392c1a
comparison
equal deleted inserted replaced
1078:b3b772646974 1079:acf444bcb115
432 channel->sent_eof = 1; 432 channel->sent_eof = 1;
433 433
434 TRACE(("leave send_msg_channel_eof")) 434 TRACE(("leave send_msg_channel_eof"))
435 } 435 }
436 436
437 /* Called to write data out to the local side of the channel. 437 #ifndef HAVE_WRITEV
438 Writes the circular buffer contents and also the "moredata" buffer 438 static void writechannel_fallback(struct Channel* channel, int fd, circbuffer *cbuf,
439 if not null. Will ignore EAGAIN */ 439 const unsigned char *UNUSED(moredata), unsigned int *morelen) {
440 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf, 440
441 unsigned char *circ_p1, *circ_p2;
442 unsigned int circ_len1, circ_len2;
443 ssize_t written;
444
445 if (morelen) {
446 /* fallback doesn't consume moredata */
447 *morelen = 0;
448 }
449
450 /* Write the first portion of the circular buffer */
451 cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2);
452 written = write(fd, circ_p1, circ_len1);
453 if (written < 0) {
454 if (errno != EINTR && errno != EAGAIN) {
455 TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
456 close_chan_fd(channel, fd, SHUT_WR);
457 }
458 } else {
459 cbuf_incrread(cbuf, written);
460 channel->recvdonelen += written;
461 }
462 }
463 #endif /* !HAVE_WRITEV */
464
465 #ifdef HAVE_WRITEV
466 static void writechannel_writev(struct Channel* channel, int fd, circbuffer *cbuf,
441 const unsigned char *moredata, unsigned int *morelen) { 467 const unsigned char *moredata, unsigned int *morelen) {
442 468
443 struct iovec iov[3]; 469 struct iovec iov[3];
444 unsigned char *circ_p1, *circ_p2; 470 unsigned char *circ_p1, *circ_p2;
445 unsigned int circ_len1, circ_len2; 471 unsigned int circ_len1, circ_len2;
446 int io_count = 0; 472 int io_count = 0;
447 473
448 int written; 474 ssize_t written;
449
450 TRACE(("enter writechannel fd %d", fd))
451 475
452 cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2); 476 cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2);
453 477
454 if (circ_len1 > 0) { 478 if (circ_len1 > 0) {
455 TRACE(("circ1 %d", circ_len1)) 479 TRACE(("circ1 %d", circ_len1))
500 *morelen = written - cbuf_written; 524 *morelen = written - cbuf_written;
501 } 525 }
502 channel->recvdonelen += written; 526 channel->recvdonelen += written;
503 } 527 }
504 528
505 #if 0 529 }
506 530 #endif /* HAVE_WRITEV */
507 maxlen = cbuf_readlen(cbuf); 531
508 532 /* Called to write data out to the local side of the channel.
509 /* Write the data out */ 533 Writes the circular buffer contents and also the "moredata" buffer
510 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen); 534 if not null. Will ignore EAGAIN */
511 if (len <= 0) { 535 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
512 TRACE(("errno %d len %d", errno, len)) 536 const unsigned char *moredata, unsigned int *morelen) {
513 if (len < 0 && errno != EINTR) { 537 TRACE(("enter writechannel fd %d", fd))
514 close_chan_fd(channel, fd, SHUT_WR); 538 #ifdef HAVE_WRITEV
515 } 539 writechannel_writev(channel, fd, cbuf, moredata, morelen);
516 TRACE(("leave writechannel: len <= 0")) 540 #else
517 return; 541 writechannel_fallback(channel, fd, cbuf, moredata, morelen);
518 }
519 TRACE(("writechannel wrote %d", len))
520
521 cbuf_incrread(cbuf, len);
522 channel->recvdonelen += len;
523 #endif 542 #endif
524 543
525 /* Window adjust handling */ 544 /* Window adjust handling */
526 if (channel->recvdonelen >= RECV_WINDOWEXTEND) { 545 if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
527 send_msg_channel_window_adjust(channel, channel->recvdonelen); 546 send_msg_channel_window_adjust(channel, channel->recvdonelen);
534 dropbear_assert(channel->extrabuf == NULL || 553 dropbear_assert(channel->extrabuf == NULL ||
535 channel->recvwindow <= cbuf_getavail(channel->extrabuf)); 554 channel->recvwindow <= cbuf_getavail(channel->extrabuf));
536 555
537 TRACE(("leave writechannel")) 556 TRACE(("leave writechannel"))
538 } 557 }
558
539 559
540 /* Set the file descriptors for the main select in session.c 560 /* Set the file descriptors for the main select in session.c
541 * This avoid channels which don't have any window available, are closed, etc*/ 561 * This avoid channels which don't have any window available, are closed, etc*/
542 void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads) { 562 void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads) {
543 563