X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/e5398e091780133b1049bd87a75fbc299ed51749..096c89c34505cadba1fc6e7a5367273d5c5bea47:/chan.c diff --git a/chan.c b/chan.c index 855c769..5fbecb1 100644 --- a/chan.c +++ b/chan.c @@ -1,66 +1,36 @@ /* -*-c-*- * - * $Id: chan.c,v 1.2 1999/07/26 23:27:52 mdw Exp $ - * * Channel management * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * - * This file is part of the `fw' port forwarder. + * This file is part of the `fwd' port forwarder. * - * `fw' is free software; you can redistribute it and/or modify + * `fwd' is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * - * `fw' is distributed in the hope that it will be useful, + * + * `fwd' is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with `fw'; if not, write to the Free Software Foundation, + * along with `fwd'; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: chan.c,v $ - * Revision 1.2 1999/07/26 23:27:52 mdw - * Minor modifications for new design. - * - * Revision 1.1.1.1 1999/07/01 08:56:23 mdw - * Initial revision. - * - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "config.h" - -#include -#include -#include -#include - -#include -#include -#include -#include +#include "fwd.h" -#include -#include -#include - -#include -#include -#include - -#include "chan.h" -#include "fw.h" +#ifdef CHAN_DEBUG +# define D(x) x +#else +# define D(x) +#endif /*----- Main code ---------------------------------------------------------*/ @@ -88,37 +58,47 @@ static void writechan(int fd, unsigned mode, void *vp) /* --- Do the write --- */ - if (base + len <= CHAN_BUFSZ) + D( printf("writechan %d: base = %u, len = %u; ", fd, base, len); ) + if (base + len <= CHAN_BUFSZ) { + D( printf("%u:%u", base, len); ) w = write(fd, c->buf + base, len); - else { + } else { struct iovec iov[2]; iov[0].iov_base = c->buf + base; iov[0].iov_len = CHAN_BUFSZ - base; iov[1].iov_base = c->buf; iov[1].iov_len = len - iov[0].iov_len; + D( printf("%u:%u, %u:%u", + base, CHAN_BUFSZ - base, + 0, len + base - CHAN_BUFSZ); ) w = writev(fd, iov, 2); } + D( printf("; returned %d\n", w); ) /* --- Sift through the results --- */ if (w < 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) return; + c->err = errno; goto close; - } - else if (w == 0) + } else if (w == 0) goto close; else if (c->len == CHAN_BUFSZ && !(c->f & CHANF_CLOSE)) sel_addfile(&c->r); c->len -= w; + c->base += w; } if (c->len == 0) sel_rmfile(&c->w); /* --- Close the output end if necessary --- */ - if (c->len == 0 && (c->f & CHANF_CLOSE)) - c->func(c->p); + if (c->len == 0) { + c->base = 0; + if (c->f & CHANF_CLOSE) + c->func(c->p); + } return; /* --- Force a close if an error occurred --- */ @@ -143,33 +123,44 @@ static void readchan(int fd, unsigned mode, void *vp) { chan *c = vp; int r; - unsigned base = (c->base + c->len) & (CHAN_BUFSZ - 1); - unsigned len = CHAN_BUFSZ - c->len; + unsigned base = c->base; + unsigned len = c->len; /* --- Do the read --- */ - if (base + len <= CHAN_BUFSZ) - r = read(fd, c->buf + base, len); - else { + D( printf("readchan %d: base = %u, len = %u; ", fd, base, len); ) + if (base == 0) { + D( printf("%u:%u", len, CHAN_BUFSZ - len); ) + r = read(fd, c->buf + len, CHAN_BUFSZ - len); + } else if (base + len >= CHAN_BUFSZ) { + D( printf("%u:%u", base + len - CHAN_BUFSZ, CHAN_BUFSZ - len); ) + r = read(fd, c->buf + base + len - CHAN_BUFSZ, CHAN_BUFSZ - len); + } else { struct iovec iov[2]; - iov[0].iov_base = c->buf + base; - iov[0].iov_len = CHAN_BUFSZ - base; + iov[0].iov_base = c->buf + base + len; + iov[0].iov_len = CHAN_BUFSZ - base - len; iov[1].iov_base = c->buf; - iov[1].iov_len = len - iov[0].iov_len; + iov[1].iov_len = base; + D( printf("%u:%u, %u:%u", + base + len, CHAN_BUFSZ - base - len, + 0, base); ) r = readv(fd, iov, 2); } + D( printf("; returned %d\n", r); ) /* --- Sift through the results --- */ if (r < 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) return; + c->err = errno; goto close; - } - else if (r == 0) + } else if (r == 0) goto close; - else if (c->len == 0 && (c->f & CHANF_READY)) + else if (c->len == 0 && (c->f & CHANF_READY)) { sel_addfile(&c->w); + sel_force(&c->w); + } c->len += r; if (c->len == CHAN_BUFSZ) sel_rmfile(&c->r); @@ -179,8 +170,10 @@ static void readchan(int fd, unsigned mode, void *vp) close: c->f |= CHANF_CLOSE; - if (!c->len && (c->f & CHANF_READY)) + if (!c->len && (c->f & CHANF_READY)) { sel_addfile(&c->w); + sel_force(&c->w); + } sel_rmfile(&c->r); } @@ -217,8 +210,10 @@ void chan_dest(chan *c, int fd) if (c->f & CHANF_READY) return; sel_initfile(sel, &c->w, fd, SEL_WRITE, writechan, c); - if (c->len || (c->f & CHANF_CLOSE)) + if (c->len || (c->f & CHANF_CLOSE)) { sel_addfile(&c->w); + sel_force(&c->w); + } c->f |= CHANF_READY; }