Merge pull request #75 from SeekingMeaning/0BSD
[pforth] / csrc / posix / pf_io_posix.c
CommitLineData
8e9db35f
PB
1/* $Id$ */
2/***************************************************************
3** I/O subsystem for PForth based on 'C'
4**
5** Author: Phil Burk
6** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom
7**
1f99f95d
S
8** Permission to use, copy, modify, and/or distribute this
9** software for any purpose with or without fee is hereby granted.
10**
11** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14** THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
15** CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
16** FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
17** CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
8e9db35f
PB
19**
20****************************************************************
21** 941004 PLB Extracted IO calls from pforth_main.c
22** 090220 PLB Fixed broken sdQueryTerminal on Mac. It always returned true.
23***************************************************************/
24
25#include "../pf_all.h"
26
27/* Configure console so that characters are not buffered.
28 * This allows KEY and ?TERMINAL to work and also HISTORY.ON
29 */
30
31#include <unistd.h>
32#include <sys/time.h>
33#ifdef sun
34#include <sys/int_types.h> /* Needed on Solaris for uint32_t in termio.h */
35#endif
36#include <termios.h>
37#include <sys/poll.h>
38
39static struct termios save_termios;
40static int stdin_is_tty;
41
42/* poll() is broken in Mac OS X Tiger OS so use select() instead. */
43#ifndef PF_USE_SELECT
44#define PF_USE_SELECT (1)
45#endif
46
47/* Default portable terminal I/O. */
48int sdTerminalOut( char c )
49{
50 return putchar(c);
51}
52
53int sdTerminalEcho( char c )
54{
55 putchar(c);
56 return 0;
57}
58
59int sdTerminalIn( void )
60{
61 return getchar();
62}
63
64int sdTerminalFlush( void )
65{
66#ifdef PF_NO_FILEIO
67 return -1;
68#else
69 return fflush(PF_STDOUT);
70#endif
71}
72
73/****************************************************/
74int sdQueryTerminal( void )
75{
76#if PF_USE_SELECT
77 int select_retval;
78 fd_set readfds;
79 struct timeval tv;
80 FD_ZERO(&readfds);
81 FD_SET(STDIN_FILENO, &readfds);
82 /* Set timeout to zero so that we just poll and return. */
83 tv.tv_sec = 0;
84 tv.tv_usec = 0;
85 select_retval = select(STDIN_FILENO+1, &readfds, NULL, NULL, &tv);
86 if (select_retval < 0)
87 {
88 perror("sdTerminalInit: select");
89 }
90 return FD_ISSET(STDIN_FILENO,&readfds) ? FTRUE : FFALSE;
91
92#else
93 int result;
94 struct pollfd pfd = { 0 };
95 sdTerminalFlush();
96 pfd.fd = STDIN_FILENO;
97 pfd.events = POLLIN;
98 result = poll( &pfd, 1, 0 );
99 /* On a Mac it may set revents to POLLNVAL because poll() is broken on Tiger. */
100 if( pfd.revents & POLLNVAL )
101 {
102 PRT(("sdQueryTerminal: poll got POLLNVAL, stdin not open\n"));
103 return FFALSE;
104 }
105 else
106 {
107 return (pfd.revents & POLLIN) ? FTRUE : FFALSE;
108 }
109#endif
110}
111
112/****************************************************/
113void sdTerminalInit(void)
114{
115 struct termios term;
116
117 stdin_is_tty = isatty(STDIN_FILENO);
118 if (stdin_is_tty)
119 {
120/* Get current terminal attributes and save them so we can restore them. */
121 tcgetattr(STDIN_FILENO, &term);
122 save_termios = term;
123
124/* ICANON says to wait upon read until a character is received,
125 * and then to return it immediately (or soon enough....)
126 * ECHOCTL says not to echo backspaces and other control chars as ^H */
127 term.c_lflag &= ~( ECHO | ECHONL | ECHOCTL | ICANON );
128 term.c_cc[VTIME] = 0;
129 term.c_cc[VMIN] = 1;
130 if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 )
131 {
132 perror("sdTerminalInit: tcsetattr");
133 }
134 }
135}
136
137/****************************************************/
138void sdTerminalTerm(void)
139{
140 if (stdin_is_tty)
141 {
142 tcsetattr(STDIN_FILENO, TCSANOW, &save_termios);
143 }
144}