**\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
-#if PF_POSIX_IO\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
+#include <sys/time.h>\r
#ifdef sun\r
#include <sys/int_types.h> /* Needed on Solaris for uint32_t in termio.h */\r
#endif\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
+/* poll() is broken in Mac OS X Tiger OS so use select() instead. */\r
+#ifndef PF_USE_SELECT\r
+#define PF_USE_SELECT (1)\r
+#endif\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
- TOUCH(c);\r
+ putchar(c);\r
return 0;\r
}\r
+\r
int sdTerminalIn( void )\r
{\r
return getchar();\r
/****************************************************/\r
int sdQueryTerminal( void )\r
{\r
- struct pollfd pfd;\r
+#if PF_USE_SELECT\r
+ int select_retval;\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
+ 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
+ int result;\r
+ struct pollfd pfd = { 0 };\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
+ 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
- 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
- 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
- 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
- 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
-#undef stdin_fd\r
-\r
-#endif\r