/*- * Copyright (c) 2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Christos Zoulas. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include static void __attribute__((__noreturn__)) usage(void) { (void)fprintf(stderr, "Usage %s: [-t ] -d \n", getprogname()); exit(1); } int main(int argc, char *argv[]) { int timeout = 1, c, error, fd; char *device = NULL; struct termios tio; struct pollfd pfd; char ch; ssize_t nr; while ((c = getopt(argc, argv, "d:t:")) != -1) switch (c) { case 'd': device = optarg; break; case 't': timeout = atoi(optarg); break; default: usage(); } if (device == NULL) usage(); if ((fd = open(device, O_RDWR|O_EXCL|O_NONBLOCK)) == -1) err(1, "Cannot open `%s'", device); if (tcgetattr(fd, &tio) == -1) err(1, "Cannot getattr for `%s'", device); cfsetispeed(&tio, B9600); cfsetospeed(&tio, B9600); tio.c_iflag = 0; tio.c_oflag = 0; tio.c_cflag = CS8|CREAD; tio.c_lflag = 0; if (tcsetattr(fd, TCSANOW, &tio) == -1) err(1, "Cannot setattr for `%s'", device); pfd.fd = fd; pfd.events = POLLIN|POLLOUT; timeout *= 1000; while ((error = poll(&pfd, 1, timeout)) > 0) { if (pfd.revents & POLLOUT) { if ((nr = read(STDIN_FILENO, &ch, 1)) > 0) { if (write(fd, &ch, 1) != 1) err(1, "Write device failed"); } else { if (nr == -1) err(1, "Read tty failed"); (void)close(STDIN_FILENO); pfd.events = POLLIN; } } else if (pfd.revents & POLLIN) { if ((nr = read(fd, &ch, 1)) > 0) { if (write(STDOUT_FILENO, &ch, 1) != 1) err(1, "Write tty failed"); } else { if (nr == -1) err(1, "Read device failed"); goto out; } } else if (pfd.revents & (POLLERR|POLLHUP)) goto out; } if (error == -1) err(1, "poll failed"); out: (void)close(STDOUT_FILENO); (void)close(STDIN_FILENO); (void)close(fd); return 0; }