3 Copyright 1999, 2000, 2001 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
24 /* Common functions shared by tty/console */
27 fhandler_termios::tcinit (tty_min *this_tc, int force)
29 /* Initial termios values */
33 if (force || !TTYISSETF (INITIALIZED))
35 tc->ti.c_iflag = BRKINT | ICRNL | IXON;
36 tc->ti.c_oflag = OPOST | ONLCR;
37 tc->ti.c_cflag = B38400 | CS8 | CREAD;
38 tc->ti.c_lflag = ISIG | ICANON | ECHO | IEXTEN;
40 tc->ti.c_cc[VDISCARD] = CFLUSH;
41 tc->ti.c_cc[VEOL] = CEOL;
42 tc->ti.c_cc[VEOL2] = CEOL2;
43 tc->ti.c_cc[VEOF] = CEOF;
44 tc->ti.c_cc[VERASE] = CERASE;
45 tc->ti.c_cc[VINTR] = CINTR;
46 tc->ti.c_cc[VKILL] = CKILL;
47 tc->ti.c_cc[VLNEXT] = CLNEXT;
48 tc->ti.c_cc[VMIN] = 1;
49 tc->ti.c_cc[VQUIT] = CQUIT;
50 tc->ti.c_cc[VREPRINT] = CRPRNT;
51 tc->ti.c_cc[VSTART] = CSTART;
52 tc->ti.c_cc[VSTOP] = CSTOP;
53 tc->ti.c_cc[VSUSP] = CSUSP;
54 tc->ti.c_cc[VSWTC] = CSWTCH;
55 tc->ti.c_cc[VTIME] = 0;
56 tc->ti.c_cc[VWERASE] = CWERASE;
58 tc->ti.c_ispeed = tc->ti.c_ospeed = B38400;
59 tc->pgid = myself->pgid;
60 TTYSETF (INITIALIZED);
65 fhandler_termios::tcsetpgrp (const pid_t pgid)
67 termios_printf ("pgid %d, sid %d, tsid %d", pgid,
68 myself->sid, tc->getsid ());
69 if (myself->sid != tc->getsid ())
79 fhandler_termios::tcgetpgrp ()
85 fhandler_termios::set_ctty (int ttynum, int flags)
87 if ((myself->ctty < 0 || myself->ctty == ttynum) && !(flags & O_NOCTTY))
89 myself->ctty = ttynum;
90 syscall_printf ("attached tty%d sid %d, pid %d, tty->pgid %d, tty->sid %d",
91 ttynum, myself->sid, myself->pid, tc->pgid, tc->getsid ());
93 pinfo p (tc->getsid ());
94 if (myself->sid == myself->pid &&
95 (p == myself || !proc_exists (p)))
97 paranoid_printf ("resetting tty%d sid. Was %d, now %d. pgid was %d, now %d.",
98 ttynum, tc->getsid(), myself->sid, tc->getpgid (), myself->pgid);
99 /* We are the session leader */
100 tc->setsid (myself->sid);
101 tc->setpgid (myself->pgid);
104 myself->sid = tc->getsid ();
105 if (tc->getpgid () == 0)
106 tc->setpgid (myself->pgid);
111 fhandler_termios::bg_check (int sig)
113 if (!myself->pgid || tc->getpgid () == myself->pgid ||
114 myself->ctty != tc->ntty ||
115 ((sig == SIGTTOU) && !(tc->ti.c_lflag & TOSTOP)))
121 termios_printf("bg I/O pgid %d, tpgid %d, ctty %d",
122 myself->pgid, tc->getpgid (), myself->ctty);
124 if (tc->getsid () == 0)
126 /* The pty has been closed by the master. Return an EOF
127 indication. FIXME: There is nothing to stop somebody
128 from reallocating this pty. I think this is the case
129 which is handled by unlockpt on a Unix system. */
130 termios_printf ("closed by master");
134 /* If the process group is no more or if process is ignoring or blocks 'sig',
136 int pgid_gone = !pid_exists (myself->pgid);
138 ((void *) myself->getsig(sig).sa_handler == (void *) SIG_IGN) ||
139 (myself->getsigmask () & SIGTOMASK (sig));
143 else if (!sigs_ignored)
145 else if (sig == SIGTTOU)
146 return bg_ok; /* Just allow the output */
148 goto setEIO; /* This is an output error */
150 /* Don't raise a SIGTT* signal if we have already been interrupted
151 by another signal. */
152 if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
161 #define set_input_done(x) input_done = input_done || (x)
164 fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
169 int iscanon = tc->ti.c_lflag & ICANON;
175 termios_printf ("char %c", c);
177 /* Check for special chars */
181 if (tc->ti.c_iflag & IGNCR)
183 if (tc->ti.c_iflag & ICRNL)
186 set_input_done (iscanon);
191 if (tc->ti.c_iflag & INLCR)
194 set_input_done (iscanon);
197 if (tc->ti.c_iflag & ISTRIP)
199 if (tc->ti.c_lflag & ISIG)
202 if (c == tc->ti.c_cc[VINTR])
204 else if (c == tc->ti.c_cc[VQUIT])
206 else if (c == tc->ti.c_cc[VSUSP])
211 termios_printf ("got interrupt %d, sending signal %d", c, sig);
212 kill_pgrp (tc->getpgid (), sig);
213 tc->ti.c_lflag &= ~FLUSHO;
218 if (tc->ti.c_iflag & IXON)
220 if (c == tc->ti.c_cc[VSTOP])
222 if (!tc->OutputStopped)
224 tc->OutputStopped = 1;
225 acquire_output_mutex (INFINITE);
229 else if (c == tc->ti.c_cc[VSTART])
232 tc->OutputStopped = 0;
233 release_output_mutex ();
236 else if ((tc->ti.c_iflag & IXANY) && tc->OutputStopped)
239 if (tc->ti.c_lflag & IEXTEN && c == tc->ti.c_cc[VDISCARD])
241 tc->ti.c_lflag ^= FLUSHO;
246 else if (c == tc->ti.c_cc[VERASE])
248 if (eat_readahead (1))
252 else if (c == tc->ti.c_cc[VWERASE])
256 if (!eat_readahead (1))
260 while ((ch = peek_readahead (1)) >= 0 && !isspace (ch));
263 else if (c == tc->ti.c_cc[VKILL])
265 int nchars = eat_readahead (-1);
270 else if (c == tc->ti.c_cc[VREPRINT])
273 doecho (rabuf, ralen);
276 else if (c == tc->ti.c_cc[VEOF])
278 termios_printf ("EOF");
282 else if (c == tc->ti.c_cc[VEOL] ||
283 c == tc->ti.c_cc[VEOL2] ||
287 termios_printf ("EOL");
290 if (tc->ti.c_iflag & IUCLC && isupper (c))
293 if (tc->ti.c_lflag & ECHO)
298 if (!iscanon || always_accept)
299 set_input_done (ralen > 0);
304 (void) accept_input ();
310 fhandler_termios::fixup_after_fork (HANDLE parent)
312 this->fhandler_base::fixup_after_fork (parent);
313 fork_fixup (parent, get_output_handle (), "output_handle");