The attached patch uses stdin instead of opening /dev/tty for run-time
interaction. It makes it shorter and, except for handling non-blocking
mode, very simple.
I assume the Cygwin part of tty_getchar() is still required.
Everything I added in the patch is in POSIX.1, so it should be very
portable to non-Windows platforms (and probably more portable than
opening /dev/tty, etc.).
Also, really, tty_done() probably isn't needed because we're modifying
stdin and not a terminal, so when we exit (the only time it's called)
it's not going to affect anything. But leaving it shouldn't hurt either.
I've tested it quite a bit and everything seems to work fine.
It's a diff against 4.20ALPHA8
Thanks,
Kris Katterjohn
--- x/nmap_tty.cc 2006-10-01 09:44:40.000000000 -0500
+++ y/nmap_tty.cc 2006-10-03 22:33:40.000000000 -0500
@@ -143,44 +143,33 @@ extern int tcsetattr(int fd, int actions
#endif
#endif
-static int tty_fd = 0;
+static int stdinflags;
static struct termios saved_ti;
static int tty_getchar()
{
- int c, numChars;
+ int c;
#ifdef __CYGWIN32__
fd_set set;
struct timeval tv;
-#endif
- if (tty_fd && tcgetpgrp(tty_fd) == getpid()) {
-
- // This is so that when the terminal has been disconnected, it will be reconnected when possible. If it slows things down, just remove it
- // tty_init();
-
-#ifdef __CYGWIN32__
- FD_ZERO(&set); FD_SET(tty_fd, &set);
- tv.tv_sec = 0; tv.tv_usec = 0;
- if (select(tty_fd + 1, &set, NULL, NULL, &tv) <= 0)
- return -1;
+ FD_ZERO(&set); FD_SET(STDIN_FILENO, &set);
+ tv.tv_sec = 0; tv.tv_usec = 0;
+ if (select(STDIN_FILENO + 1, &set, NULL, NULL, &tv) <= 0)
+ return -1;
#endif
- c = 0;
- numChars = read(tty_fd, &c, 1);
- if (numChars > 0) return c;
- }
+ c = getchar();
+
+ if (c != EOF)
+ return c;
return -1;
}
static void tty_done()
{
- if (!tty_fd) return;
-
- tcsetattr(tty_fd, TCSANOW, &saved_ti);
-
- close(tty_fd);
- tty_fd = 0;
+ fcntl(STDIN_FILENO, F_SETFL, stdinflags & ~O_NONBLOCK);
+ tcsetattr(STDIN_FILENO, TCSANOW, &saved_ti);
}
/*
@@ -192,23 +181,20 @@ void tty_init()
{
struct termios ti;
- if (tty_fd)
+ if (!isatty(STDIN_FILENO))
return;
- if ((tty_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return;
-
-#ifndef __CYGWIN32__
- if (tcgetpgrp(tty_fd) != getpid()) {
- close(tty_fd); return;
- }
-#endif
+ stdinflags = fcntl(STDIN_FILENO, F_GETFL);
+ if (!(stdinflags & O_NONBLOCK))
+ if (fcntl(STDIN_FILENO, F_SETFL, stdinflags | O_NONBLOCK) == -1)
+ return;
- tcgetattr(tty_fd, &ti);
+ tcgetattr(STDIN_FILENO, &ti);
saved_ti = ti;
ti.c_lflag &= ~(ICANON | ECHO);
ti.c_cc[VMIN] = 1;
ti.c_cc[VTIME] = 0;
- tcsetattr(tty_fd, TCSANOW, &ti);
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &ti);
atexit(tty_done);
}
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org
Received on Oct 03 2006