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