diff -ruN libax25-0.0.10/ChangeLog libax25-0.0.10.rxq/ChangeLog --- libax25-0.0.10/ChangeLog Thu Mar 28 23:09:15 2002 +++ libax25-0.0.10.rxq/ChangeLog Fri Mar 29 16:59:45 2002 @@ -1,3 +1,6 @@ + * libax25io handles nonblocking io correctly. (PE1RXQ) + THIS BREAKS PRACTICLY EVERY APP USING THIS LIBRARY, FIX THEM!!! + libax25 0.0.10 * Fixed byte counting in flush_obuf() (PE1RXQ) diff -ruN libax25-0.0.10/ax25io.c libax25-0.0.10.rxq/ax25io.c --- libax25-0.0.10/ax25io.c Thu Mar 28 22:57:51 2002 +++ libax25-0.0.10.rxq/ax25io.c Sat Apr 6 17:52:34 2002 @@ -134,38 +134,24 @@ static int flush_obuf(ax25io *p) { int ret; - int count=0; if (p->optr == 0) return 0; - do { - if ((ret = write(p->ofd, p->obuf, p->optr < p->paclen ? p->optr : p->paclen)) < 0) + if ((ret = write(p->ofd, p->obuf, p->optr < p->paclen ? p->optr : p->paclen)) < 0) return -1; - if (ret < p->optr) - memmove(p->obuf, &p->obuf[ret], p->optr - ret); - p->optr -= ret; - count += ret; - - /* If buffer full block until there is room */ - if (p->optr>=AXBUFLEN) { - fd_set fdset; - - FD_ZERO(&fdset); - FD_SET(p->ofd, &fdset); - if (select(p->ofd+1, NULL, &fdset, NULL, NULL)<0) - return -1; - } - } while (p->optr>=AXBUFLEN); + if (ret && ret < p->optr) + memmove(p->obuf, &p->obuf[ret], p->optr - ret); + p->optr -= ret; - return count; + return ret; } int axio_flush(ax25io *p) { int flushed=0; - fd_set fdset; + int ret; #ifdef HAVE_ZLIB_H if (p->zptr) { @@ -227,18 +213,23 @@ #endif while (p->optr) { - FD_ZERO(&fdset); - FD_SET(p->ofd, &fdset); - if (select(p->ofd+1, NULL, &fdset, NULL, NULL)<0) + /* Return on error or if zero bytes written */ + if ((ret=flush_obuf(p))<=0) return -1; - flushed+=flush_obuf(p); + flushed+=ret; } return flushed; } -static int rsendchar(unsigned char c, ax25io *p) +static int rsend(unsigned char *c, int len, ax25io *p) { + /* Don't go further until there is space */ + if (p->paclen <= p->optr) { + if (flush_obuf(p)<=0) + return -1; + } + #ifdef HAVE_ZLIB_H if (p->zptr) { struct compr_s *z = (struct compr_s *) p->zptr; @@ -255,9 +246,8 @@ /* * One new character to input. */ - z->char_buf = c; - z->zout.next_in = &z->char_buf; - z->zout.avail_in = 1; + z->zout.next_in = c; + z->zout.avail_in = len; /* * Now loop until deflate returns with avail_out != 0 */ @@ -298,18 +288,26 @@ } while (z->zout.avail_out == 0); - return c; + return len; } #endif - p->obuf[p->optr++] = c; + if (p->optr+lenobuf+p->optr, c, len); + p->optr+=len; + } else { + errno=EAGAIN; + return -1; + } - if (p->optr >= p->paclen && flush_obuf(p) < 0) + if (p->optr >= p->paclen && flush_obuf(p) < 0) { return -1; + } - return c; + return len; } + /* --------------------------------------------------------------------- */ static int recv_ibuf(ax25io *p) @@ -423,32 +421,25 @@ int axio_putc(int c, ax25io *p) { - char *cp; + char cp; if (p->telnetmode && c == IAC) { - if (rsendchar(IAC, p) == -1) - return -1; - return rsendchar(IAC, p); + static char iac[]={IAC, IAC}; + return rsend(iac, 2, p); } if (c == INTERNAL_EOL) { if (p->eolmode == EOLMODE_BINARY) - return rsendchar('\n', p); + return rsend("\n", 1, p); else - for (cp = p->eol; *cp; cp++) - if (rsendchar(*cp, p) == -1) - return -1; - return 1; + return rsend(p->eol, strlen(p->eol), p); } - if (p->eolmode == EOLMODE_TEXT && c == '\n') { - for (cp = p->eol; *cp; cp++) - if (rsendchar(*cp, p) == -1) - return -1; - return 1; - } + if (p->eolmode == EOLMODE_TEXT && c == '\n') + return rsend(p->eol, strlen(p->eol), p); - return rsendchar(c & 0xff, p); + cp=c&0xff; + return rsend(&cp, 1, p); } int axio_getc(ax25io *p) @@ -500,28 +491,34 @@ * ECHO and TRAPSIG). */ if (opt == TELOPT_LINEMODE && p->tn_linemode) { - rsendchar(IAC, p); - rsendchar(SB, p); - rsendchar(TELOPT_LINEMODE, p); - rsendchar(LM_MODE, p); - rsendchar(MODE_EDIT | MODE_TRAPSIG, p); - rsendchar(IAC, p); - rsendchar(SE, p); + static char telopt_linemode[]={ + IAC, + SB, + TELOPT_LINEMODE, + LM_MODE, + MODE_EDIT | MODE_TRAPSIG, + IAC, + SE }; + if (rsend(telopt_linemode, 7, p)<0) + return -1; } else { - rsendchar(IAC, p); - rsendchar(DONT, p); - rsendchar(opt, p); + static char iac_dont[]={IAC, DONT, 0}; + iac_dont[2]=opt; + if (rsend(iac_dont, 3, p)<0) + return -1; } axio_flush(p); break; case DO: switch (opt) { - case TELOPT_SGA: - rsendchar(IAC, p); - rsendchar(WILL, p); - rsendchar(opt, p); + case TELOPT_SGA: { + static char iac_will[]={IAC, WILL, 0}; + iac_will[2]=opt; + if (rsend(iac_will, 3, p)<0) + return -1; axio_flush(p); break; + } case TELOPT_ECHO: /* * If we want echo then just silently @@ -530,13 +527,15 @@ if (p->tn_echo) break; /* Note fall-through */ - default: - rsendchar(IAC, p); - rsendchar(WONT, p); - rsendchar(opt, p); + default: { + static char iac_wont[]={IAC, WONT, 0}; + iac_wont[2]=opt; + if (rsend(iac_wont, 3, p)<0) + return -1; axio_flush(p); break; } + } break; case IAC: /* Escaped IAC */ return IAC; @@ -639,29 +638,34 @@ } /* --------------------------------------------------------------------- */ +static char do_linemode[]={IAC, DO, TELOPT_LINEMODE}; -void axio_tn_do_linemode(ax25io *p) +int axio_tn_do_linemode(ax25io *p) { - rsendchar(IAC, p); - rsendchar(DO, p); - rsendchar(TELOPT_LINEMODE, p); + if (rsend(do_linemode, 3, p)<0) + return -1; p->tn_linemode = 1; + return 0; } -void axio_tn_will_echo(ax25io *p) +static char will_echo[]={IAC, WILL, TELOPT_ECHO}; + +int axio_tn_will_echo(ax25io *p) { - rsendchar(IAC, p); - rsendchar(WILL, p); - rsendchar(TELOPT_ECHO, p); + if (rsend(will_echo, 3, p)<0) + return -1; p->tn_echo = 1; + return 0; } -void axio_tn_wont_echo(ax25io *p) +static char wont_echo[]={IAC, WONT, TELOPT_ECHO}; + +int axio_tn_wont_echo(ax25io *p) { - rsendchar(IAC, p); - rsendchar(WONT, p); - rsendchar(TELOPT_ECHO, p); + if (rsend(wont_echo, 3, p)<0) + return -1; p->tn_echo = 0; + return 0; } /* --------------------------------------------------------------------- */ diff -ruN libax25-0.0.10/ax25io.h libax25-0.0.10.rxq/ax25io.h --- libax25-0.0.10/ax25io.h Tue Apr 10 03:54:09 2001 +++ libax25-0.0.10.rxq/ax25io.h Sat Mar 30 14:16:15 2002 @@ -78,8 +78,8 @@ extern int axio_printf(ax25io *, const char *, ...); -extern void axio_tn_do_linemode(ax25io *); -extern void axio_tn_will_echo(ax25io *); -extern void axio_tn_wont_echo(ax25io *); +extern int axio_tn_do_linemode(ax25io *); +extern int axio_tn_will_echo(ax25io *); +extern int axio_tn_wont_echo(ax25io *); #endif _AX25IO_H