Merge pull request #13 from philburk/fixrom
[pforth] / csrc / posix / pf_io_posix.c
CommitLineData
bb6b2dcd 1/* $Id$ */\r
2/***************************************************************\r
3** I/O subsystem for PForth based on 'C'\r
4**\r
5** Author: Phil Burk\r
6** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom\r
7**\r
8** The pForth software code is dedicated to the public domain,\r
9** and any third party may reproduce, distribute and modify\r
10** the pForth software code or any derivative works thereof\r
11** without any compensation or license. The pForth software\r
12** code is provided on an "as is" basis without any warranty\r
13** of any kind, including, without limitation, the implied\r
14** warranties of merchantability and fitness for a particular\r
15** purpose and their equivalents under the laws of any jurisdiction.\r
16**\r
17****************************************************************\r
18** 941004 PLB Extracted IO calls from pforth_main.c\r
6b91cb54 19** 090220 PLB Fixed broken sdQueryTerminal on Mac. It always returned true.\r
bb6b2dcd 20***************************************************************/\r
21\r
22#include "../pf_all.h"\r
23\r
bb6b2dcd 24/* Configure console so that characters are not buffered.\r
6b91cb54 25 * This allows KEY and ?TERMINAL to work and also HISTORY.ON\r
bb6b2dcd 26 */\r
27\r
28#include <unistd.h>\r
b93ef4a1 29#include <sys/time.h>\r
bb6b2dcd 30#ifdef sun\r
31#include <sys/int_types.h> /* Needed on Solaris for uint32_t in termio.h */\r
32#endif\r
33#include <termios.h>\r
34#include <sys/poll.h>\r
35\r
bb6b2dcd 36static struct termios save_termios;\r
37static int stdin_is_tty;\r
38\r
6b91cb54 39/* poll() is broken in Mac OS X Tiger OS so use select() instead. */\r
b93ef4a1 40#ifndef PF_USE_SELECT\r
6b91cb54 41#define PF_USE_SELECT (1)\r
b93ef4a1 42#endif\r
6b91cb54 43\r
bb6b2dcd 44/* Default portable terminal I/O. */\r
45int sdTerminalOut( char c )\r
46{\r
47 return putchar(c);\r
48}\r
6b91cb54 49\r
bb6b2dcd 50int sdTerminalEcho( char c )\r
51{\r
6b91cb54 52 putchar(c);\r
bb6b2dcd 53 return 0;\r
54}\r
6b91cb54 55\r
bb6b2dcd 56int sdTerminalIn( void )\r
57{\r
58 return getchar();\r
59}\r
60\r
61int sdTerminalFlush( void )\r
62{\r
63#ifdef PF_NO_FILEIO\r
64 return -1;\r
65#else\r
66 return fflush(PF_STDOUT);\r
67#endif\r
68}\r
69\r
70/****************************************************/\r
71int sdQueryTerminal( void )\r
72{\r
6b91cb54 73#if PF_USE_SELECT\r
b93ef4a1 74 int select_retval;\r
6b91cb54 75 fd_set readfds;\r
76 struct timeval tv;\r
77 FD_ZERO(&readfds);\r
78 FD_SET(STDIN_FILENO, &readfds);\r
79 /* Set timeout to zero so that we just poll and return. */\r
80 tv.tv_sec = 0;\r
81 tv.tv_usec = 0;\r
b93ef4a1 82 select_retval = select(STDIN_FILENO+1, &readfds, NULL, NULL, &tv);\r
6b91cb54 83 if (select_retval < 0)\r
84 {\r
85 perror("sdTerminalInit: select");\r
86 }\r
87 return FD_ISSET(STDIN_FILENO,&readfds) ? FTRUE : FFALSE;\r
88\r
89#else\r
b93ef4a1 90 int result;\r
6b91cb54 91 struct pollfd pfd = { 0 };\r
bb6b2dcd 92 sdTerminalFlush();\r
6b91cb54 93 pfd.fd = STDIN_FILENO;\r
94 pfd.events = POLLIN;\r
b93ef4a1 95 result = poll( &pfd, 1, 0 );\r
6b91cb54 96 /* On a Mac it may set revents to POLLNVAL because poll() is broken on Tiger. */\r
97 if( pfd.revents & POLLNVAL )\r
98 {\r
99 PRT(("sdQueryTerminal: poll got POLLNVAL, stdin not open\n"));\r
100 return FFALSE;\r
101 }\r
102 else\r
103 {\r
104 return (pfd.revents & POLLIN) ? FTRUE : FFALSE;\r
105 }\r
106#endif\r
bb6b2dcd 107}\r
108\r
109/****************************************************/\r
110void sdTerminalInit(void)\r
111{\r
6b91cb54 112 struct termios term;\r
113\r
114 stdin_is_tty = isatty(STDIN_FILENO);\r
115 if (stdin_is_tty)\r
116 { \r
bb6b2dcd 117/* Get current terminal attributes and save them so we can restore them. */\r
6b91cb54 118 tcgetattr(STDIN_FILENO, &term);\r
119 save_termios = term;\r
bb6b2dcd 120 \r
121/* ICANON says to wait upon read until a character is received,\r
122 * and then to return it immediately (or soon enough....)\r
123 * ECHOCTL says not to echo backspaces and other control chars as ^H */\r
6b91cb54 124 term.c_lflag &= ~( ECHO | ECHONL | ECHOCTL | ICANON );\r
125 term.c_cc[VTIME] = 0;\r
126 term.c_cc[VMIN] = 1;\r
127 if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 )\r
128 {\r
129 perror("sdTerminalInit: tcsetattr");\r
130 }\r
131 }\r
bb6b2dcd 132}\r
133\r
134/****************************************************/\r
135void sdTerminalTerm(void)\r
136{\r
6b91cb54 137 if (stdin_is_tty)\r
138 {\r
139 tcsetattr(STDIN_FILENO, TCSANOW, &save_termios);\r
140 }\r
bb6b2dcd 141}\r