Fixed POSIX IO, (ACCEPT) now emits SPACE at end of line.
[pforth] / csrc / posix / pf_io_posix.c
index bf4a5c3..211c516 100644 (file)
 **\r
 ****************************************************************\r
 ** 941004 PLB Extracted IO calls from pforth_main.c\r
 **\r
 ****************************************************************\r
 ** 941004 PLB Extracted IO calls from pforth_main.c\r
+** 090220 PLB Fixed broken sdQueryTerminal on Mac. It always returned true.\r
 ***************************************************************/\r
 \r
 #include "../pf_all.h"\r
 \r
 ***************************************************************/\r
 \r
 #include "../pf_all.h"\r
 \r
-#if PF_POSIX_IO\r
 /* Configure console so that characters are not buffered.\r
 /* Configure console so that characters are not buffered.\r
- * This allows KEY to work and also HISTORY.ON\r
- * Thanks to Ralf Baechle and David Feuer for contributing this.\r
+ * This allows KEY and ?TERMINAL to work and also HISTORY.ON\r
  */\r
 \r
 #include <unistd.h>\r
  */\r
 \r
 #include <unistd.h>\r
 #include <termios.h>\r
 #include <sys/poll.h>\r
 \r
 #include <termios.h>\r
 #include <sys/poll.h>\r
 \r
-#define stdin_fd 1\r
-\r
 static struct termios save_termios;\r
 static int stdin_is_tty;\r
 \r
 static struct termios save_termios;\r
 static int stdin_is_tty;\r
 \r
+/* poll() is broken in Mac OS X Tiger OS so use select() instead. */\r
+#define PF_USE_SELECT  (1)\r
+\r
 /* Default portable terminal I/O. */\r
 int  sdTerminalOut( char c )\r
 {\r
        return putchar(c);\r
 }\r
 /* Default portable terminal I/O. */\r
 int  sdTerminalOut( char c )\r
 {\r
        return putchar(c);\r
 }\r
-/* We don't need to echo because getchar() echos. */\r
+\r
 int  sdTerminalEcho( char c )\r
 {\r
 int  sdTerminalEcho( char c )\r
 {\r
-       TOUCH(c);\r
+       putchar(c);\r
        return 0;\r
 }\r
        return 0;\r
 }\r
+\r
 int  sdTerminalIn( void )\r
 {\r
        return getchar();\r
 int  sdTerminalIn( void )\r
 {\r
        return getchar();\r
@@ -66,44 +67,70 @@ int  sdTerminalFlush( void )
 /****************************************************/\r
 int sdQueryTerminal( void )\r
 {\r
 /****************************************************/\r
 int sdQueryTerminal( void )\r
 {\r
-       struct pollfd  pfd;\r
+#if PF_USE_SELECT\r
+       fd_set readfds;\r
+       struct timeval tv;\r
+       FD_ZERO(&readfds);\r
+       FD_SET(STDIN_FILENO, &readfds);\r
+       /* Set timeout to zero so that we just poll and return. */\r
+       tv.tv_sec = 0;\r
+       tv.tv_usec = 0;\r
+       int select_retval = select(STDIN_FILENO+1, &readfds, NULL, NULL, &tv);\r
+       if (select_retval < 0)\r
+       {\r
+               perror("sdTerminalInit: select");\r
+       }\r
+       return FD_ISSET(STDIN_FILENO,&readfds) ? FTRUE : FFALSE;\r
+\r
+#else\r
+       struct pollfd  pfd = { 0 };\r
        sdTerminalFlush();\r
        sdTerminalFlush();\r
-       pfd.fd = stdin_fd;\r
-       pfd.events = stdin_fd;\r
-       return poll( &pfd, 1, 0 );      \r
+       pfd.fd = STDIN_FILENO;\r
+       pfd.events = POLLIN;\r
+       int result = poll( &pfd, 1, 0 );\r
+    /* On a Mac it may set revents to POLLNVAL because poll() is broken on Tiger. */\r
+       if( pfd.revents & POLLNVAL )\r
+       {\r
+               PRT(("sdQueryTerminal: poll got POLLNVAL, stdin not open\n"));\r
+               return FFALSE;\r
+       }\r
+       else\r
+       {\r
+               return (pfd.revents & POLLIN) ? FTRUE : FFALSE;\r
+       }\r
+#endif\r
 }\r
 \r
 /****************************************************/\r
 void sdTerminalInit(void)\r
 {\r
 }\r
 \r
 /****************************************************/\r
 void sdTerminalInit(void)\r
 {\r
-        struct termios term;\r
-       \r
-        stdin_is_tty = isatty(stdin_fd);\r
-        if (!stdin_is_tty)\r
-                return;\r
-               \r
+       struct termios term;\r
+\r
+       stdin_is_tty = isatty(STDIN_FILENO);\r
+       if (stdin_is_tty)\r
+       {               \r
 /* Get current terminal attributes and save them so we can restore them. */\r
 /* Get current terminal attributes and save them so we can restore them. */\r
-        tcgetattr(stdin_fd, &term);\r
-        save_termios = term;\r
+               tcgetattr(STDIN_FILENO, &term);\r
+               save_termios = term;\r
        \r
 /* ICANON says to wait upon read until a character is received,\r
  * and then to return it immediately (or soon enough....)\r
  * ECHOCTL says not to echo backspaces and other control chars as ^H */\r
        \r
 /* ICANON says to wait upon read until a character is received,\r
  * and then to return it immediately (or soon enough....)\r
  * ECHOCTL says not to echo backspaces and other control chars as ^H */\r
-        term.c_lflag &= ~( ECHO | ECHONL | ECHOCTL | ICANON );\r
-        term.c_cc[VTIME] = 0;\r
-        term.c_cc[VMIN] = 1;\r
-        tcsetattr(stdin_fd, TCSANOW, &term);\r
+               term.c_lflag &= ~( ECHO | ECHONL | ECHOCTL | ICANON );\r
+               term.c_cc[VTIME] = 0;\r
+               term.c_cc[VMIN] = 1;\r
+               if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 )\r
+               {\r
+                       perror("sdTerminalInit: tcsetattr");\r
+               }\r
+       }\r
 }\r
 \r
 /****************************************************/\r
 void sdTerminalTerm(void)\r
 {\r
 }\r
 \r
 /****************************************************/\r
 void sdTerminalTerm(void)\r
 {\r
-        if (!stdin_is_tty)\r
-                return;\r
-\r
-        tcsetattr(stdin_fd, TCSANOW, &save_termios);\r
+       if (stdin_is_tty)\r
+       {\r
+               tcsetattr(STDIN_FILENO, TCSANOW, &save_termios);\r
+       }\r
 }\r
 }\r
-\r
-#undef stdin_fd\r
-\r
-#endif\r