]>
sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/fhandler_termios.cc
7fddba5b3fc045b76fc332a1b4946d244a480713
3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009,
4 2010, 2011, 2012 Red Hat, Inc.
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
24 #include "child_info.h"
27 /* Common functions shared by tty/console */
30 fhandler_termios::tcinit (bool is_pty_master
)
32 /* Initial termios values */
34 if (is_pty_master
|| !tc ()->initialized ())
36 tc ()->ti
.c_iflag
= BRKINT
| ICRNL
| IXON
;
37 tc ()->ti
.c_oflag
= OPOST
| ONLCR
;
38 tc ()->ti
.c_cflag
= B38400
| CS8
| CREAD
;
39 tc ()->ti
.c_lflag
= ISIG
| ICANON
| ECHO
| IEXTEN
;
41 tc ()->ti
.c_cc
[VDISCARD
] = CFLUSH
;
42 tc ()->ti
.c_cc
[VEOL
] = CEOL
;
43 tc ()->ti
.c_cc
[VEOL2
] = CEOL2
;
44 tc ()->ti
.c_cc
[VEOF
] = CEOF
;
45 tc ()->ti
.c_cc
[VERASE
] = CERASE
;
46 tc ()->ti
.c_cc
[VINTR
] = CINTR
;
47 tc ()->ti
.c_cc
[VKILL
] = CKILL
;
48 tc ()->ti
.c_cc
[VLNEXT
] = CLNEXT
;
49 tc ()->ti
.c_cc
[VMIN
] = 1;
50 tc ()->ti
.c_cc
[VQUIT
] = CQUIT
;
51 tc ()->ti
.c_cc
[VREPRINT
] = CRPRNT
;
52 tc ()->ti
.c_cc
[VSTART
] = CSTART
;
53 tc ()->ti
.c_cc
[VSTOP
] = CSTOP
;
54 tc ()->ti
.c_cc
[VSUSP
] = CSUSP
;
55 tc ()->ti
.c_cc
[VSWTC
] = CSWTCH
;
56 tc ()->ti
.c_cc
[VTIME
] = 0;
57 tc ()->ti
.c_cc
[VWERASE
] = CWERASE
;
59 tc ()->ti
.c_ispeed
= tc ()->ti
.c_ospeed
= B38400
;
60 tc ()->pgid
= is_pty_master
? 0 : myself
->pgid
;
61 tc ()->initialized (true);
66 fhandler_termios::tcsetpgrp (const pid_t pgid
)
68 termios_printf ("%s, pgid %d, sid %d, tsid %d", tc ()->ttyname (), pgid
,
69 myself
->sid
, tc ()->getsid ());
70 if (myself
->sid
!= tc ()->getsid ())
78 res
= bg_check (-SIGTTOU
);
83 tc ()->setpgid (pgid
);
84 if (tc ()->is_console
&& (strace
.active () || !being_debugged ()))
85 tc ()->kill_pgrp (__SIGSETPGRP
);
89 if (_my_tls
.call_signal_handler ())
92 /* fall through intentionally */
103 fhandler_termios::tcgetpgrp ()
105 if (myself
->ctty
> 0 && myself
->ctty
== tc ()->ntty
)
112 fhandler_pty_master::tcgetpgrp ()
118 tty_min::kill_pgrp (int sig
)
120 bool killself
= false;
121 winpids
pids ((DWORD
) PID_MAP_RW
);
124 si
.si_code
= SI_KERNEL
;
125 for (unsigned i
= 0; i
< pids
.npids
; i
++)
128 if (!p
->exists () || p
->ctty
!= ntty
|| p
->pgid
!= pgid
)
131 killself
= sig
!= __SIGSETPGRP
;
136 sig_send (myself
, si
);
140 tty_min::is_orphaned_process_group (int pgid
)
142 /* An orphaned process group is a process group in which the parent
143 of every member is either itself a member of the group or is not
144 a member of the group's session. */
145 termios_printf ("checking pgid %d, my sid %d, my parent %d", pgid
, myself
->sid
, myself
->ppid
);
146 winpids
pids ((DWORD
) 0);
147 for (unsigned i
= 0; i
< pids
.npids
; i
++)
150 termios_printf ("checking pid %d - has pgid %d\n", p
->pid
, p
->pgid
);
151 if (!p
|| !p
->exists () || p
->pgid
!= pgid
)
153 pinfo
ppid (p
->ppid
);
156 termios_printf ("ppid->pgid %d, ppid->sid %d", ppid
->pgid
, ppid
->sid
);
157 if (ppid
->pgid
!= pgid
&& ppid
->sid
== myself
->sid
)
164 fhandler_termios::bg_check (int sig
)
166 if (!myself
->pgid
|| tc ()->getpgid () == myself
->pgid
||
167 myself
->ctty
!= tc ()->ntty
||
168 ((sig
== SIGTTOU
) && !(tc ()->ti
.c_lflag
& TOSTOP
)))
174 termios_printf ("%s, bg I/O pgid %d, tpgid %d, myctty %s", tc ()->ttyname (),
175 myself
->pgid
, tc ()->getpgid (), myctty ());
177 if (tc ()->getsid () == 0)
179 /* The pty has been closed by the master. Return an EOF
180 indication. FIXME: There is nothing to stop somebody
181 from reallocating this pty. I think this is the case
182 which is handled by unlockpt on a Unix system. */
183 termios_printf ("closed by master");
188 ((void *) global_sigs
[sig
].sa_handler
== (void *) SIG_IGN
) ||
189 (_main_tls
->sigmask
& SIGTOMASK (sig
));
191 /* If the process is ignoring SIGTT*, then background IO is OK. If
192 the process is not ignoring SIGTT*, then the sig is to be sent to
193 all processes in the process group (unless the process group of the
194 process is orphaned, in which case we return EIO). */
196 return bg_ok
; /* Just allow the IO */
197 else if (tc ()->is_orphaned_process_group (myself
->pgid
))
199 termios_printf ("process group is orphaned");
200 set_errno (EIO
); /* This is an IO error */
205 /* Don't raise a SIGTT* signal if we have already been
206 interrupted by another signal. */
207 if (WaitForSingleObject (signal_arrived
, 0) != WAIT_OBJECT_0
)
211 si
.si_code
= SI_KERNEL
;
212 kill_pgrp (myself
->pgid
, si
);
218 #define set_input_done(x) input_done = input_done || (x)
221 fhandler_termios::echo_erase (int force
)
223 if (force
|| tc ()->ti
.c_lflag
& ECHO
)
228 fhandler_termios::line_edit (const char *rptr
, int nread
, termios
& ti
)
230 line_edit_status ret
= line_edit_ok
;
234 int iscanon
= ti
.c_lflag
& ICANON
;
240 termios_printf ("char %c", c
);
242 /* Check for special chars */
246 if (ti
.c_iflag
& IGNCR
)
248 if (ti
.c_iflag
& ICRNL
)
251 set_input_done (iscanon
);
256 if (ti
.c_iflag
& INLCR
)
259 set_input_done (iscanon
);
262 if (ti
.c_iflag
& ISTRIP
)
264 if (ti
.c_lflag
& ISIG
)
267 if (CCEQ (ti
.c_cc
[VINTR
], c
))
269 else if (CCEQ (ti
.c_cc
[VQUIT
], c
))
271 else if (CCEQ (ti
.c_cc
[VSUSP
], c
))
276 termios_printf ("got interrupt %d, sending signal %d", c
, sig
);
278 tc ()->kill_pgrp (sig
);
279 ti
.c_lflag
&= ~FLUSHO
;
284 if (ti
.c_iflag
& IXON
)
286 if (CCEQ (ti
.c_cc
[VSTOP
], c
))
288 if (!tc ()->output_stopped
)
290 tc ()->output_stopped
= 1;
291 acquire_output_mutex (INFINITE
);
295 else if (CCEQ (ti
.c_cc
[VSTART
], c
))
298 tc ()->output_stopped
= 0;
299 release_output_mutex ();
302 else if ((ti
.c_iflag
& IXANY
) && tc ()->output_stopped
)
305 if (iscanon
&& ti
.c_lflag
& IEXTEN
&& CCEQ (ti
.c_cc
[VDISCARD
], c
))
307 ti
.c_lflag
^= FLUSHO
;
312 else if (CCEQ (ti
.c_cc
[VERASE
], c
))
314 if (eat_readahead (1))
318 else if (CCEQ (ti
.c_cc
[VWERASE
], c
))
322 if (!eat_readahead (1))
326 while ((ch
= peek_readahead (1)) >= 0 && !isspace (ch
));
329 else if (CCEQ (ti
.c_cc
[VKILL
], c
))
331 int nchars
= eat_readahead (-1);
332 if (ti
.c_lflag
& ECHO
)
337 else if (CCEQ (ti
.c_cc
[VREPRINT
], c
))
339 if (ti
.c_lflag
& ECHO
)
342 doecho (rabuf
, ralen
);
346 else if (CCEQ (ti
.c_cc
[VEOF
], c
))
348 termios_printf ("EOF");
350 ret
= line_edit_input_done
;
353 else if (CCEQ (ti
.c_cc
[VEOL
], c
) ||
354 CCEQ (ti
.c_cc
[VEOL2
], c
) ||
358 termios_printf ("EOL");
361 if (ti
.c_iflag
& IUCLC
&& isupper (c
))
365 if (ti
.c_lflag
& ECHO
)
367 if (!iscanon
|| input_done
)
369 int status
= accept_input ();
372 ret
= status
? line_edit_error
: line_edit_pipe_full
;
376 ret
= line_edit_input_done
;
381 if (!iscanon
&& ralen
> 0)
382 ret
= line_edit_input_done
;
385 ret
= line_edit_signalled
;
391 fhandler_termios::lseek (_off64_t
, int)
398 fhandler_termios::sigflush ()
400 /* FIXME: Checking get_ttyp() for NULL is not right since it should not
401 be NULL while this is alive. However, we can conceivably close a
402 ctty while exiting and that will zero this. */
403 if ((!have_execed
|| have_execed_cygwin
) && get_ttyp ()
404 && !(get_ttyp ()->ti
.c_lflag
& NOFLSH
))
409 fhandler_termios::tcgetsid ()
411 if (myself
->ctty
> 0 && myself
->ctty
== tc ()->ntty
)
412 return tc ()->getsid ();
418 fhandler_termios::ioctl (int cmd
, void *varg
)
420 if (cmd
!= TIOCSCTTY
)
421 return 1; /* Not handled by this function */
423 int arg
= (int) varg
;
425 if (arg
!= 0 && arg
!= 1)
431 termios_printf ("myself->ctty %d, myself->sid %d, myself->pid %d, arg %d, tc()->getsid () %d\n",
432 myself
->ctty
, myself
->sid
, myself
->pid
, arg
, tc ()->getsid ());
433 if (myself
->ctty
> 0 || myself
->sid
!= myself
->pid
|| (!arg
&& tc ()->getsid () > 0))
440 myself
->set_ctty (this, 0);
This page took 0.053251 seconds and 4 git commands to generate.