diff -ruN node-0.3.0/HISTORY node-0.3.0.rxq/HISTORY --- node-0.3.0/HISTORY Mon Jul 5 19:35:49 1999 +++ node-0.3.0.rxq/HISTORY Fri Feb 14 00:03:26 2003 @@ -1,3 +1,6 @@ + - Fixed Nonblocking response for new libax25io. + (PE1RXQ) + 0.3.0 05 Jul 1999 - Initial version using the new dynamic libax25. - Moved the IO code to libax25. diff -ruN node-0.3.0/extcmd.c node-0.3.0.rxq/extcmd.c --- node-0.3.0/extcmd.c Sun Jun 6 22:24:34 1999 +++ node-0.3.0.rxq/extcmd.c Fri Feb 14 00:03:26 2003 @@ -49,8 +49,9 @@ { ax25io *iop; int pipe_in[2], pipe_out[2]; - int pid, c; - fd_set fdset; + int pid, cn=0, cp=0; + fd_set fdset, fdsetno; + int pend_nodew=0, pend_nodef=0, pend_pipew=0, pend_pipef=0; if (pipe(pipe_in) == -1) { node_perror("pipe_extcmd: pipe_in", errno); @@ -102,31 +103,66 @@ } while (1) { FD_ZERO(&fdset); + FD_ZERO(&fdsetno); FD_SET(STDIN_FILENO, &fdset); FD_SET(pipe_out[0], &fdset); - if (select(32, &fdset, 0, 0, 0) == -1) { + if (pend_nodew || pend_nodef) + FD_SET(NodeIo->ofd, &fdsetno); + if (pend_pipew || pend_pipef) + FD_SET(iop->ofd, &fdsetno); + if (select(32, &fdset, &fdsetno, 0, 0) == -1) { node_perror("pipe_extcmd: select", errno); break; } - if (FD_ISSET(STDIN_FILENO, &fdset)) { + /* Try to write pending char to pipe */ + if (FD_ISSET(iop->ofd, &fdsetno)) { + if (axio_putc(cn, iop) != -1) + pend_pipew=0; + else if (errno != EAGAIN) + break; + } + if (FD_ISSET(STDIN_FILENO, &fdset) && !pend_pipew) { alarm(ConnTimeout); - while((c = axio_getc(NodeIo)) != -1) - axio_putc(c, iop); + while((cn = axio_getc(NodeIo)) != -1) + if (axio_putc(cn, iop)==-1 && errno==EAGAIN) { + pend_pipew=1; + break; + } if (errno != EAGAIN) break; } - if (FD_ISSET(pipe_out[0], &fdset)) { + if (FD_ISSET(NodeIo->ofd, &fdsetno)) { + if (axio_putc(cp, NodeIo) != -1) + pend_pipew=0; + else if (errno != EAGAIN) + break; + } + if (FD_ISSET(pipe_out[0], &fdset) && !pend_nodew) { alarm(ConnTimeout); - while((c = axio_getc(iop)) != -1) - axio_putc(c, NodeIo); + while((cp = axio_getc(iop)) != -1) + if (axio_putc(cp, NodeIo)==-1 && errno==EAGAIN) { + pend_nodew=1; + break; + } if (errno != EAGAIN) { if (errno) node_msg("%s", strerror(errno)); break; } } - axio_flush(NodeIo); - axio_flush(iop); + if (axio_flush(NodeIo)==-1) { + if (errno==EAGAIN) + pend_nodef=1; + else + break; + } else + pend_nodef=0; + if (axio_flush(iop)==-1) { + if (errno==EAGAIN) + pend_pipef=1; + else + break; + } } axio_end(iop); end: diff -ruN node-0.3.0/gateway.c node-0.3.0.rxq/gateway.c --- node-0.3.0/gateway.c Sun Jun 6 22:24:34 1999 +++ node-0.3.0.rxq/gateway.c Mon Feb 17 01:19:22 2003 @@ -272,7 +272,18 @@ } User.dl_type = family; node_msg("Trying %s... Type to abort", print_dl(&User)); - axio_flush(NodeIo); + while (axio_flush(NodeIo)==-1) { + if (errno!=EAGAIN) { + close(fd); + return NULL; + } + FD_ZERO(&write_fdset); + FD_SET(NodeIo->ofd, &write_fdset); + if (select(NodeIo->ofd+1, 0, &write_fdset, 0, 0)==-1) { + close(fd); + return NULL; + } + } User.state = STATE_TRYING; update_user(); /* @@ -335,7 +346,18 @@ escape < 32 ? "CTRL-" : "", escape < 32 ? (escape + 'A' - 1) : escape); - axio_flush(NodeIo); + while (axio_flush(NodeIo)==-1) { + if (errno!=EAGAIN) { + close(fd); + return NULL; + } + FD_ZERO(&write_fdset); + FD_SET(NodeIo->ofd, &write_fdset); + if (select(NodeIo->ofd+1, 0, &write_fdset, 0, 0)==-1) { + close(fd); + return NULL; + } + } log(L_GW, "Connected to %s", print_dl(&User)); if ((riop = axio_init(fd, fd, paclen, eol)) == NULL) { node_perror("connect_to: Initializing I/O failed", errno); @@ -352,9 +374,10 @@ int do_connect(int argc, char **argv) { ax25io *riop; - int c, family, stay, escape, compress; - fd_set fdset; + int c, family, stay, escape, compress, cp=0, cn=0; + fd_set fdset, fdsetno; char *connstr = NULL; + int pend_pipew=0, pend_pipef=0, pend_nodew=0, pend_nodef=0, pend_getline=0; stay = ReConnectTo; if (!strcasecmp(argv[argc - 1], "s")) { @@ -406,7 +429,15 @@ axio_tnmode(riop, 1); if (connstr) { axio_printf(riop, "%s\n", connstr); - axio_flush(riop); + while (axio_flush(riop)==-1) { + if (errno!=EAGAIN) + return 0; + FD_ZERO(&fdset); + FD_SET(riop->ofd, &fdset); + if (select(riop->ofd+1, 0, &fdset, 0, 0)==-1) { + return 0; + } + } } /* * If eol conventions are compatible, switch to binary mode, @@ -421,16 +452,30 @@ } while (1) { FD_ZERO(&fdset); + FD_ZERO(&fdsetno); FD_SET(riop->ifd, &fdset); FD_SET(STDIN_FILENO, &fdset); - if (select(32, &fdset, 0, 0, 0) == -1) { + if (pend_nodew || pend_nodef) + FD_SET(NodeIo->ofd, &fdsetno); + if (pend_pipew || pend_pipef) + FD_SET(riop->ofd, &fdsetno); + if (select(32, &fdset, &fdsetno, 0, 0) == -1) { node_perror("do_connect: select", errno); break; } - if (FD_ISSET(riop->ifd, &fdset)) { + if (FD_ISSET(NodeIo->ofd, &fdsetno)) { + if (axio_putc(cp, NodeIo) != -1) + pend_nodew=0; + else if (errno != EAGAIN) + break; + } + if (FD_ISSET(riop->ifd, &fdset) && !pend_nodew) { alarm(ConnTimeout); - while((c = axio_getc(riop)) != -1) - axio_putc(c, NodeIo); + while((cp = axio_getc(riop)) != -1) + if (axio_putc(cp, NodeIo)==-1 && errno==EAGAIN) { + pend_nodew=1; + break; + } if (errno != EAGAIN) { switch (errno) { case 0: @@ -451,25 +496,52 @@ break; } } - if (FD_ISSET(STDIN_FILENO, &fdset)) { + if (FD_ISSET(riop->ofd, &fdsetno)) { + if (axio_putc(cn, riop) != -1) + pend_pipew=0; + else if (errno != EAGAIN) + break; + } + if (FD_ISSET(STDIN_FILENO, &fdset) && pend_getline) { + if (axio_getline(NodeIo)) + pend_getline=0; + } + if (FD_ISSET(STDIN_FILENO, &fdset) && !pend_pipew && !pend_getline) { alarm(ConnTimeout); - while((c = axio_getc(NodeIo)) != -1) { - if (escape != -1 && c == escape) + while((cn = axio_getc(NodeIo)) != -1) { + if (escape != -1 && cn == escape) break; - axio_putc(c, riop); + if (axio_putc(cn, riop)==-1 && errno==EAGAIN) { + pend_pipew=1; + break; + } } - if (escape != -1 && c == escape) { + if (escape != -1 && cn == escape) { axio_eolmode(NodeIo, EOLMODE_TEXT); - axio_getline(NodeIo); - break; + if (!axio_getline(NodeIo)) + pend_getline=1; + else + break; } if (errno != EAGAIN) { stay = 0; break; } } - axio_flush(riop); - axio_flush(NodeIo); + if (axio_flush(riop)==-1) { + if (errno==EAGAIN) + pend_pipef=1; + else + break; + } else + pend_pipef=0; + if (axio_flush(NodeIo)==-1) { + if (errno==EAGAIN) + pend_nodef=1; + else + break; + } else + pend_nodef=0; } axio_end(riop); log(L_GW, "Disconnected from %s", print_dl(&User)); @@ -488,6 +560,7 @@ ax25io *riop; int c; char *name, *addr[3], *cp; + fd_set fdset; if (argc < 2) { name = ""; @@ -507,9 +580,26 @@ if (fcntl(riop->ifd, F_SETFL, 0) == -1) node_perror("do_finger: fcntl - fd", errno); axio_printf(riop, "%s\n", name); - axio_flush(riop); + while (axio_flush(riop)==-1) { + if (errno!=EAGAIN) + break; + FD_ZERO(&fdset); + FD_SET(riop->ofd, &fdset); + if (select(riop->ofd+1, 0, &fdset, 0, 0)==-1) + break; + } while((c = axio_getc(riop)) != -1) - axio_putc(c, NodeIo); + if (axio_putc(c, NodeIo)==-1) { + if (errno!=EAGAIN) + break; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + /* This is one way traffic, we are just going + to sit and wait until we can send again */ + if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1) + break; + axio_putc(c, NodeIo); + } axio_end(riop); node_msg("Reconnected to %s", HostName); } @@ -615,7 +705,14 @@ return 0; } node_msg("Pinging %s... Type to abort", inet_ntoa(to.sin_addr)); - axio_flush(NodeIo); + while (axio_flush(NodeIo)==-1) { + if (errno!=EAGAIN) + return 0; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1) + return 0; + } strncpy(User.dl_name, hp->h_name, 31); User.dl_name[31] = 0; User.dl_type = AF_INET; diff -ruN node-0.3.0/node.c node-0.3.0.rxq/node.c --- node-0.3.0/node.c Sun Jun 6 22:24:34 1999 +++ node-0.3.0.rxq/node.c Mon Feb 17 01:18:42 2003 @@ -90,6 +90,7 @@ int paclen; FILE *fp; int invalid_cmds = 0; + fd_set fdset; signal(SIGALRM, signal_handler); signal(SIGTERM, signal_handler); @@ -170,7 +171,14 @@ #endif if (User.ul_type == AF_INET) { axio_tnmode(NodeIo, 1); - axio_tn_do_linemode(NodeIo); + while (axio_tn_do_linemode(NodeIo)==-1) { + if (errno!=EAGAIN) + return 1; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1) + return 1; + } } init_nodecmds(); if (read_config() == -1) { @@ -192,9 +200,22 @@ login_user(); if (User.call[0] == 0) { nprintf("\n%s (%s)\n\nlogin: ", VERSION, HostName); - axio_flush(NodeIo); + while (axio_flush(NodeIo)==-1) { + if (errno!=EAGAIN) + return 1; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1) + return 1; + } alarm(300L); /* 5 min timeout */ - if ((p = axio_getline(NodeIo)) == NULL) + while ((p = axio_getline(NodeIo)) == NULL && errno==EAGAIN) { + FD_ZERO(&fdset); + FD_SET(NodeIo->ifd, &fdset); + if (select(NodeIo->ifd+1, &fdset, 0, 0, 0)==-1) + return 1; + } + if (p == NULL) logout("User disconnected"); alarm(0L); strncpy(User.call, p, 9); @@ -215,13 +236,39 @@ } else if (strcmp(pw, "*") != 0) { nputs("Password: "); if (User.ul_type == AF_INET) { - axio_tn_will_echo(NodeIo); + while (axio_tn_will_echo(NodeIo)==-1) { + if (errno!=EAGAIN) + return 1; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1) + return 1; + } axio_eolmode(NodeIo, EOLMODE_BINARY); } - axio_flush(NodeIo); - p = axio_getline(NodeIo); + while (axio_flush(NodeIo)==-1) { + if (errno!=EAGAIN) + return 1; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1) + return 1; + } + while ((p = axio_getline(NodeIo)) == NULL && errno==EAGAIN) { + FD_ZERO(&fdset); + FD_SET(NodeIo->ifd, &fdset); + if (select(NodeIo->ifd+1, &fdset, 0, 0, 0)==-1) + return 1; + } if (User.ul_type == AF_INET) { - axio_tn_wont_echo(NodeIo); + while (axio_tn_wont_echo(NodeIo)==-1) { + if (errno!=EAGAIN) + return 1; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + if (select(NodeIo->ofd+1, 0,&fdset, 0, 0)==-1) + return 1; + } axio_eolmode(NodeIo, EOLMODE_TEXT); nputs("\n"); } @@ -243,7 +290,14 @@ put_prompt(); log(L_LOGIN, "%s @ %s logged in", User.call, User.ul_name); while (1) { - axio_flush(NodeIo); + while (axio_flush(NodeIo)==-1) { + if (errno!=EAGAIN) + return 1; + FD_ZERO(&fdset); + FD_SET(NodeIo->ofd, &fdset); + if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1) + return 1; + } User.state = STATE_IDLE; time(&User.cmdtime); update_user(); @@ -251,6 +305,13 @@ if ((p = axio_getline(NodeIo)) == NULL) { if (errno == EINTR) continue; + if (errno == EAGAIN) { + FD_ZERO(&fdset); + FD_SET(NodeIo->ifd, &fdset); + if (select(NodeIo->ifd+1, &fdset, 0, 0, 0)==-1) + return 1; + continue; + } logout("User disconnected"); } alarm(IdleTimeout); diff -ruN node-0.3.0/nodeusers.c node-0.3.0.rxq/nodeusers.c --- node-0.3.0/nodeusers.c Sun Jun 6 22:24:34 1999 +++ node-0.3.0.rxq/nodeusers.c Mon Feb 17 01:13:58 2003 @@ -67,11 +67,21 @@ fprintf(stderr, "nodeusers: axio_init failed\r\n"); return 1; } - if (inet && axio_getline(NodeIo) == NULL) { - if (logging) - syslog(LOG_ERR, "axio_getline: %m"); - axio_end(NodeIo); - return 1; + if (inet) { + while (axio_getline(NodeIo) == NULL) { + if (errno==EAGAIN) { + fd_set fdset; + + FD_ZERO(&fdset); + FD_SET(NodeIo->ifd, &fdset); + select(NodeIo->ifd+1, &fdset, 0, 0, 0); + continue; + } + if (logging) + syslog(LOG_ERR, "axio_getline: %m"); + axio_end(NodeIo); + return 1; + } } n = user_count(); nprintf("\n%s - %d user%s.\n\n", VERSION, n, n == 1 ? "" : "s"); diff -ruN node-0.3.0/util.c node-0.3.0.rxq/util.c --- node-0.3.0/util.c Wed Apr 21 22:38:43 1999 +++ node-0.3.0.rxq/util.c Fri Feb 14 00:12:03 2003 @@ -15,7 +15,15 @@ int nputs(const char *str) { - return axio_puts(str, NodeIo); + int i=0, ret; + + while (i