Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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__) && !defined(PLAN9)
114
	if ((tfd = open("/dev/tty", O_RDWR, 0)) < 0) {
115
#ifdef __NeXT
116
		/* rlogin on NeXT boxes does not set up the controlling tty,
117
		 * so force it to be done here...
118
		 */
119
		{
120
			extern char *ttyname ARGS((int));
121
			char *s = ttyname(isatty(2) ? 2 : 0);
122
			int fd;
123
 
124
			if (s && (fd = open(s, O_RDWR, 0)) >= 0) {
125
				close(fd);
126
				tfd = open("/dev/tty", O_RDWR, 0);
127
			}
128
		}
129
#endif /* __NeXT */
130
 
131
/* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */
132
# if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
133
		if (tfd < 0) {
134
			tty_devtty = 0;
135
			warningf(FALSE,
136
				"No controlling tty (open /dev/tty: %s)",
137
				strerror(errno));
138
		}
139
# endif /* __mips  */
140
	}
141
#else /* !__SCO__ */
142
	tfd = -1;
143
#endif /* __SCO__ */
144
 
145
	if (tfd < 0) {
146
		do_close = 0;
147
		if (isatty(0))
148
			tfd = 0;
149
		else if (isatty(2))
150
			tfd = 2;
151
		else {
152
			warningf(FALSE, "Can't find tty file descriptor");
153
			return;
154
		}
155
	}
156
	if ((tty_fd = ksh_dupbase(tfd, FDBASE)) < 0) {
157
		warningf(FALSE, "j_ttyinit: dup of tty fd failed: %s",
158
			strerror(errno));
159
	} else if (fd_clexec(tty_fd) < 0) {
160
		warningf(FALSE, "j_ttyinit: can't set close-on-exec flag: %s",
161
			strerror(errno));
162
		close(tty_fd);
163
		tty_fd = -1;
164
	} else if (init_ttystate)
165
		get_tty(tty_fd, &tty_state);
166
	if (do_close)
167
		close(tfd);
168
}
169
 
170
void
171
tty_close()
172
{
173
	if (tty_fd >= 0) {
174
		close(tty_fd);
175
		tty_fd = -1;
176
	}
177
}