3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009,
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
23 /* Common functions shared by tty/console */
26 fhandler_termios::tcinit (tty_min *this_tc, bool is_pty_master)
28 /* Initial termios values */
32 if (is_pty_master || !tc->initialized ())
34 tc->ti.c_iflag = BRKINT | ICRNL | IXON;
35 tc->ti.c_oflag = OPOST | ONLCR;
36 tc->ti.c_cflag = B38400 | CS8 | CREAD;
37 tc->ti.c_lflag = ISIG | ICANON | ECHO | IEXTEN;
39 tc->ti.c_cc[VDISCARD] = CFLUSH;
40 tc->ti.c_cc[VEOL] = CEOL;
41 tc->ti.c_cc[VEOL2] = CEOL2;
42 tc->ti.c_cc[VEOF] = CEOF;
43 tc->ti.c_cc[VERASE] = CERASE;
44 tc->ti.c_cc[VINTR] = CINTR;
45 tc->ti.c_cc[VKILL] = CKILL;
46 tc->ti.c_cc[VLNEXT] = CLNEXT;
47 tc->ti.c_cc[VMIN] = 1;
48 tc->ti.c_cc[VQUIT] = CQUIT;
49 tc->ti.c_cc[VREPRINT] = CRPRNT;
50 tc->ti.c_cc[VSTART] = CSTART;
51 tc->ti.c_cc[VSTOP] = CSTOP;
52 tc->ti.c_cc[VSUSP] = CSUSP;
53 tc->ti.c_cc[VSWTC] = CSWTCH;
54 tc->ti.c_cc[VTIME] = 0;
55 tc->ti.c_cc[VWERASE] = CWERASE;
57 tc->ti.c_ispeed = tc->ti.c_ospeed = B38400;
58 tc->pgid = is_pty_master ? 0 : myself->pgid;
59 tc->initialized (true);
64 fhandler_termios::tcsetpgrp (const pid_t pgid)
66 termios_printf ("tty %d pgid %d, sid %d, tsid %d", tc->ntty, pgid,
67 myself->sid, tc->getsid ());
68 if (myself->sid != tc->getsid ())
76 res = bg_check (-SIGTTOU);
82 init_console_handler (tc->gethwnd ());
86 if (_my_tls.call_signal_handler ())
89 /* fall through intentionally */
100 fhandler_termios::tcgetpgrp ()
102 if (myself->ctty != -1 && myself->ctty == tc->ntty)
109 fhandler_pty_master::tcgetpgrp ()
115 tty_min::kill_pgrp (int sig)
118 winpids pids ((DWORD) PID_MAP_RW);
121 si.si_code = SI_KERNEL;
122 for (unsigned i = 0; i < pids.npids; i++)
125 if (!p->exists () || p->ctty != ntty || p->pgid != pgid)
133 sig_send (myself, si);
137 fhandler_termios::bg_check (int sig)
139 if (!myself->pgid || tc->getpgid () == myself->pgid ||
140 myself->ctty != tc->ntty ||
141 ((sig == SIGTTOU) && !(tc->ti.c_lflag & TOSTOP)))
147 termios_printf ("bg I/O pgid %d, tpgid %d, %s, ntty tty%d", myself->pgid, tc->getpgid (),
148 myctty (), tc->ntty);
150 if (tc->getsid () == 0)
152 /* The pty has been closed by the master. Return an EOF
153 indication. FIXME: There is nothing to stop somebody
154 from reallocating this pty. I think this is the case
155 which is handled by unlockpt on a Unix system. */
156 termios_printf ("closed by master");
160 /* If the process group is no more or if process is ignoring or blocks 'sig',
162 int pgid_gone = !pid_exists (myself->pgid);
164 ((void *) global_sigs[sig].sa_handler == (void *) SIG_IGN) ||
165 (_main_tls->sigmask & SIGTOMASK (sig));
169 else if (!sigs_ignored)
171 else if (sig == SIGTTOU)
172 return bg_ok; /* Just allow the output */
174 goto setEIO; /* This is an output error */
176 /* Don't raise a SIGTT* signal if we have already been interrupted
177 by another signal. */
178 if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
182 si.si_code = SI_KERNEL;
183 kill_pgrp (myself->pgid, si);
192 #define set_input_done(x) input_done = input_done || (x)
195 fhandler_termios::echo_erase (int force)
197 if (force || tc->ti.c_lflag & ECHO)
202 fhandler_termios::line_edit (const char *rptr, int nread, termios& ti)
204 line_edit_status ret = line_edit_ok;
208 int iscanon = ti.c_lflag & ICANON;
214 termios_printf ("char %c", c);
216 /* Check for special chars */
220 if (ti.c_iflag & IGNCR)
222 if (ti.c_iflag & ICRNL)
225 set_input_done (iscanon);
230 if (ti.c_iflag & INLCR)
233 set_input_done (iscanon);
236 if (ti.c_iflag & ISTRIP)
238 if (ti.c_lflag & ISIG)
241 if (CCEQ (ti.c_cc[VINTR], c))
243 else if (CCEQ (ti.c_cc[VQUIT], c))
245 else if (CCEQ (ti.c_cc[VSUSP], c))
250 termios_printf ("got interrupt %d, sending signal %d", c, sig);
253 ti.c_lflag &= ~FLUSHO;
258 if (ti.c_iflag & IXON)
260 if (CCEQ (ti.c_cc[VSTOP], c))
262 if (!tc->output_stopped)
264 tc->output_stopped = 1;
265 acquire_output_mutex (INFINITE);
269 else if (CCEQ (ti.c_cc[VSTART], c))
272 tc->output_stopped = 0;
273 release_output_mutex ();
276 else if ((ti.c_iflag & IXANY) && tc->output_stopped)
279 if (iscanon && ti.c_lflag & IEXTEN && CCEQ (ti.c_cc[VDISCARD], c))
281 ti.c_lflag ^= FLUSHO;
286 else if (CCEQ (ti.c_cc[VERASE], c))
288 if (eat_readahead (1))
292 else if (CCEQ (ti.c_cc[VWERASE], c))
296 if (!eat_readahead (1))
300 while ((ch = peek_readahead (1)) >= 0 && !isspace (ch));
303 else if (CCEQ (ti.c_cc[VKILL], c))
305 int nchars = eat_readahead (-1);
306 if (ti.c_lflag & ECHO)
311 else if (CCEQ (ti.c_cc[VREPRINT], c))
313 if (ti.c_lflag & ECHO)
316 doecho (rabuf, ralen);
320 else if (CCEQ (ti.c_cc[VEOF], c))
322 termios_printf ("EOF");
324 ret = line_edit_input_done;
327 else if (CCEQ (ti.c_cc[VEOL], c) ||
328 CCEQ (ti.c_cc[VEOL2], c) ||
332 termios_printf ("EOL");
335 if (ti.c_iflag & IUCLC && isupper (c))
339 if (ti.c_lflag & ECHO)
341 if (!iscanon || input_done)
343 int status = accept_input ();
346 ret = status ? line_edit_error : line_edit_pipe_full;
350 ret = line_edit_input_done;
355 if (!iscanon && ralen > 0)
356 ret = line_edit_input_done;
359 ret = line_edit_signalled;
365 fhandler_termios::lseek (_off64_t, int)