/* * xtty by Davide Libenzi (trivial console to peek/poke to tty-like devices) * Copyright (C) 2005 Davide Libenzi * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Davide Libenzi * */ #include #include #include #include #include #include #include #include #include #define STD_POLL_TIMEO (1 * 1000) static void xtty_usage(char const *prg) { fprintf(stderr, "use: %s --dev DEV [--at-mode] [--unbuf] [--help]\n", prg); } static char *xtty_tr(char *str, int n, char const *imap, char const *omap, int mn) { int i; char const *tmp; for (i = 0; i < n; i++) if ((tmp = (char *) memchr(imap, str[i], mn)) != NULL) str[i] = omap[tmp - imap]; return str; } static int xtty_setnobuf(int fd) { struct termios ttysts; if (tcgetattr(fd, &ttysts)) { perror("tcgetattr"); return -1; } /* * Disable canonical mode, and set buffer size to 1 byte. */ ttysts.c_lflag &= ~ICANON; ttysts.c_cc[VTIME] = 0; ttysts.c_cc[VMIN] = 1; if (tcsetattr(fd, TCSANOW, &ttysts)) { perror("tcgetattr"); return -1; } return 0; } int main(int ac, char **av) { int i, fd, rdbytes, timeo = STD_POLL_TIMEO, atmode = 0; char const *dev = NULL; struct pollfd pfds[2]; char buf[1024]; for (i = 1; i < ac; i++) { if (!strcmp(av[i], "--dev")) { if (++i < ac) dev = av[i]; } else if (!strcmp(av[i], "--at-mode")) atmode++; else if (!strcmp(av[i], "--unbuf")) xtty_setnobuf(0); else if (!strcmp(av[i], "--help")) { xtty_usage(av[0]); return 1; } } if (dev == NULL) { xtty_usage(av[0]); return 1; } if ((fd = open(dev, O_RDWR)) == -1) { perror(dev); return 2; } for (;;) { pfds[0].fd = fd; pfds[0].events = POLLIN; pfds[0].revents = 0; pfds[1].fd = 0; pfds[1].events = POLLIN; pfds[1].revents = 0; poll(pfds, 2, timeo); if (pfds[0].revents & POLLIN) { if ((rdbytes = read(pfds[0].fd, buf, sizeof(buf))) > 0) write(1, buf, rdbytes); else if (rdbytes == 0) break; } if (pfds[1].revents & POLLIN) { if ((rdbytes = read(pfds[1].fd, buf, sizeof(buf))) > 0) { if (atmode) xtty_tr(buf, rdbytes, "\n", "\r", 1); write(fd, buf, rdbytes); } else if (rdbytes == 0) break; } } close(fd); return 0; }