tty.c revision 1.1 1 #include "sh.h"
2 #include "ksh_stat.h"
3 #define EXTERN
4 #include "tty.h"
5 #undef EXTERN
6
7 int
8 get_tty(fd, ts)
9 int fd;
10 TTY_state *ts;
11 {
12 int ret;
13
14 # ifdef HAVE_TERMIOS_H
15 ret = tcgetattr(fd, ts);
16 # else /* HAVE_TERIOS_H */
17 # ifdef HAVE_TERMIO_H
18 ret = ioctl(fd, TCGETA, ts);
19 # else /* HAVE_TERMIO_H */
20 ret = ioctl(fd, TIOCGETP, &ts->sgttyb);
21 # ifdef TIOCGATC
22 if (ioctl(fd, TIOCGATC, &ts->lchars) < 0)
23 ret = -1;
24 # else
25 if (ioctl(fd, TIOCGETC, &ts->tchars) < 0)
26 ret = -1;
27 # ifdef TIOCGLTC
28 if (ioctl(fd, TIOCGLTC, &ts->ltchars) < 0)
29 ret = -1;
30 # endif /* TIOCGLTC */
31 # endif /* TIOCGATC */
32 # endif /* HAVE_TERMIO_H */
33 # endif /* HAVE_TERIOS_H */
34 return ret;
35 }
36
37 int
38 set_tty(fd, ts, flags)
39 int fd;
40 TTY_state *ts;
41 int flags;
42 {
43 int ret = 0;
44
45 # ifdef HAVE_TERMIOS_H
46 ret = tcsetattr(fd, TCSADRAIN, ts);
47 # else /* HAVE_TERIOS_H */
48 # ifdef HAVE_TERMIO_H
49 # ifndef TCSETAW /* e.g. Cray-2 */
50 /* first wait for output to drain */
51 # ifdef TCSBRK
52 if (ioctl(tty_fd, TCSBRK, 1) < 0)
53 ret = -1;
54 # else /* the following kludge is minimally intrusive, but sometimes fails */
55 if (flags & TF_WAIT)
56 sleep((unsigned)1); /* fake it */
57 # endif
58 # endif /* !TCSETAW */
59 # if defined(_BSD_SYSV) || !defined(TCSETAW)
60 /* _BSD_SYSV must force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
61 if (ioctl(tty_fd, TCSETA, ts) < 0)
62 ret = -1;
63 # else
64 if (ioctl(tty_fd, TCSETAW, ts) < 0)
65 ret = -1;
66 # endif
67 # else /* HAVE_TERMIO_H */
68 # if defined(__mips) && (defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
69 /* Under RISC/os 5.00, bsd43 environment, after a tty driver
70 * generated interrupt (eg, INTR, TSTP), all output to tty is
71 * lost until a SETP is done (there must be a better way of
72 * doing this...).
73 */
74 if (flags & TF_MIPSKLUDGE)
75 ret = ioctl(fd, TIOCSETP, &ts->sgttyb);
76 else
77 # endif /* _SYSTYPE_BSD43 */
78 ret = ioctl(fd, TIOCSETN, &ts->sgttyb);
79 # ifdef TIOCGATC
80 if (ioctl(fd, TIOCSATC, &ts->lchars) < 0)
81 ret = -1;
82 # else
83 if (ioctl(fd, TIOCSETC, &ts->tchars) < 0)
84 ret = -1;
85 # ifdef TIOCGLTC
86 if (ioctl(fd, TIOCSLTC, &ts->ltchars) < 0)
87 ret = -1;
88 # endif /* TIOCGLTC */
89 # endif /* TIOCGATC */
90 # endif /* HAVE_TERMIO_H */
91 # endif /* HAVE_TERIOS_H */
92 return ret;
93 }
94
95
96 /* Initialize tty_fd. Used for saving/reseting tty modes upon
97 * foreground job completion and for setting up tty process group.
98 */
99 void
100 tty_init(init_ttystate)
101 int init_ttystate;
102 {
103 int do_close = 1;
104 int tfd;
105
106 if (tty_fd >= 0) {
107 close(tty_fd);
108 tty_fd = -1;
109 }
110 tty_devtty = 1;
111
112 /* SCO can't job control on /dev/tty, so don't try... */
113 #if !defined(__SCO__)
114 if ((tfd = open("/dev/tty", O_RDWR, 0)) < 0) {
115 /* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */
116 # if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
117 tty_devtty = 0;
118 warningf(FALSE, "No controlling tty (open /dev/tty: %s)",
119 strerror(errno));
120 # endif /* __mips */
121 }
122 #else /* !__SCO__ */
123 tfd = -1;
124 #endif /* __SCO__ */
125
126 if (tfd < 0) {
127 do_close = 0;
128 if (isatty(0))
129 tfd = 0;
130 else if (isatty(2))
131 tfd = 2;
132 else {
133 warningf(FALSE, "Can't find tty file descriptor");
134 return;
135 }
136 }
137 if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
138 warningf(FALSE, "j_ttyinit: dup of tty fd failed: %s",
139 strerror(errno));
140 } else if (fd_clexec(tty_fd) < 0) {
141 warningf(FALSE, "j_ttyinit: can't set close-on-exec flag: %s",
142 strerror(errno));
143 close(tty_fd);
144 tty_fd = -1;
145 } else if (init_ttystate)
146 get_tty(tty_fd, &tty_state);
147 if (do_close)
148 close(tfd);
149 }
150
151 void
152 tty_close()
153 {
154 if (tty_fd >= 0) {
155 close(tty_fd);
156 tty_fd = -1;
157 }
158 }
159