xref: /freebsd/contrib/tcsh/mi.termios.c (revision 6560ac57ce879857203bc456cdc3849808dc0700)
1c80476e4SDavid E. O'Brien /* termios.c - fake termios interface using sgtty interface
2c80476e4SDavid E. O'Brien  * 	       by Magnus Doell and Bruce Evans.
3c80476e4SDavid E. O'Brien  *
4c80476e4SDavid E. O'Brien  */
5c80476e4SDavid E. O'Brien #include "sh.h"
6c80476e4SDavid E. O'Brien 
73b6eaa7bSAndrey A. Chernov #if defined(_MINIX) && !defined(_MINIX_VMD)
8c80476e4SDavid E. O'Brien 
9c80476e4SDavid E. O'Brien 
10c80476e4SDavid E. O'Brien /* Undefine everything that clashes with sgtty.h. */
11c80476e4SDavid E. O'Brien #undef B0
12c80476e4SDavid E. O'Brien #undef B50
13c80476e4SDavid E. O'Brien #undef B75
14c80476e4SDavid E. O'Brien #undef B110
15c80476e4SDavid E. O'Brien #undef B134
16c80476e4SDavid E. O'Brien #undef B150
17c80476e4SDavid E. O'Brien #undef B200
18c80476e4SDavid E. O'Brien #undef B300
19c80476e4SDavid E. O'Brien #undef B600
20c80476e4SDavid E. O'Brien #undef B1200
21c80476e4SDavid E. O'Brien #undef B1800
22c80476e4SDavid E. O'Brien #undef B2400
23c80476e4SDavid E. O'Brien #undef B4800
24c80476e4SDavid E. O'Brien #undef B9600
25c80476e4SDavid E. O'Brien #undef B19200
26c80476e4SDavid E. O'Brien #undef B28800
27c80476e4SDavid E. O'Brien #undef B38400
28c80476e4SDavid E. O'Brien #undef B57600
29c80476e4SDavid E. O'Brien #undef B115200
30c80476e4SDavid E. O'Brien /* Do not #undef CRMOD. We want a warning when they differ! */
31c80476e4SDavid E. O'Brien #undef ECHO
32c80476e4SDavid E. O'Brien /* Do not #undef XTABS. We want a warning when they differ! */
33c80476e4SDavid E. O'Brien 
34c80476e4SDavid E. O'Brien /* Redefine some of the termios.h names just undefined with 'T_' prefixed
35c80476e4SDavid E. O'Brien  * to the name.  Don't bother with the low speeds - Minix does not support
36c80476e4SDavid E. O'Brien  * them.  Add support for higher speeds (speeds are now easy and don't need
37c80476e4SDavid E. O'Brien  * defines because they are not encoded).
38c80476e4SDavid E. O'Brien  */
39c80476e4SDavid E. O'Brien #define T_ECHO		000001
40c80476e4SDavid E. O'Brien 
41c80476e4SDavid E. O'Brien #include <errno.h>
42c80476e4SDavid E. O'Brien #include <sgtty.h>
43c80476e4SDavid E. O'Brien 
44c80476e4SDavid E. O'Brien static _PROTOTYPE( int tc_to_sg_speed, (speed_t speed) );
45c80476e4SDavid E. O'Brien static _PROTOTYPE( speed_t sg_to_tc_speed, (int speed) );
46c80476e4SDavid E. O'Brien #define B19200   192
47c80476e4SDavid E. O'Brien 
48c80476e4SDavid E. O'Brien /* The speed get/set functions could be macros in the Minix implementation
49c80476e4SDavid E. O'Brien  * because there are speed fields in the structure with no fancy packing
50c80476e4SDavid E. O'Brien  * and it is not practical to check the values outside the driver.
51c80476e4SDavid E. O'Brien  * Where tests are necessary because the driver acts different from what
52c80476e4SDavid E. O'Brien  * POSIX requires, they are done in tcsetattr.
53c80476e4SDavid E. O'Brien  */
54c80476e4SDavid E. O'Brien 
cfgetispeed(termios_p)55c80476e4SDavid E. O'Brien speed_t cfgetispeed(termios_p)
56c80476e4SDavid E. O'Brien struct termios *termios_p;
57c80476e4SDavid E. O'Brien {
58c80476e4SDavid E. O'Brien     return termios_p->c_ispeed;
59c80476e4SDavid E. O'Brien }
60c80476e4SDavid E. O'Brien 
cfgetospeed(termios_p)61c80476e4SDavid E. O'Brien speed_t cfgetospeed(termios_p)
62c80476e4SDavid E. O'Brien struct termios *termios_p;
63c80476e4SDavid E. O'Brien {
64c80476e4SDavid E. O'Brien     return termios_p->c_ospeed;
65c80476e4SDavid E. O'Brien }
66c80476e4SDavid E. O'Brien 
cfsetispeed(termios_p,speed)67c80476e4SDavid E. O'Brien speed_t cfsetispeed(termios_p, speed)
68c80476e4SDavid E. O'Brien struct termios *termios_p;
69c80476e4SDavid E. O'Brien speed_t speed;
70c80476e4SDavid E. O'Brien {
71c80476e4SDavid E. O'Brien     termios_p->c_ispeed = speed;
72c80476e4SDavid E. O'Brien     return 0;
73c80476e4SDavid E. O'Brien }
74c80476e4SDavid E. O'Brien 
cfsetospeed(termios_p,speed)75c80476e4SDavid E. O'Brien speed_t cfsetospeed(termios_p, speed)
76c80476e4SDavid E. O'Brien struct termios *termios_p;
77c80476e4SDavid E. O'Brien speed_t speed;
78c80476e4SDavid E. O'Brien {
79c80476e4SDavid E. O'Brien     termios_p->c_ospeed = speed;
80c80476e4SDavid E. O'Brien     return 0;
81c80476e4SDavid E. O'Brien }
82c80476e4SDavid E. O'Brien 
sg_to_tc_speed(speed)83c80476e4SDavid E. O'Brien static speed_t sg_to_tc_speed(speed)
84c80476e4SDavid E. O'Brien int speed;
85c80476e4SDavid E. O'Brien {
86c80476e4SDavid E. O'Brien     /* The speed encodings in sgtty.h and termios.h are different.  Both are
87c80476e4SDavid E. O'Brien      * inflexible.  Minix doesn't really support B0 but we map it through
88c80476e4SDavid E. O'Brien      * anyway.  It doesn't support B50, B75 or B134.
89c80476e4SDavid E. O'Brien      */
90c80476e4SDavid E. O'Brien     switch (speed) {
91c80476e4SDavid E. O'Brien 	case B0: return 0;
92c80476e4SDavid E. O'Brien 	case B110: return 110;
93c80476e4SDavid E. O'Brien 	case B200: return 200;
94c80476e4SDavid E. O'Brien 	case B300: return 300;
95c80476e4SDavid E. O'Brien 	case B600: return 600;
96c80476e4SDavid E. O'Brien 	case B1200: return 1200;
97c80476e4SDavid E. O'Brien 	case B1800: return 1800;
98c80476e4SDavid E. O'Brien 	case B2400: return 2400;
99c80476e4SDavid E. O'Brien 	case B4800: return 4800;
100c80476e4SDavid E. O'Brien 	case B9600: return 9600;
101c80476e4SDavid E. O'Brien 	case B19200: return 19200;
102c80476e4SDavid E. O'Brien #ifdef B28800
103c80476e4SDavid E. O'Brien 	case B28800: return 28800;
104c80476e4SDavid E. O'Brien #endif
105c80476e4SDavid E. O'Brien #ifdef B38400
106c80476e4SDavid E. O'Brien 	case B38400: return 38400;
107c80476e4SDavid E. O'Brien #endif
108c80476e4SDavid E. O'Brien #ifdef B57600
109c80476e4SDavid E. O'Brien 	case B57600: return 57600;
110c80476e4SDavid E. O'Brien #endif
111c80476e4SDavid E. O'Brien #ifdef B115200
112c80476e4SDavid E. O'Brien 	case B115200: return 115200;
113c80476e4SDavid E. O'Brien #endif
114c80476e4SDavid E. O'Brien 	default: return (speed_t)-1;
115c80476e4SDavid E. O'Brien     }
116c80476e4SDavid E. O'Brien }
117c80476e4SDavid E. O'Brien 
tc_to_sg_speed(speed)118c80476e4SDavid E. O'Brien static int tc_to_sg_speed(speed)
119c80476e4SDavid E. O'Brien speed_t speed;
120c80476e4SDavid E. O'Brien {
121c80476e4SDavid E. O'Brien     /* Don't use a switch here in case the compiler is 16-bit and doesn't
122c80476e4SDavid E. O'Brien      * properly support longs (speed_t's) in switches.  It turns out the
123c80476e4SDavid E. O'Brien      * switch is larger and slower for most compilers anyway!
124c80476e4SDavid E. O'Brien      */
125c80476e4SDavid E. O'Brien     if (speed == 0) return 0;
126c80476e4SDavid E. O'Brien     if (speed == 110) return B110;
127c80476e4SDavid E. O'Brien     if (speed == 200) return B200;
128c80476e4SDavid E. O'Brien     if (speed == 300) return B300;
129c80476e4SDavid E. O'Brien     if (speed == 600) return B600;
130c80476e4SDavid E. O'Brien     if (speed == 1200) return B1200;
131c80476e4SDavid E. O'Brien     if (speed == 1800) return B1800;
132c80476e4SDavid E. O'Brien     if (speed == 2400) return B2400;
133c80476e4SDavid E. O'Brien     if (speed == 4800) return B4800;
134c80476e4SDavid E. O'Brien     if (speed == 9600) return B9600;
135c80476e4SDavid E. O'Brien     if (speed == 19200) return B19200;
136c80476e4SDavid E. O'Brien #ifdef B28800
137c80476e4SDavid E. O'Brien     if (speed == 28800) return B28800;
138c80476e4SDavid E. O'Brien #endif
139c80476e4SDavid E. O'Brien #ifdef B38400
140c80476e4SDavid E. O'Brien     if (speed == 38400) return B38400;
141c80476e4SDavid E. O'Brien #endif
142c80476e4SDavid E. O'Brien #ifdef B57600
143c80476e4SDavid E. O'Brien     if (speed == 57600) return B57600;
144c80476e4SDavid E. O'Brien #endif
145c80476e4SDavid E. O'Brien #ifdef B115200
146c80476e4SDavid E. O'Brien     if (speed == 115200) return B115200;
147c80476e4SDavid E. O'Brien #endif
148c80476e4SDavid E. O'Brien     return -1;
149c80476e4SDavid E. O'Brien }
150c80476e4SDavid E. O'Brien 
tcgetattr(filedes,termios_p)151c80476e4SDavid E. O'Brien int tcgetattr(filedes, termios_p)
152c80476e4SDavid E. O'Brien int filedes;
153c80476e4SDavid E. O'Brien struct termios *termios_p;
154c80476e4SDavid E. O'Brien {
155c80476e4SDavid E. O'Brien     struct sgttyb sgbuf;
156c80476e4SDavid E. O'Brien     struct tchars tcbuf;
157c80476e4SDavid E. O'Brien 
158c80476e4SDavid E. O'Brien     if (ioctl(filedes, TIOCGETP, &sgbuf) < 0
159c80476e4SDavid E. O'Brien 	|| ioctl(filedes, TIOCGETC, (struct sgttyb *) &tcbuf) < 0)
160c80476e4SDavid E. O'Brien     {
161c80476e4SDavid E. O'Brien 	return -1;
162c80476e4SDavid E. O'Brien     }
163c80476e4SDavid E. O'Brien 
164c80476e4SDavid E. O'Brien     /* Minix input flags:
165c80476e4SDavid E. O'Brien      *   BRKINT:  forced off (break is not recognized)
166c80476e4SDavid E. O'Brien      *   IGNBRK:  forced on (break is not recognized)
167c80476e4SDavid E. O'Brien      *   ICRNL:   set if CRMOD is set and not RAW (CRMOD also controls output)
168c80476e4SDavid E. O'Brien      *   IGNCR:   forced off (ignoring cr's is not supported)
169c80476e4SDavid E. O'Brien      *   INLCR:   forced off (mapping nl's to cr's is not supported)
170c80476e4SDavid E. O'Brien      *   ISTRIP:  forced off (should be off for consoles, on for rs232 no RAW)
171c80476e4SDavid E. O'Brien      *   IXOFF:   forced off (rs232 uses CTS instead of XON/XOFF)
172c80476e4SDavid E. O'Brien      *   IXON:    forced on if not RAW
173c80476e4SDavid E. O'Brien      *   PARMRK:  forced off (no '\377', '\0', X sequence on errors)
174c80476e4SDavid E. O'Brien      * ? IGNPAR:  forced off (input with parity/framing errors is kept)
175c80476e4SDavid E. O'Brien      * ? INPCK:   forced off (input parity checking is not supported)
176c80476e4SDavid E. O'Brien      */
177c80476e4SDavid E. O'Brien     termios_p->c_iflag = IGNBRK;
178c80476e4SDavid E. O'Brien     if (!(sgbuf.sg_flags & RAW))
179c80476e4SDavid E. O'Brien     {
180c80476e4SDavid E. O'Brien 	termios_p->c_iflag |= IXON;
181c80476e4SDavid E. O'Brien 	if (sgbuf.sg_flags & CRMOD)
182c80476e4SDavid E. O'Brien 	{
183c80476e4SDavid E. O'Brien 	    termios_p->c_iflag |= ICRNL;
184c80476e4SDavid E. O'Brien 	}
185c80476e4SDavid E. O'Brien     }
186c80476e4SDavid E. O'Brien 
187c80476e4SDavid E. O'Brien     /* Minix output flags:
188c80476e4SDavid E. O'Brien      *   OPOST:   set if CRMOD or XTABS is set
189c80476e4SDavid E. O'Brien      *   XTABS:   copied from sg_flags
190c80476e4SDavid E. O'Brien      *   CRMOD:	  copied from sg_flags
191c80476e4SDavid E. O'Brien      */
192c80476e4SDavid E. O'Brien     termios_p->c_oflag = sgbuf.sg_flags & (CRMOD | XTABS);
193c80476e4SDavid E. O'Brien     if (termios_p->c_oflag)
194c80476e4SDavid E. O'Brien     {
195c80476e4SDavid E. O'Brien 	termios_p->c_oflag |= OPOST;
196c80476e4SDavid E. O'Brien     }
197c80476e4SDavid E. O'Brien 
198c80476e4SDavid E. O'Brien     /* Minix local flags:
199c80476e4SDavid E. O'Brien      *   ECHO:    set if ECHO is set
200c80476e4SDavid E. O'Brien      *   ECHOE:   set if ECHO is set (ERASE echoed as error-corecting backspace)
201c80476e4SDavid E. O'Brien      *   ECHOK:   set if ECHO is set ('\n' echoed after KILL char)
202c80476e4SDavid E. O'Brien      *   ECHONL:  forced off ('\n' not echoed when ECHO isn't set)
203c80476e4SDavid E. O'Brien      *   ICANON:  set if neither CBREAK nor RAW
204c80476e4SDavid E. O'Brien      *   IEXTEN:  forced off
205c80476e4SDavid E. O'Brien      *   ISIG:    set if not RAW
206c80476e4SDavid E. O'Brien      *   NOFLSH:  forced off (input/output queues are always flushed)
207c80476e4SDavid E. O'Brien      *   TOSTOP:  forced off (no job control)
208c80476e4SDavid E. O'Brien      */
209c80476e4SDavid E. O'Brien     termios_p->c_lflag = 0;
210c80476e4SDavid E. O'Brien     if (sgbuf.sg_flags & ECHO)
211c80476e4SDavid E. O'Brien     {
212c80476e4SDavid E. O'Brien 	termios_p->c_lflag |= T_ECHO | ECHOE | ECHOK;
213c80476e4SDavid E. O'Brien     }
214c80476e4SDavid E. O'Brien     if (!(sgbuf.sg_flags & RAW))
215c80476e4SDavid E. O'Brien     {
216c80476e4SDavid E. O'Brien 	termios_p->c_lflag |= ISIG;
217c80476e4SDavid E. O'Brien 	if (!(sgbuf.sg_flags & CBREAK))
218c80476e4SDavid E. O'Brien 	{
219c80476e4SDavid E. O'Brien 	    termios_p->c_lflag |= ICANON;
220c80476e4SDavid E. O'Brien 	}
221c80476e4SDavid E. O'Brien     }
222c80476e4SDavid E. O'Brien 
223c80476e4SDavid E. O'Brien     /* Minix control flags:
224c80476e4SDavid E. O'Brien      *   CLOCAL:  forced on (ignore modem status lines - not quite right)
225c80476e4SDavid E. O'Brien      *   CREAD:   forced on (receiver is always enabled)
226c80476e4SDavid E. O'Brien      *   CSIZE:   CS5-CS8 correspond directly to BITS5-BITS8
227c80476e4SDavid E. O'Brien      *   CSTOPB:  set for B110 (driver will generate 2 stop-bits than)
228c80476e4SDavid E. O'Brien      *   HUPCL:   forced off
229c80476e4SDavid E. O'Brien      *   PARENB:  set if EVENP or ODDP is set
230c80476e4SDavid E. O'Brien      *   PARODD:  set if ODDP is set
231c80476e4SDavid E. O'Brien      */
232c80476e4SDavid E. O'Brien     termios_p->c_cflag = CLOCAL | CREAD;
233c80476e4SDavid E. O'Brien     switch (sgbuf.sg_flags & BITS8)
234c80476e4SDavid E. O'Brien     {
235c80476e4SDavid E. O'Brien 	case BITS5: termios_p->c_cflag |= CS5; break;
236c80476e4SDavid E. O'Brien 	case BITS6: termios_p->c_cflag |= CS6; break;
237c80476e4SDavid E. O'Brien 	case BITS7: termios_p->c_cflag |= CS7; break;
238c80476e4SDavid E. O'Brien 	case BITS8: termios_p->c_cflag |= CS8; break;
239c80476e4SDavid E. O'Brien     }
240c80476e4SDavid E. O'Brien     if (sgbuf.sg_flags & ODDP)
241c80476e4SDavid E. O'Brien     {
242c80476e4SDavid E. O'Brien 	termios_p->c_cflag |= PARENB | PARODD;
243c80476e4SDavid E. O'Brien     }
244c80476e4SDavid E. O'Brien     if (sgbuf.sg_flags & EVENP)
245c80476e4SDavid E. O'Brien     {
246c80476e4SDavid E. O'Brien 	termios_p->c_cflag |= PARENB;
247c80476e4SDavid E. O'Brien     }
248c80476e4SDavid E. O'Brien     if (sgbuf.sg_ispeed == B110)
249c80476e4SDavid E. O'Brien     {
250c80476e4SDavid E. O'Brien 	termios_p->c_cflag |= CSTOPB;
251c80476e4SDavid E. O'Brien     }
252c80476e4SDavid E. O'Brien 
253c80476e4SDavid E. O'Brien     /* Minix may give back different input and output baudrates,
254c80476e4SDavid E. O'Brien      * but only the input baudrate is valid for both.
255c80476e4SDavid E. O'Brien      * As our termios emulation will fail, if input baudrate differs
256c80476e4SDavid E. O'Brien      * from output baudrate, force them to be equal.
257c80476e4SDavid E. O'Brien      * Otherwise it would be very suprisingly not to be able to set
258c80476e4SDavid E. O'Brien      * the terminal back to the state returned by tcgetattr :).
259c80476e4SDavid E. O'Brien      */
260c80476e4SDavid E. O'Brien     termios_p->c_ospeed =
261c80476e4SDavid E. O'Brien     termios_p->c_ispeed =
262c80476e4SDavid E. O'Brien 		sg_to_tc_speed((unsigned char) sgbuf.sg_ispeed);
263c80476e4SDavid E. O'Brien 
264c80476e4SDavid E. O'Brien     /* Minix control characters correspond directly except VSUSP and the
265c80476e4SDavid E. O'Brien      * important VMIN and VTIME are not really supported.
266c80476e4SDavid E. O'Brien      */
267c80476e4SDavid E. O'Brien     termios_p->c_cc[VEOF] = tcbuf.t_eofc;
268c80476e4SDavid E. O'Brien     termios_p->c_cc[VEOL] = tcbuf.t_brkc;
269c80476e4SDavid E. O'Brien     termios_p->c_cc[VERASE] = sgbuf.sg_erase;
270c80476e4SDavid E. O'Brien     termios_p->c_cc[VINTR] = tcbuf.t_intrc;
271c80476e4SDavid E. O'Brien     termios_p->c_cc[VKILL] = sgbuf.sg_kill;
272c80476e4SDavid E. O'Brien     termios_p->c_cc[VQUIT] = tcbuf.t_quitc;
273c80476e4SDavid E. O'Brien     termios_p->c_cc[VSTART] = tcbuf.t_startc;
274c80476e4SDavid E. O'Brien     termios_p->c_cc[VSTOP] = tcbuf.t_stopc;
275c80476e4SDavid E. O'Brien     termios_p->c_cc[VMIN] = 1;
276c80476e4SDavid E. O'Brien     termios_p->c_cc[VTIME] = 0;
277c80476e4SDavid E. O'Brien     termios_p->c_cc[VSUSP] = 0;
278c80476e4SDavid E. O'Brien 
279c80476e4SDavid E. O'Brien     return 0;
280c80476e4SDavid E. O'Brien }
281c80476e4SDavid E. O'Brien 
tcsetattr(filedes,opt_actions,termios_p)282c80476e4SDavid E. O'Brien int tcsetattr(filedes, opt_actions, termios_p)
283c80476e4SDavid E. O'Brien int filedes;
284c80476e4SDavid E. O'Brien int opt_actions;
285c80476e4SDavid E. O'Brien struct termios *termios_p;
286c80476e4SDavid E. O'Brien {
287c80476e4SDavid E. O'Brien     struct sgttyb sgbuf;
288c80476e4SDavid E. O'Brien     struct tchars tcbuf;
289c80476e4SDavid E. O'Brien     int sgspeed;
290c80476e4SDavid E. O'Brien 
291c80476e4SDavid E. O'Brien     /* Posix 1003.1-1988 page 135 says:
292c80476e4SDavid E. O'Brien      * Attempts to set unsupported baud rates shall be ignored, and it is
293c80476e4SDavid E. O'Brien      * implementation-defined whether an error is returned by any or all of
294c80476e4SDavid E. O'Brien      * cfsetispeed(), cfsetospeed(), or tcsetattr(). This refers both to
295c80476e4SDavid E. O'Brien      * changes to baud rates not supported by the hardware, and to changes
296c80476e4SDavid E. O'Brien      * setting the input and output baud rates to different values if the
297c80476e4SDavid E. O'Brien      * hardware does not support it.
298c80476e4SDavid E. O'Brien      * Ignoring means not to change the existing settings, doesn't it?
299c80476e4SDavid E. O'Brien      */
300c80476e4SDavid E. O'Brien     if ((termios_p->c_ispeed != 0 && termios_p->c_ispeed != termios_p->c_ospeed)
301c80476e4SDavid E. O'Brien 	|| (sgspeed = tc_to_sg_speed(termios_p->c_ospeed)) < 0)
302c80476e4SDavid E. O'Brien     {
303c80476e4SDavid E. O'Brien 	errno = EINVAL;
304c80476e4SDavid E. O'Brien 	return -1;
305c80476e4SDavid E. O'Brien     }
306c80476e4SDavid E. O'Brien 
307c80476e4SDavid E. O'Brien     sgbuf.sg_ispeed = sgbuf.sg_ospeed = sgspeed;
308c80476e4SDavid E. O'Brien     sgbuf.sg_flags = 0;
309c80476e4SDavid E. O'Brien 
310c80476e4SDavid E. O'Brien     /* I don't know what should happen with requests that are not supported by
311c80476e4SDavid E. O'Brien      * old Minix drivers and therefore cannot be emulated.
312c80476e4SDavid E. O'Brien      * Returning an error may confuse the application (the values aren't really
313c80476e4SDavid E. O'Brien      * invalid or unsupported by the hardware, they just couldn't be satisfied
314c80476e4SDavid E. O'Brien      * by the driver). Not returning an error might be even worse because the
315c80476e4SDavid E. O'Brien      * driver will act different to what the application requires it to act
316c80476e4SDavid E. O'Brien      * after sucessfully setting the attributes as specified.
317c80476e4SDavid E. O'Brien      * Settings that cannot be emulated fully include:
318c80476e4SDavid E. O'Brien      *   c_ospeed != 110 && c_cflag & CSTOPB
319c80476e4SDavid E. O'Brien      *   c_ospeed == 110 && ! c_cflag & CSTOPB
320c80476e4SDavid E. O'Brien      *   (c_cc[VMIN] != 1 || c_cc[VTIME] != 0) && ! c_lflag & ICANON
321c80476e4SDavid E. O'Brien      *   c_lflag & ICANON && ! c_lflag & ISIG
322c80476e4SDavid E. O'Brien      * For the moment I just ignore these conflicts.
323c80476e4SDavid E. O'Brien      */
324c80476e4SDavid E. O'Brien 
325c80476e4SDavid E. O'Brien     if (termios_p->c_oflag & OPOST)
326c80476e4SDavid E. O'Brien     {
327c80476e4SDavid E. O'Brien 	/* CRMOD isn't Posix and may conflict with ICRNL, which is Posix,
328c80476e4SDavid E. O'Brien 	 * so we just ignore it.
329c80476e4SDavid E. O'Brien 	 */
330c80476e4SDavid E. O'Brien 	if (termios_p->c_oflag & XTABS)
331c80476e4SDavid E. O'Brien 	{
332c80476e4SDavid E. O'Brien 		sgbuf.sg_flags |= XTABS;
333c80476e4SDavid E. O'Brien 	}
334c80476e4SDavid E. O'Brien     }
335c80476e4SDavid E. O'Brien 
336c80476e4SDavid E. O'Brien     if (termios_p->c_iflag & ICRNL)
337c80476e4SDavid E. O'Brien     {
338c80476e4SDavid E. O'Brien 	/* We couldn't do it better :-(. */
339c80476e4SDavid E. O'Brien 	sgbuf.sg_flags |= CRMOD;
340c80476e4SDavid E. O'Brien     }
341c80476e4SDavid E. O'Brien 
342c80476e4SDavid E. O'Brien     if (termios_p->c_lflag & T_ECHO)
343c80476e4SDavid E. O'Brien     {
344c80476e4SDavid E. O'Brien 	sgbuf.sg_flags |= ECHO;
345c80476e4SDavid E. O'Brien     }
346c80476e4SDavid E. O'Brien     if (!(termios_p->c_lflag & ICANON))
347c80476e4SDavid E. O'Brien     {
348c80476e4SDavid E. O'Brien 	if (termios_p->c_lflag & ISIG)
349c80476e4SDavid E. O'Brien 	{
350c80476e4SDavid E. O'Brien 	     sgbuf.sg_flags |= CBREAK;
351c80476e4SDavid E. O'Brien 	}
352c80476e4SDavid E. O'Brien 	else
353c80476e4SDavid E. O'Brien 	{
354c80476e4SDavid E. O'Brien 	     sgbuf.sg_flags |= RAW;
355c80476e4SDavid E. O'Brien 	}
356c80476e4SDavid E. O'Brien     }
357c80476e4SDavid E. O'Brien 
358c80476e4SDavid E. O'Brien     switch (termios_p->c_cflag & CSIZE)
359c80476e4SDavid E. O'Brien     {
360c80476e4SDavid E. O'Brien 	case CS5: sgbuf.sg_flags |= BITS5; break;
361c80476e4SDavid E. O'Brien 	case CS6: sgbuf.sg_flags |= BITS6; break;
362c80476e4SDavid E. O'Brien 	case CS7: sgbuf.sg_flags |= BITS7; break;
363c80476e4SDavid E. O'Brien 	case CS8: sgbuf.sg_flags |= BITS8; break;
364c80476e4SDavid E. O'Brien     }
365c80476e4SDavid E. O'Brien     if (termios_p->c_cflag & PARENB)
366c80476e4SDavid E. O'Brien     {
367c80476e4SDavid E. O'Brien 	if (termios_p->c_cflag & PARODD)
368c80476e4SDavid E. O'Brien 	{
369c80476e4SDavid E. O'Brien 	    sgbuf.sg_flags |= ODDP;
370c80476e4SDavid E. O'Brien 	}
371c80476e4SDavid E. O'Brien 	else
372c80476e4SDavid E. O'Brien 	{
373c80476e4SDavid E. O'Brien 	    sgbuf.sg_flags |= EVENP;
374c80476e4SDavid E. O'Brien 	}
375c80476e4SDavid E. O'Brien     }
376c80476e4SDavid E. O'Brien 
377c80476e4SDavid E. O'Brien     sgbuf.sg_erase = termios_p->c_cc[VERASE];
378c80476e4SDavid E. O'Brien     sgbuf.sg_kill = termios_p->c_cc[VKILL];
379c80476e4SDavid E. O'Brien 
380c80476e4SDavid E. O'Brien     tcbuf.t_intrc = termios_p->c_cc[VINTR];
381c80476e4SDavid E. O'Brien     tcbuf.t_quitc = termios_p->c_cc[VQUIT];
382c80476e4SDavid E. O'Brien     tcbuf.t_startc = termios_p->c_cc[VSTART];
383c80476e4SDavid E. O'Brien     tcbuf.t_stopc = termios_p->c_cc[VSTOP];
384c80476e4SDavid E. O'Brien     tcbuf.t_eofc = termios_p->c_cc[VEOF];
385c80476e4SDavid E. O'Brien     tcbuf.t_brkc = termios_p->c_cc[VEOL];
386c80476e4SDavid E. O'Brien 
387c80476e4SDavid E. O'Brien     return ioctl(filedes, TIOCSETP, &sgbuf) < 0 &&
388c80476e4SDavid E. O'Brien 	   ioctl(filedes, TIOCSETC, (struct sgttyb *) &tcbuf) < 0 ?
389c80476e4SDavid E. O'Brien 		-1 : 0;
390c80476e4SDavid E. O'Brien }
3913b6eaa7bSAndrey A. Chernov #endif /* _MINIX && !_MINIX_VMD */
392