2 static char *RCSid() { return RCSid("$Id: readline.c,v 1.41.2.2 2008/12/12 06:57:50 sfeam Exp $"); }
5 /* GNUPLOT - readline.c */
8 * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
10 * Permission to use, copy, and distribute this software and its
11 * documentation for any purpose with or without fee is hereby granted,
12 * provided that the above copyright notice appear in all copies and
13 * that both that copyright notice and this permission notice appear
14 * in supporting documentation.
16 * Permission to modify the software is granted, but not the right to
17 * distribute the complete modified source code. Modifications are to
18 * be distributed as patches to the released version. Permission to
19 * distribute binaries produced by compiling modified sources is granted,
21 * 1. distribute the corresponding source modifications from the
22 * released version in the form of a patch file along with the binaries,
23 * 2. add special version identification to distinguish your version
24 * in addition to the base release version number,
25 * 3. provide your name and address as the primary contact for the
26 * support of your modified version, and
27 * 4. retain our contact information in regard to use of the base
29 * Permission to distribute the released version of the source code along
30 * with corresponding source modifications in the form of a patch file is
31 * granted with same provisions 2 through 4 for binary distributions.
33 * This software is provided "as is" without express or implied warranty
34 * to the extent permitted by applicable law.
44 * Msdos port and some enhancements:
45 * Gershon Elber and many others.
60 #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)
61 /* #include <readline/readline.h> --- HBB 20000508: now included by readline.h*/
62 /* #include <readline/history.h> --- HBB 20000508: now included by gp_hist */
65 static char* line_buffer;
66 static int line_complete;
69 * called by libreadline or editline if the input
70 * was typed (not from the ipc).
73 LineCompleteHandler(char* ptr)
75 rl_callback_handler_remove();
80 #if defined(HAVE_LIBEDITLINE)
85 #if defined(HAVE_LIBEDITLINE)
86 getc_wrapper(FILE* fp /* is NULL, supplied by libedit */)
88 getc_wrapper(FILE* fp /* should be stdin, supplied by readline */)
95 if (term && term->waitforinput && interactive) {
96 c = term->waitforinput();
100 #if defined(HAVE_LIBEDITLINE)
105 if (c == EOF && errno == EINTR)
111 #endif /* HAVE_LIBREADLINE || HAVE_LIBEDITLINE */
113 #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE) || defined(READLINE)
115 readline_ipc(const char* prompt)
117 #if defined(PIPE_IPC) && defined(HAVE_LIBREADLINE)
118 /* use readline's alternate interface.
119 * this requires rl_library_version > 2.2
120 * TODO: make a check in configure.in */
122 rl_callback_handler_install((char*) prompt, LineCompleteHandler);
123 rl_getc_function = getc_wrapper;
125 for (line_complete = 0; !line_complete; /* EMPTY */) {
126 rl_callback_read_char(); /* stdin */
130 return readline((const char*) prompt);
133 #endif /* defined(HAVE_LIBREADLINE) || define(READLINE) */
136 #if defined(READLINE) && !(defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE))
138 /* a small portable version of GNU's readline
139 * this is not the BASH or GNU EMACS version of READLINE due to Copyleft
141 * do not need any terminal capabilities except backspace,
142 * and space overwrites a character
145 /* NANO-EMACS line editing facility
146 * printable characters print as themselves (insert not overwrite)
147 * ^A moves to the beginning of the line
148 * ^B moves back a single character
149 * ^E moves to the end of the line
150 * ^F moves forward a single character
151 * ^K kills from current position to the end of line
152 * ^P moves back through history
153 * ^N moves forward through history
154 * ^H and DEL delete the previous character
155 * ^D deletes the current character, or EOF if line is empty
156 * ^L/^R redraw line in case it gets trashed
157 * ^U kills the entire line
159 * LF and CR return the entire line regardless of the cursor postition
160 * EOF with an empty line returns (char *)NULL
162 * all other characters are ignored
165 #ifdef HAVE_SYS_IOCTL_H
166 /* For ioctl() prototype under Linux (and BeOS?) */
167 # include <sys/ioctl.h>
170 /* replaces the previous klugde in configure */
171 #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCGETATTR)
173 #else /* not HAVE_TERMIOS_H && HAVE_TCGETATTR */
177 #endif /* not HAVE_TERMIOS_H && HAVE_TCGETATTR */
179 #if !defined(MSDOS) && !defined(ATARI) && !defined(MTOS) && !defined(_Windows) && !defined(DOS386) && !defined(OSK)
182 * Set up structures using the proper include file
184 # if defined(_IBMR2) || defined(alliant)
188 /* submitted by Francois.Dagorn@cicb.fr */
191 static struct sgttyb orig_termio, rl_termio;
192 /* define terminal control characters */
193 static struct tchars s_tchars;
196 # endif /* not VERASE */
199 # endif /* not VEOF */
202 # endif /* not VKILL */
203 # ifdef TIOCGLTC /* available only with the 'new' line discipline */
204 static struct ltchars s_ltchars;
207 # endif /* not VWERASE */
210 # endif /* not VREPRINT */
213 # endif /* not VSUP */
214 # endif /* TIOCGLTC */
217 # endif /* not NCCS */
219 # else /* not SGTTY */
221 /* SIGTSTP defines job control
222 * if there is job control then we need termios.h instead of termio.h
223 * (Are there any systems with job control that use termio.h? I hope not.)
225 # if defined(SIGTSTP) || defined(TERMIOS)
228 # endif /* not TERMIOS */
229 # include <termios.h>
230 /* Added by Robert Eckardt, RobertE@beta.TP2.Ruhr-Uni-Bochum.de */
232 # ifndef ONOCR /* taken from sys/termio.h */
233 # define ONOCR 0000020 /* true at least for ISC 2.2 */
234 # endif /* not ONOCR */
236 # define IUCLC 0001000
237 # endif /* not IUCLC */
240 /* translate upper to lower case not supported */
242 # endif /* not IUCLC */
244 static struct termios orig_termio, rl_termio;
245 # else /* not SIGSTP || TERMIOS */
247 static struct termio orig_termio, rl_termio;
248 /* termio defines NCC instead of NCCS */
250 # endif /* not SIGTSTP || TERMIOS */
253 /* ULTRIX defines VRPRNT instead of VREPRINT */
254 # if defined(VRPRNT) && !defined(VREPRINT)
255 # define VREPRINT VRPRNT
258 /* define characters to use with our input character handler */
259 static char term_chars[NCCS];
261 static int term_set = 0; /* =1 if rl_termio set */
263 #define special_getc() ansi_getc()
264 static int ansi_getc __PROTO((void));
266 #else /* MSDOS or ATARI or MTOS or _Windows or DOS386 or OSK */
269 # include <windows.h>
270 # include "win/wtext.h"
271 # include "win/winmain.h"
272 # define TEXTUSER 0xf1
273 # define TEXTGNUPLOT 0xf0
274 # define special_getc() msdos_getch()
275 static char msdos_getch __PROTO((void)); /* HBB 980308: PROTO'ed it */
276 # endif /* _Windows */
278 # if defined(MSDOS) || defined(DOS386)
279 /* MSDOS specific stuff */
283 # if defined(__EMX__) || defined (__WATCOMC__)
285 # endif /* __EMX__ */
286 # define special_getc() msdos_getch()
287 static char msdos_getch();
288 # endif /* MSDOS || DOS386 */
295 static int term_set = 0; /* =1 if new_settings is set */
297 static struct _sgs old_settings; /* old terminal settings */
298 static struct _sgs new_settings; /* new terminal settings */
300 # define special_getc() ansi_getc()
301 static int ansi_getc __PROTO((void));
303 /* On OS9 a '\n' is a character 13 and '\r' == '\n'. This gives troubles
304 here, so we need a new putc wich handles this correctly and print a
305 character 10 on each place we want a '\n'.
307 # undef putc /* Undefine the macro for putc */
310 putc(char c, FILE *fp)
312 write(fileno(fp), &c, 1);
313 if (c == '\012') { /* A normal ASCII '\n' */
315 write(fileno(fp), &c, 1);
321 # if defined(ATARI) || defined(MTOS)
322 # define special_getc() tos_getch()
323 # endif /* ATARI || MTOS */
325 #endif /* MSDOS or ATARI or MTOS or _Windows or DOS386 or OSK */
328 # if defined( special_getc )
329 # undef special_getc()
330 # endif /* special_getc */
331 # define special_getc() os2_getch()
332 static char msdos_getch __PROTO((void)); /* HBB 980308: PROTO'ed it */
333 static char os2_getch __PROTO((void));
337 /* initial size and increment of input line length */
339 #define BACKSPACE 0x08 /* ^H */
343 # define NEWLINE '\012'
345 # define NEWLINE '\n'
348 static char *cur_line; /* current contents of the line */
349 static size_t line_len = 0;
350 static size_t cur_pos = 0; /* current position of the cursor */
351 static size_t max_pos = 0; /* maximum character position */
353 static void fix_line __PROTO((void));
354 static void redraw_line __PROTO((const char *prompt));
355 static void clear_line __PROTO((const char *prompt));
356 static void clear_eoline __PROTO((void));
357 static void copy_line __PROTO((char *line));
358 static void set_termio __PROTO((void));
359 static void reset_termio __PROTO((void));
360 static int user_putc __PROTO((int ch));
361 static int user_puts __PROTO((char *str));
362 static void backspace __PROTO((void));
363 static void extend_cur_line __PROTO((void));
366 /* user_putc and user_puts should be used in the place of
367 * fputc(ch,stderr) and fputs(str,stderr) for all output
368 * of user typed characters. This allows MS-Windows to
369 * display user input in a different color.
376 TextAttr(&textwin, TEXTUSER);
378 rv = fputc(ch, stderr);
380 TextAttr(&textwin, TEXTGNUPLOT);
390 TextAttr(&textwin, TEXTUSER);
392 rv = fputs(str, stderr);
394 TextAttr(&textwin, TEXTGNUPLOT);
399 /* This function provides a centralized non-destructive backspace capability
405 user_putc(BACKSPACE);
413 /* extent input line length */
414 new_line = gp_realloc(cur_line, line_len + MAXBUF, NULL);
417 int_error(NO_CARET, "Can't extend readline length");
421 FPRINTF((stderr, "\nextending readline length to %d chars\n", line_len));
425 readline(const char *prompt)
431 /* start with a string of MAXBUF chars */
436 cur_line = gp_alloc(MAXBUF, "readline");
439 /* set the termio so we can do our own input processing */
442 /* print the prompt */
443 fputs(prompt, stderr);
452 cur_char = special_getc();
454 /* The #define CHARSET7BIT should be used when one encounters
455 * problems with 8bit characters that should not be entered on
456 * the commandline. I cannot think on any reasonable example
457 * where this could happen, but what do I know? After all,
458 * the unix world still ignores 8bit chars in most
461 * Note that latin1 defines the chars 0x80-0x9f as control
462 * chars. For the benefit of Atari, MSDOS, Windows and NeXT I
463 * have decided to ignore this, since it would require more
466 if (isprint(cur_char)
468 /* || ((unsigned char) cur_char == 011) */ /* EAM allowing <tab> breaks auto-completion! */
469 || (((unsigned char) cur_char > 0x7f) && cur_char != EOF)
470 #endif /* CHARSET7BIT */
474 if (max_pos + 1 >= line_len) {
477 for (i = max_pos; i > cur_pos; i--) {
478 cur_line[i] = cur_line[i - 1];
481 cur_line[cur_pos] = cur_char;
484 if (cur_pos < max_pos)
486 cur_line[max_pos] = '\0';
488 /* else interpret unix terminal driver characters */
490 } else if (cur_char == term_chars[VERASE]) { /* DEL? */
495 for (i = cur_pos; i < max_pos; i++)
496 cur_line[i] = cur_line[i + 1];
502 } else if (cur_char == term_chars[VEOF]) { /* ^D? */
505 return ((char *) NULL);
507 if ((cur_pos < max_pos) && (cur_char == 004)) { /* ^D */
509 for (i = cur_pos; i < max_pos; i++)
510 cur_line[i] = cur_line[i + 1];
516 } else if (cur_char == term_chars[VKILL]) { /* ^U? */
520 } else if (cur_char == term_chars[VWERASE]) { /* ^W? */
521 while ((cur_pos > 0) &&
522 (cur_line[cur_pos - 1] == SPACE)) {
526 while ((cur_pos > 0) &&
527 (cur_line[cur_pos - 1] != SPACE)) {
535 } else if (cur_char == term_chars[VREPRINT]) { /* ^R? */
536 putc(NEWLINE, stderr); /* go to a fresh line */
538 #endif /* VREPRINT */
540 } else if (cur_char == term_chars[VSUSP]) {
544 /* process stops here */
547 /* print the prompt */
551 /* do normal editing commands */
552 /* some of these are also done above */
557 return ((char *) NULL);
559 while (cur_pos > 0) {
571 while (cur_pos < max_pos) {
572 user_putc(cur_line[cur_pos]);
577 if (cur_pos < max_pos) {
578 user_putc(cur_line[cur_pos]);
587 if (history != NULL) {
588 if (cur_entry == NULL) {
591 copy_line(cur_entry->line);
592 } else if (cur_entry->prev != NULL) {
593 cur_entry = cur_entry->prev;
595 copy_line(cur_entry->line);
600 if (cur_entry != NULL) {
601 cur_entry = cur_entry->next;
603 if (cur_entry != NULL)
604 copy_line(cur_entry->line);
606 cur_pos = max_pos = 0;
611 putc(NEWLINE, stderr); /* go to a fresh line */
619 for (i = cur_pos; i < max_pos; i++)
620 cur_line[i] = cur_line[i + 1];
628 return ((char *) NULL);
630 if (cur_pos < max_pos) {
631 for (i = cur_pos; i < max_pos; i++)
632 cur_line[i] = cur_line[i + 1];
641 while ((cur_pos > 0) &&
642 (cur_line[cur_pos - 1] == SPACE)) {
646 while ((cur_pos > 0) &&
647 (cur_line[cur_pos - 1] != SPACE)) {
658 cur_line[max_pos + 1] = '\0';
660 while (cur_pos < max_pos) {
661 user_putc(cur_line[cur_pos]);
665 putc(NEWLINE, stderr);
667 /* Shrink the block down to fit the string ?
668 * if the alloc fails, we still own block at cur_line,
669 * but this shouldn't really fail.
671 new_line = (char *) gp_realloc(cur_line, strlen(cur_line) + 1,
675 /* else we just hang on to what we had - it's not a problem */
678 FPRINTF((stderr, "Resizing input line to %d chars\n", strlen(cur_line)));
688 /* fix up the line from cur_pos to max_pos
689 * do not need any terminal capabilities except backspace,
690 * and space overwrites a character
697 /* write tail of string */
698 for (i = cur_pos; i < max_pos; i++)
699 user_putc(cur_line[i]);
701 /* write a space at the end of the line in case we deleted one */
704 /* backup to original position */
705 for (i = max_pos + 1; i > cur_pos; i--)
710 /* redraw the entire line, putting the cursor where it belongs */
712 redraw_line(const char *prompt)
716 fputs(prompt, stderr);
719 /* put the cursor where it belongs */
720 for (i = max_pos; i > cur_pos; i--)
724 /* clear cur_line and the screen line */
726 clear_line(const char *prompt)
729 for (i = 0; i < max_pos; i++)
732 for (i = cur_pos; i > 0; i--)
735 for (i = 0; i < max_pos; i++)
739 fputs(prompt, stderr);
745 /* clear to end of line and the screen end of line */
750 for (i = cur_pos; i < max_pos; i++)
753 for (i = cur_pos; i < max_pos; i++)
755 for (i = cur_pos; i < max_pos; i++)
759 /* copy line to cur_line, draw it and set cur_pos and max_pos */
761 copy_line(char *line)
763 while (strlen(line) + 1 > line_len) {
766 strcpy(cur_line, line);
768 cur_pos = max_pos = strlen(cur_line);
771 #if !defined(MSDOS) && !defined(ATARI) && !defined(MTOS) && !defined(_Windows) && !defined(DOS386) && !defined(OSK)
772 /* Convert ANSI arrow keys to control characters */
779 if (term && term->waitforinput && interactive)
780 c = term->waitforinput();
786 c = getc(stdin); /* check for CSI */
788 c = getc(stdin); /* get command character */
790 case 'D': /* left arrow key */
793 case 'C': /* right arrow key */
796 case 'A': /* up arrow key */
799 case 'B': /* down arrow key */
802 case 'F': /* end key */
805 case 'H': /* home key */
815 #if defined(MSDOS) || defined(_Windows) || defined(DOS386) || defined(OS2)
817 /* Convert Arrow keystrokes to Control characters: */
825 c = (ch & 0xff00) ? 0 : ch & 0xff;
828 #else /* not OS2, not DJGPP*/
829 # if defined (_Windows) && defined (USE_MOUSE)
830 if (term && term->waitforinput && interactive)
831 c = term->waitforinput();
833 # endif /* not _Windows && not USE_MOUSE */
835 #endif /* not DJGPP, not OS2 */
840 #else /* not DJGPP */
844 c = getch(); /* Get the extended code. */
846 #endif /* not DJGPP */
849 case 75: /* Left Arrow. */
852 case 77: /* Right Arrow. */
855 case 72: /* Up Arrow. */
858 case 80: /* Down Arrow. */
861 case 115: /* Ctl Left Arrow. */
865 case 116: /* Ctl Right Arrow. */
869 case 83: /* Delete */
876 } else if (c == 033) { /* ESC */
882 #endif /* MSDOS || _Windows || DOS386 || OS2 */
885 /* We need to call different procedures, dependent on the
886 session type: VIO/window or an (XFree86) xterm */
889 static int IsXterm = 0;
893 if (getenv("WINDOWID")) {
901 return msdos_getch();
906 #if defined(ATARI) || defined(MTOS)
908 /* Convert Arrow keystrokes to Control characters: TOS version */
910 /* from term/atariaes.trm: */
911 long poll_events(int);
913 /* this function is used in help.c as well. this means that the
914 * program doesn't work without -DREADLINE (which would be the case
915 * if help.c didn't use it as well, since no events would be processed)
923 static int in_help = 0;
925 if (strcmp(term->name, "atari") == 0)
950 if (strcmp(term->name, "atari") == 0) {
955 rawkey = poll_events(1);
956 } while (rawkey == 0);
961 scan_code = ((int) (rawkey >> 16)) & 0xff; /* get the scancode */
962 if (Kbshift(-1) & 0x00000007)
963 scan_code |= 0x80; /* shift or control ? */
966 case 0x62: /* HELP */
967 case 0xe2: /* shift HELP */
969 if (scan_code == 0x62) {
978 case 0x48: /* Up Arrow */
979 return 0x10; /* ^P */
980 case 0x50: /* Down Arrow */
981 return 0x0e; /* ^N */
982 case 0x4b: /* Left Arrow */
983 return 0x02; /* ^B */
984 case 0x4d: /* Right Arrow */
985 return 0x06; /* ^F */
986 case 0xcb: /* Shift Left Arrow */
987 case 0xf3: /* Ctrl Left Arrow (TOS-bug ?) */
988 case 0x47: /* Home */
989 return 0x01; /* ^A */
990 case 0xcd: /* Shift Right Arrow */
991 case 0xf4: /* Ctrl Right Arrow (TOS-bug ?) */
992 case 0xc7: /* Shift Home */
993 case 0xf7: /* Ctrl Home */
994 return 0x05; /* ^E */
995 case 0x61: /* Undo - redraw line */
996 return 0x0c; /* ^L */
999 return 0x15; /* ESC becomes ^U */
1001 return 0x04; /* Del becomes ^D */
1007 #endif /* ATARI || MTOS */
1009 /* set termio so we can do our own input processing */
1013 #if !defined(MSDOS) && !defined(ATARI) && !defined(MTOS) && !defined(_Windows) && !defined(DOS386)
1014 /* set termio so we can do our own input processing */
1015 /* and save the old terminal modes so we can reset them later */
1016 if (term_set == 0) {
1018 * Get terminal modes.
1022 ioctl(0, TIOCGETP, &orig_termio);
1023 # else /* not SGTTY */
1026 ioctl(0, TCGETS, &orig_termio);
1027 # else /* not TCGETS */
1028 tcgetattr(0, &orig_termio);
1029 # endif /* not TCGETS */
1030 # else /* not TERMIOS */
1031 ioctl(0, TCGETA, &orig_termio);
1032 # endif /* TERMIOS */
1033 # endif /* not SGTTY */
1035 setbuf(stdin, (char *) 0); /* Make stdin and stdout unbuffered */
1036 setbuf(stderr, (char *) 0);
1037 _gs_opt(STDIN, &new_settings);
1041 * Save terminal modes
1044 rl_termio = orig_termio;
1046 _gs_opt(STDIN, &old_settings);
1050 * Set the modes to the way we want them
1051 * and save our input special characters
1055 rl_termio.sg_flags |= CBREAK;
1056 rl_termio.sg_flags &= ~(ECHO | XTABS);
1057 ioctl(0, TIOCSETN, &rl_termio);
1059 ioctl(0, TIOCGETC, &s_tchars);
1060 term_chars[VERASE] = orig_termio.sg_erase;
1061 term_chars[VEOF] = s_tchars.t_eofc;
1062 term_chars[VKILL] = orig_termio.sg_kill;
1064 ioctl(0, TIOCGLTC, &s_ltchars);
1065 term_chars[VWERASE] = s_ltchars.t_werasc;
1066 term_chars[VREPRINT] = s_ltchars.t_rprntc;
1067 term_chars[VSUSP] = s_ltchars.t_suspc;
1069 /* disable suspending process on ^Z */
1070 s_ltchars.t_suspc = 0;
1071 ioctl(0, TIOCSLTC, &s_ltchars);
1072 # endif /* TIOCGLTC */
1073 # else /* not SGTTY */
1074 rl_termio.c_iflag &= ~(BRKINT | PARMRK | INPCK | IUCLC | IXON | IXOFF);
1075 rl_termio.c_iflag |= (IGNBRK | IGNPAR);
1077 /* rl_termio.c_oflag &= ~(ONOCR); Costas Sphocleous Irvine,CA */
1079 rl_termio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | NOFLSH);
1081 /* for emx: remove default terminal processing */
1082 rl_termio.c_lflag &= ~(IDEFAULT);
1084 rl_termio.c_lflag |= (ISIG);
1085 rl_termio.c_cc[VMIN] = 1;
1086 rl_termio.c_cc[VTIME] = 0;
1090 # endif /* VWERASE */
1091 term_chars[VERASE] = orig_termio.c_cc[VERASE];
1092 term_chars[VEOF] = orig_termio.c_cc[VEOF];
1093 term_chars[VKILL] = orig_termio.c_cc[VKILL];
1095 term_chars[VWERASE] = orig_termio.c_cc[VWERASE];
1097 term_chars[VREPRINT] = orig_termio.c_cc[VREPRINT];
1098 # else /* not VREPRINT */
1100 term_chars[VRPRNT] = orig_termio.c_cc[VRPRNT];
1101 # endif /* VRPRNT */
1102 # endif /* not VREPRINT */
1103 term_chars[VSUSP] = orig_termio.c_cc[VSUSP];
1105 /* disable suspending process on ^Z */
1106 rl_termio.c_cc[VSUSP] = 0;
1107 # endif /* TERMIOS */
1108 # endif /* not SGTTY */
1110 new_settings._sgs_echo = 0; /* switch off terminal echo */
1111 new_settings._sgs_pause = 0; /* inhibit page pause */
1112 new_settings._sgs_eofch = 0; /* inhibit eof */
1113 new_settings._sgs_kbich = 0; /* inhibit ^C */
1114 new_settings._sgs_kbach = 0; /* inhibit ^E */
1118 * Set the new terminal modes.
1122 ioctl(0, TIOCSLTC, &s_ltchars);
1123 # else /* not SGTTY */
1126 ioctl(0, TCSETSW, &rl_termio);
1127 # else /* not TCSETSW */
1128 tcsetattr(0, TCSADRAIN, &rl_termio);
1129 # endif /* not TCSETSW */
1130 # else /* not TERMIOS */
1131 ioctl(0, TCSETAW, &rl_termio);
1132 # endif /* not TERMIOS */
1133 # endif /* not SGTTY */
1135 _ss_opt(STDIN, &new_settings);
1139 #endif /* not MSDOS && not ATARI && not MTOS && not _Windows && not DOS386 */
1145 #if !defined(MSDOS) && !defined(ATARI) && !defined(MTOS) && !defined(_Windows) && !defined(DOS386)
1146 /* reset saved terminal modes */
1147 if (term_set == 1) {
1150 ioctl(0, TIOCSETN, &orig_termio);
1152 /* enable suspending process on ^Z */
1153 s_ltchars.t_suspc = term_chars[VSUSP];
1154 ioctl(0, TIOCSLTC, &s_ltchars);
1155 # endif /* TIOCGLTC */
1156 # else /* not SGTTY */
1159 ioctl(0, TCSETSW, &orig_termio);
1160 # else /* not TCSETSW */
1161 tcsetattr(0, TCSADRAIN, &orig_termio);
1162 # endif /* not TCSETSW */
1163 # else /* not TERMIOS */
1164 ioctl(0, TCSETAW, &orig_termio);
1165 # endif /* TERMIOS */
1166 # endif /* not SGTTY */
1168 _ss_opt(STDIN, &old_settings);
1172 #endif /* not MSDOS && not ATARI && not MTOS && not _Windows && not DOS386 */
1175 #endif /* READLINE && !HAVE_LIBREADLINE */