* cygheap.h (init_cygheap::ctty_on_hold): Remove conditionalized variable.
* dcrt0.cc (do_exit): Remove code which handled CYGWIN=tty style ttys. * devices.in: Remove "/dev/ttym". * dtable.cc: Rename tty to pty where appropriate throughout. (dtable::stdio_init): Use new t->is_console rather than using now-deleted hwnd element in tty structure. (dtable::init_std_file_from_handle): Remove code which handled CYGWIN=tty style ttys. (fh_alloc): Ditto. * fhandler.h: Rename tty to pty where appropriate. (fhandler_pty_common): Delete output_done_event, ioctl_request_event, ioctl_done_event. (fhandler_pty_master::setup): Delete argument. (fhandler_tty_master): Delete. (fhandler_union): Delete __tty_master. * fhandler_console.cc (use_tty): Delete. (fhandler_console::get_tty_stuff): Set is_console to true rather than calling sethwnd. (fhandler_console::send_winch_maybe): Remove CYGWIN=tty considerations. (fhandler_console::input_tcsetattr): Ditto. * fhandler_termios.cc (fhandler_termios::tcsetpgrp): Use new t->is_console rather than using now-deleted hwnd element in tty structure. * fhandler_tty.cc: Rename tty to pty where appropriate throughout. (tty_master): Delete. (process_input): Ditto. (process_output): Ditto. (process_ioctl): Ditto. (fhandler_tty_master::*): Ditto. (fhandler_pty_master::process_slave_output): Remove CYGWIN=tty considerations. (fhandler_pty_slave::open): Ditto for *_done_event. (fhandler_pty_slave::write): Ditto. (fhandler_pty_slave::ioctl): Ditto. (fhandler_pty_slave::fch_open_handles): Ditto. (fhandler_pty_slave::fch_set_sd): Ditto. (fhandler_pty_slave::fch_close_handles): Ditto. (fhandler_pty_common::close): Ditto. (fhandler_pty_master::setup): Ditto. Remove now-unneeded ispty parameter. (fhandler_pty_master::open): Reflect argument removal for tty::allocate. * select.cc: Rename tty to pty where appropriate throughout. * sigproc.cc (proc_subproc): Remove CYGWIN=tty considerations. * tty.cc (ttyslot): Accommodate CYGWIN=tty removal. (tty_list::init_session): Ditto. (tty_list::attach): Ditto. (tty::create_master): Delete. (tty_list::terminate): Ditto. (tty_list::allocate): Delete "with_console" parameter. Remove CYGWIN=tty considerations. (tty::init): Set is_console = false. Use 'false' for was_opened since it is a boolean. * tty.h (*_{DONE,REQUEST}_EVENT): Delete. (tty_min::is_console): Declare new field which replaces hwnd. (tty_min::gethwnd): Delete. (tty_min::sethwnd): Ditto. (tty_list::allocate): Delete parameter. (tty_list::terminate): Delete declaration. * include/sys/cygwin.h (PID_USETTY): Redefine to PID_UNUSED1 and change comment to reflect its availability.
This commit is contained in:
parent
d0009604ad
commit
c75b5b2d13
|
@ -1,3 +1,68 @@
|
||||||
|
2011-06-14 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||||
|
|
||||||
|
* cygheap.h (init_cygheap::ctty_on_hold): Remove conditionalized
|
||||||
|
variable.
|
||||||
|
* dcrt0.cc (do_exit): Remove code which handled CYGWIN=tty style ttys.
|
||||||
|
* devices.in: Remove "/dev/ttym".
|
||||||
|
* dtable.cc: Rename tty to pty where appropriate throughout.
|
||||||
|
(dtable::stdio_init): Use new t->is_console rather than using
|
||||||
|
now-deleted hwnd element in tty structure.
|
||||||
|
(dtable::init_std_file_from_handle): Remove code which handled
|
||||||
|
CYGWIN=tty style ttys.
|
||||||
|
(fh_alloc): Ditto.
|
||||||
|
* fhandler.h: Rename tty to pty where appropriate.
|
||||||
|
(fhandler_pty_common): Delete output_done_event, ioctl_request_event,
|
||||||
|
ioctl_done_event.
|
||||||
|
(fhandler_pty_master::setup): Delete argument.
|
||||||
|
(fhandler_tty_master): Delete.
|
||||||
|
(fhandler_union): Delete __tty_master.
|
||||||
|
* fhandler_console.cc (use_tty): Delete.
|
||||||
|
(fhandler_console::get_tty_stuff): Set is_console to true rather than
|
||||||
|
calling sethwnd.
|
||||||
|
(fhandler_console::send_winch_maybe): Remove CYGWIN=tty considerations.
|
||||||
|
(fhandler_console::input_tcsetattr): Ditto.
|
||||||
|
* fhandler_termios.cc (fhandler_termios::tcsetpgrp): Use new
|
||||||
|
t->is_console rather than using now-deleted hwnd element in tty
|
||||||
|
structure.
|
||||||
|
* fhandler_tty.cc: Rename tty to pty where appropriate throughout.
|
||||||
|
(tty_master): Delete.
|
||||||
|
(process_input): Ditto.
|
||||||
|
(process_output): Ditto.
|
||||||
|
(process_ioctl): Ditto.
|
||||||
|
(fhandler_tty_master::*): Ditto.
|
||||||
|
(fhandler_pty_master::process_slave_output): Remove CYGWIN=tty
|
||||||
|
considerations.
|
||||||
|
(fhandler_pty_slave::open): Ditto for *_done_event.
|
||||||
|
(fhandler_pty_slave::write): Ditto.
|
||||||
|
(fhandler_pty_slave::ioctl): Ditto.
|
||||||
|
(fhandler_pty_slave::fch_open_handles): Ditto.
|
||||||
|
(fhandler_pty_slave::fch_set_sd): Ditto.
|
||||||
|
(fhandler_pty_slave::fch_close_handles): Ditto.
|
||||||
|
(fhandler_pty_common::close): Ditto.
|
||||||
|
(fhandler_pty_master::setup): Ditto. Remove now-unneeded ispty
|
||||||
|
parameter.
|
||||||
|
(fhandler_pty_master::open): Reflect argument removal for
|
||||||
|
tty::allocate.
|
||||||
|
* select.cc: Rename tty to pty where appropriate throughout.
|
||||||
|
* sigproc.cc (proc_subproc): Remove CYGWIN=tty considerations.
|
||||||
|
* tty.cc (ttyslot): Accommodate CYGWIN=tty removal.
|
||||||
|
(tty_list::init_session): Ditto.
|
||||||
|
(tty_list::attach): Ditto.
|
||||||
|
(tty::create_master): Delete.
|
||||||
|
(tty_list::terminate): Ditto.
|
||||||
|
(tty_list::allocate): Delete "with_console" parameter. Remove
|
||||||
|
CYGWIN=tty considerations.
|
||||||
|
(tty::init): Set is_console = false. Use 'false' for was_opened since
|
||||||
|
it is a boolean.
|
||||||
|
* tty.h (*_{DONE,REQUEST}_EVENT): Delete.
|
||||||
|
(tty_min::is_console): Declare new field which replaces hwnd.
|
||||||
|
(tty_min::gethwnd): Delete.
|
||||||
|
(tty_min::sethwnd): Ditto.
|
||||||
|
(tty_list::allocate): Delete parameter.
|
||||||
|
(tty_list::terminate): Delete declaration.
|
||||||
|
* include/sys/cygwin.h (PID_USETTY): Redefine to PID_UNUSED1 and change
|
||||||
|
comment to reflect its availability.
|
||||||
|
|
||||||
2011-06-13 Christopher Faylor <me.cygwin2011@cgf.cx>
|
2011-06-13 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||||
|
|
||||||
* fhandler_tty_slave.cc (fhandler_tty_slave::fhandler_tty_slave):
|
* fhandler_tty_slave.cc (fhandler_tty_slave::fhandler_tty_slave):
|
||||||
|
|
|
@ -294,9 +294,6 @@ struct init_cygheap: public mini_cygheap
|
||||||
struct sigaction *sigs;
|
struct sigaction *sigs;
|
||||||
|
|
||||||
fhandler_termios *ctty; /* Current tty */
|
fhandler_termios *ctty; /* Current tty */
|
||||||
#ifdef NEWVFORK
|
|
||||||
fhandler_tty_slave *ctty_on_hold;
|
|
||||||
#endif
|
|
||||||
struct _cygtls **threadlist;
|
struct _cygtls **threadlist;
|
||||||
size_t sthreads;
|
size_t sthreads;
|
||||||
pid_t pid; /* my pid */
|
pid_t pid; /* my pid */
|
||||||
|
|
|
@ -1045,12 +1045,6 @@ do_exit (int status)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exit_state < ES_TTY_TERMINATE)
|
|
||||||
{
|
|
||||||
exit_state = ES_TTY_TERMINATE;
|
|
||||||
cygwin_shared->tty.terminate ();
|
|
||||||
}
|
|
||||||
|
|
||||||
myself.exit (n);
|
myself.exit (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2645,7 +2645,6 @@ static const device dev_storage[] =
|
||||||
{"/dev/ttyS61", BRACK(FHDEV(DEV_SERIAL_MAJOR, 61)), "\\??\\COM62"},
|
{"/dev/ttyS61", BRACK(FHDEV(DEV_SERIAL_MAJOR, 61)), "\\??\\COM62"},
|
||||||
{"/dev/ttyS62", BRACK(FHDEV(DEV_SERIAL_MAJOR, 62)), "\\??\\COM63"},
|
{"/dev/ttyS62", BRACK(FHDEV(DEV_SERIAL_MAJOR, 62)), "\\??\\COM63"},
|
||||||
{"/dev/ttyS63", BRACK(FHDEV(DEV_SERIAL_MAJOR, 63)), "\\??\\COM64"},
|
{"/dev/ttyS63", BRACK(FHDEV(DEV_SERIAL_MAJOR, 63)), "\\??\\COM64"},
|
||||||
{"/dev/ttym", BRACK(FH_TTYM), "/dev/ttym"},
|
|
||||||
{"/dev/urandom", BRACK(FH_URANDOM), "/dev/urandom"},
|
{"/dev/urandom", BRACK(FH_URANDOM), "/dev/urandom"},
|
||||||
{"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows"},
|
{"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows"},
|
||||||
{"/dev/zero", BRACK(FH_ZERO), "/dev/zero"}
|
{"/dev/zero", BRACK(FH_ZERO), "/dev/zero"}
|
||||||
|
@ -2653,9 +2652,8 @@ static const device dev_storage[] =
|
||||||
|
|
||||||
const device *cons_dev = dev_storage + 20;
|
const device *cons_dev = dev_storage + 20;
|
||||||
const device *console_dev = dev_storage + 84;
|
const device *console_dev = dev_storage + 84;
|
||||||
const device *ttym_dev = dev_storage + 2577;
|
|
||||||
const device *ttys_dev = dev_storage + 2449;
|
const device *ttys_dev = dev_storage + 2449;
|
||||||
const device *urandom_dev = dev_storage + 2578;
|
const device *urandom_dev = dev_storage + 2577;
|
||||||
|
|
||||||
|
|
||||||
static KR_device_t KR_find_keyword (const char *KR_keyword, int KR_length)
|
static KR_device_t KR_find_keyword (const char *KR_keyword, int KR_length)
|
||||||
|
@ -3839,21 +3837,6 @@ return NULL;
|
||||||
case 'y':
|
case 'y':
|
||||||
switch (KR_keyword [8])
|
switch (KR_keyword [8])
|
||||||
{
|
{
|
||||||
case 'm':
|
|
||||||
if (strncmp (KR_keyword, "/dev/ttym", 9) == 0)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
return dev_storage + 2577;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case '9':
|
case '9':
|
||||||
switch (KR_keyword [5])
|
switch (KR_keyword [5])
|
||||||
{
|
{
|
||||||
|
@ -5358,7 +5341,7 @@ return NULL;
|
||||||
if (strncmp (KR_keyword, "/dev/zero", 9) == 0)
|
if (strncmp (KR_keyword, "/dev/zero", 9) == 0)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
return dev_storage + 2580;
|
return dev_storage + 2579;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44583,7 +44566,7 @@ return NULL;
|
||||||
if (strncmp (KR_keyword, "/dev/windows", 12) == 0)
|
if (strncmp (KR_keyword, "/dev/windows", 12) == 0)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
return dev_storage + 2579;
|
return dev_storage + 2578;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44598,7 +44581,7 @@ return NULL;
|
||||||
if (strncmp (KR_keyword, "/dev/urandom", 12) == 0)
|
if (strncmp (KR_keyword, "/dev/urandom", 12) == 0)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
return dev_storage + 2578;
|
return dev_storage + 2577;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,6 @@ const device dev_error_storage =
|
||||||
"/dev/tty%(0-63)d", BRACK(FHDEV(DEV_TTYS_MAJOR, {$1})), "/dev/tty{$1}", ttys_dev
|
"/dev/tty%(0-63)d", BRACK(FHDEV(DEV_TTYS_MAJOR, {$1})), "/dev/tty{$1}", ttys_dev
|
||||||
"/dev/cons%(0-63)d", BRACK(FHDEV(DEV_CONS_MAJOR, {$1})), "/dev/cons{$1}", cons_dev
|
"/dev/cons%(0-63)d", BRACK(FHDEV(DEV_CONS_MAJOR, {$1})), "/dev/cons{$1}", cons_dev
|
||||||
"/dev/console", BRACK(FH_CONSOLE), "/dev/console", console_dev
|
"/dev/console", BRACK(FH_CONSOLE), "/dev/console", console_dev
|
||||||
"/dev/ttym", BRACK(FH_TTYM), "/dev/ttym", ttym_dev
|
|
||||||
"/dev/ptmx", BRACK(FH_PTYM), "/dev/ptmx"
|
"/dev/ptmx", BRACK(FH_PTYM), "/dev/ptmx"
|
||||||
"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows"
|
"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows"
|
||||||
"/dev/dsp", BRACK(FH_OSS_DSP), "/dev/dsp"
|
"/dev/dsp", BRACK(FH_OSS_DSP), "/dev/dsp"
|
||||||
|
|
|
@ -154,7 +154,7 @@ dtable::stdio_init ()
|
||||||
if (myself->cygstarted || ISSTATE (myself, PID_CYGPARENT))
|
if (myself->cygstarted || ISSTATE (myself, PID_CYGPARENT))
|
||||||
{
|
{
|
||||||
tty_min *t = cygwin_shared->tty.get_cttyp ();
|
tty_min *t = cygwin_shared->tty.get_cttyp ();
|
||||||
if (t && t->getpgid () == myself->pid && t->gethwnd ())
|
if (t && t->getpgid () == myself->pid && t->is_console)
|
||||||
init_console_handler (true);
|
init_console_handler (true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -309,12 +309,10 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
||||||
|| GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
|
|| GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
|
||||||
{
|
{
|
||||||
/* Console I/O */
|
/* Console I/O */
|
||||||
if (!ISSTATE (myself, PID_USETTY))
|
if (myself->ctty > 0)
|
||||||
dev.parse (FH_CONSOLE);
|
|
||||||
else if (myself->ctty > 0)
|
|
||||||
dev.parse (myself->ctty);
|
dev.parse (myself->ctty);
|
||||||
else
|
else
|
||||||
dev.parse (FH_TTY);
|
dev.parse (FH_CONSOLE);
|
||||||
}
|
}
|
||||||
else if (GetCommState (handle, &dcb))
|
else if (GetCommState (handle, &dcb))
|
||||||
/* FIXME: Not right - assumes ttyS0 */
|
/* FIXME: Not right - assumes ttyS0 */
|
||||||
|
@ -433,10 +431,7 @@ fh_alloc (device dev)
|
||||||
switch (dev.get_major ())
|
switch (dev.get_major ())
|
||||||
{
|
{
|
||||||
case DEV_TTYS_MAJOR:
|
case DEV_TTYS_MAJOR:
|
||||||
fh = cnew (fhandler_tty_slave) (dev.get_minor ());
|
fh = cnew (fhandler_pty_slave) (dev.get_minor ());
|
||||||
break;
|
|
||||||
case DEV_TTYM_MAJOR:
|
|
||||||
fh = cnew (fhandler_tty_master) ();
|
|
||||||
break;
|
break;
|
||||||
case DEV_CYGDRIVE_MAJOR:
|
case DEV_CYGDRIVE_MAJOR:
|
||||||
fh = cnew (fhandler_cygdrive) ();
|
fh = cnew (fhandler_cygdrive) ();
|
||||||
|
@ -543,7 +538,7 @@ fh_alloc (device dev)
|
||||||
if (iscons_dev (myself->ctty))
|
if (iscons_dev (myself->ctty))
|
||||||
fh = cnew (fhandler_console) (dev);
|
fh = cnew (fhandler_console) (dev);
|
||||||
else
|
else
|
||||||
fh = cnew (fhandler_tty_slave) (myself->ctty);
|
fh = cnew (fhandler_pty_slave) (myself->ctty);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FH_KMSG:
|
case FH_KMSG:
|
||||||
|
|
|
@ -901,7 +901,7 @@ class fhandler_serial: public fhandler_base
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
|
|
||||||
/* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
|
/* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
|
||||||
don't use it for permissions checking. fhandler_tty_slave does
|
don't use it for permissions checking. fhandler_pty_slave does
|
||||||
permission checking on pgrps. */
|
permission checking on pgrps. */
|
||||||
virtual int tcgetpgrp () { return pgrp_; }
|
virtual int tcgetpgrp () { return pgrp_; }
|
||||||
virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
|
virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
|
||||||
|
@ -1132,22 +1132,16 @@ private:
|
||||||
friend tty_min * tty_list::get_cttyp ();
|
friend tty_min * tty_list::get_cttyp ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_tty_common: public fhandler_termios
|
class fhandler_pty_common: public fhandler_termios
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fhandler_tty_common ()
|
fhandler_pty_common ()
|
||||||
: fhandler_termios (), output_done_event (NULL),
|
: fhandler_termios (),
|
||||||
ioctl_request_event (NULL), ioctl_done_event (NULL), output_mutex (NULL),
|
output_mutex (NULL),
|
||||||
input_mutex (NULL), input_available_event (NULL)
|
input_mutex (NULL), input_available_event (NULL)
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
HANDLE output_done_event; // Raised by master when tty's output buffer
|
|
||||||
// written. Write status in tty::write_retval.
|
|
||||||
HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
|
|
||||||
// Ioctl() request in tty::cmd/arg.
|
|
||||||
HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
|
|
||||||
// Ioctl() status in tty::ioctl_retval.
|
|
||||||
HANDLE output_mutex, input_mutex;
|
HANDLE output_mutex, input_mutex;
|
||||||
HANDLE input_available_event;
|
HANDLE input_available_event;
|
||||||
|
|
||||||
|
@ -1162,7 +1156,7 @@ class fhandler_tty_common: public fhandler_termios
|
||||||
select_record *select_except (select_stuff *);
|
select_record *select_except (select_stuff *);
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_tty_slave: public fhandler_tty_common
|
class fhandler_pty_slave: public fhandler_pty_common
|
||||||
{
|
{
|
||||||
HANDLE inuse; // used to indicate that a tty is in use
|
HANDLE inuse; // used to indicate that a tty is in use
|
||||||
|
|
||||||
|
@ -1173,7 +1167,7 @@ class fhandler_tty_slave: public fhandler_tty_common
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
fhandler_tty_slave (int);
|
fhandler_pty_slave (int);
|
||||||
|
|
||||||
bool use_archetype () const {return true;}
|
bool use_archetype () const {return true;}
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
|
@ -1201,7 +1195,7 @@ class fhandler_tty_slave: public fhandler_tty_common
|
||||||
size_t size () const { return sizeof (*this);}
|
size_t size () const { return sizeof (*this);}
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_pty_master: public fhandler_tty_common
|
class fhandler_pty_master: public fhandler_pty_common
|
||||||
{
|
{
|
||||||
int pktmode; // non-zero if pty in a packet mode.
|
int pktmode; // non-zero if pty in a packet mode.
|
||||||
HANDLE master_ctl; // Control socket for handle duplication
|
HANDLE master_ctl; // Control socket for handle duplication
|
||||||
|
@ -1210,6 +1204,7 @@ class fhandler_pty_master: public fhandler_tty_common
|
||||||
public:
|
public:
|
||||||
int need_nl; // Next read should start with \n
|
int need_nl; // Next read should start with \n
|
||||||
DWORD dwProcessId; // Owner of master handles
|
DWORD dwProcessId; // Owner of master handles
|
||||||
|
HANDLE from_master, to_master;
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
fhandler_pty_master ();
|
fhandler_pty_master ();
|
||||||
|
@ -1232,29 +1227,12 @@ public:
|
||||||
|
|
||||||
char *ptsname ();
|
char *ptsname ();
|
||||||
|
|
||||||
HANDLE from_master, to_master;
|
|
||||||
bool hit_eof ();
|
bool hit_eof ();
|
||||||
bool setup (bool);
|
bool setup ();
|
||||||
int dup (fhandler_base *);
|
int dup (fhandler_base *);
|
||||||
void fixup_after_fork (HANDLE parent);
|
void fixup_after_fork (HANDLE parent);
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
int tcgetpgrp ();
|
int tcgetpgrp ();
|
||||||
virtual bool is_tty_master () const {return false;}
|
|
||||||
size_t size () const { return sizeof (*this);}
|
|
||||||
};
|
|
||||||
|
|
||||||
class fhandler_tty_master: public fhandler_pty_master
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/* Constructor */
|
|
||||||
fhandler_console *console; // device handler to perform real i/o.
|
|
||||||
bool use_archetype () const {return false;}
|
|
||||||
|
|
||||||
fhandler_tty_master ();
|
|
||||||
int init ();
|
|
||||||
int init_console ();
|
|
||||||
void set_winsize (bool);
|
|
||||||
bool is_tty_master () const {return true;}
|
|
||||||
size_t size () const { return sizeof (*this);}
|
size_t size () const { return sizeof (*this);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1567,7 +1545,7 @@ struct fhandler_nodevice: public fhandler_base
|
||||||
#define report_tty_counts(fh, call, use_op) \
|
#define report_tty_counts(fh, call, use_op) \
|
||||||
termios_printf ("%s %s, %susecount %d",\
|
termios_printf ("%s %s, %susecount %d",\
|
||||||
fh->ttyname (), call,\
|
fh->ttyname (), call,\
|
||||||
use_op, ((fhandler_tty_slave *) (fh->archetype ?: fh))->usecount);
|
use_op, ((fhandler_pty_slave *) (fh->archetype ?: fh))->usecount);
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
|
@ -1599,9 +1577,8 @@ typedef union
|
||||||
char __serial[sizeof (fhandler_serial)];
|
char __serial[sizeof (fhandler_serial)];
|
||||||
char __socket[sizeof (fhandler_socket)];
|
char __socket[sizeof (fhandler_socket)];
|
||||||
char __termios[sizeof (fhandler_termios)];
|
char __termios[sizeof (fhandler_termios)];
|
||||||
char __tty_common[sizeof (fhandler_tty_common)];
|
char __pty_common[sizeof (fhandler_pty_common)];
|
||||||
char __tty_master[sizeof (fhandler_tty_master)];
|
char __pty_slave[sizeof (fhandler_pty_slave)];
|
||||||
char __tty_slave[sizeof (fhandler_tty_slave)];
|
|
||||||
char __virtual[sizeof (fhandler_virtual)];
|
char __virtual[sizeof (fhandler_virtual)];
|
||||||
char __windows[sizeof (fhandler_windows)];
|
char __windows[sizeof (fhandler_windows)];
|
||||||
} fhandler_union;
|
} fhandler_union;
|
||||||
|
|
|
@ -49,8 +49,6 @@ details. */
|
||||||
#define srTop (dev_state.info.winTop + dev_state.scroll_region.Top)
|
#define srTop (dev_state.info.winTop + dev_state.scroll_region.Top)
|
||||||
#define srBottom ((dev_state.scroll_region.Bottom < 0) ? dev_state.info.winBottom : dev_state.info.winTop + dev_state.scroll_region.Bottom)
|
#define srBottom ((dev_state.scroll_region.Bottom < 0) ? dev_state.info.winBottom : dev_state.info.winTop + dev_state.scroll_region.Bottom)
|
||||||
|
|
||||||
#define use_tty ISSTATE (myself, PID_USETTY)
|
|
||||||
|
|
||||||
const char *get_nonascii_key (INPUT_RECORD&, char *);
|
const char *get_nonascii_key (INPUT_RECORD&, char *);
|
||||||
|
|
||||||
const unsigned fhandler_console::MAX_WRITE_CHARS = 16384;
|
const unsigned fhandler_console::MAX_WRITE_CHARS = 16384;
|
||||||
|
@ -191,7 +189,7 @@ fhandler_console::get_tty_stuff ()
|
||||||
dev_state.meta_mask |= RIGHT_ALT_PRESSED;
|
dev_state.meta_mask |= RIGHT_ALT_PRESSED;
|
||||||
dev_state.set_default_attr ();
|
dev_state.set_default_attr ();
|
||||||
dev_state.backspace_keycode = CERASE;
|
dev_state.backspace_keycode = CERASE;
|
||||||
shared_console_info->tty_min_state.sethwnd ((HWND) INVALID_HANDLE_VALUE);
|
shared_console_info->tty_min_state.is_console = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,12 +263,8 @@ fhandler_console::send_winch_maybe ()
|
||||||
|
|
||||||
if (y != dev_state.info.dwWinSize.Y || x != dev_state.info.dwWinSize.X)
|
if (y != dev_state.info.dwWinSize.Y || x != dev_state.info.dwWinSize.X)
|
||||||
{
|
{
|
||||||
extern fhandler_tty_master *tty_master;
|
|
||||||
dev_state.scroll_region.Top = 0;
|
dev_state.scroll_region.Top = 0;
|
||||||
dev_state.scroll_region.Bottom = -1;
|
dev_state.scroll_region.Bottom = -1;
|
||||||
if (tty_master)
|
|
||||||
tty_master->set_winsize (true);
|
|
||||||
else
|
|
||||||
tc ()->kill_pgrp (SIGWINCH);
|
tc ()->kill_pgrp (SIGWINCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -977,13 +971,6 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
|
||||||
flags |= ENABLE_PROCESSED_INPUT;
|
flags |= ENABLE_PROCESSED_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_tty)
|
|
||||||
{
|
|
||||||
flags = 0; // ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
|
|
||||||
tc ()->ti.c_iflag = 0;
|
|
||||||
tc ()->ti.c_lflag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags |= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
|
flags |= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
|
|
|
@ -78,7 +78,7 @@ fhandler_termios::tcsetpgrp (const pid_t pgid)
|
||||||
{
|
{
|
||||||
case bg_ok:
|
case bg_ok:
|
||||||
tc ()->setpgid (pgid);
|
tc ()->setpgid (pgid);
|
||||||
init_console_handler (tc ()->gethwnd ());
|
init_console_handler (tc ()->is_console);
|
||||||
res = 0;
|
res = 0;
|
||||||
break;
|
break;
|
||||||
case bg_signalled:
|
case bg_signalled:
|
||||||
|
|
|
@ -42,60 +42,12 @@ struct pipe_reply {
|
||||||
DWORD error;
|
DWORD error;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* tty master stuff */
|
|
||||||
|
|
||||||
fhandler_tty_master NO_COPY *tty_master;
|
|
||||||
|
|
||||||
static void WINAPI process_input (void *) __attribute__((noreturn)); // Input queue thread
|
|
||||||
static void WINAPI process_output (void *) __attribute__((noreturn)); // Output queue thread
|
|
||||||
static void WINAPI process_ioctl (void *) __attribute__((noreturn)); // Ioctl requests thread
|
|
||||||
|
|
||||||
fhandler_tty_master::fhandler_tty_master ()
|
|
||||||
: fhandler_pty_master (), console (NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::get_unit ()
|
fhandler_pty_slave::get_unit ()
|
||||||
{
|
{
|
||||||
return dev ().get_minor ();
|
return dev ().get_minor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
fhandler_tty_master::set_winsize (bool sendSIGWINCH)
|
|
||||||
{
|
|
||||||
winsize w;
|
|
||||||
console->ioctl (TIOCGWINSZ, &w);
|
|
||||||
get_ttyp ()->winsize = w;
|
|
||||||
if (sendSIGWINCH)
|
|
||||||
tc ()->kill_pgrp (SIGWINCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_tty_master::init ()
|
|
||||||
{
|
|
||||||
termios_printf ("Creating master for tty%d", get_unit ());
|
|
||||||
|
|
||||||
if (init_console ())
|
|
||||||
{
|
|
||||||
termios_printf ("can't create fhandler");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!setup (false))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
set_winsize (false);
|
|
||||||
|
|
||||||
set_close_on_exec (true);
|
|
||||||
|
|
||||||
new cygthread (process_input, cygself, "ttyin");
|
|
||||||
new cygthread (process_ioctl, cygself, "ttyioctl");
|
|
||||||
new cygthread (process_output, cygself, "ttyout");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
static class mutex_stack
|
static class mutex_stack
|
||||||
{
|
{
|
||||||
|
@ -109,17 +61,17 @@ static int osi;
|
||||||
#endif /*DEBUGGING*/
|
#endif /*DEBUGGING*/
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
|
fhandler_pty_common::__acquire_output_mutex (const char *fn, int ln,
|
||||||
DWORD ms)
|
DWORD ms)
|
||||||
{
|
{
|
||||||
if (strace.active ())
|
if (strace.active ())
|
||||||
strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex (%p): waiting %d ms", ln, output_mutex, ms);
|
strace.prntf (_STRACE_TERMIOS, fn, "(%d): pty output_mutex (%p): waiting %d ms", ln, output_mutex, ms);
|
||||||
DWORD res = WaitForSingleObject (output_mutex, ms);
|
DWORD res = WaitForSingleObject (output_mutex, ms);
|
||||||
if (res == WAIT_OBJECT_0)
|
if (res == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
#ifndef DEBUGGING
|
#ifndef DEBUGGING
|
||||||
if (strace.active ())
|
if (strace.active ())
|
||||||
strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex: acquired", ln, res);
|
strace.prntf (_STRACE_TERMIOS, fn, "(%d): pty output_mutex: acquired", ln, res);
|
||||||
#else
|
#else
|
||||||
ostack[osi].fn = fn;
|
ostack[osi].fn = fn;
|
||||||
ostack[osi].ln = ln;
|
ostack[osi].ln = ln;
|
||||||
|
@ -132,13 +84,13 @@ fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_tty_common::__release_output_mutex (const char *fn, int ln)
|
fhandler_pty_common::__release_output_mutex (const char *fn, int ln)
|
||||||
{
|
{
|
||||||
if (ReleaseMutex (output_mutex))
|
if (ReleaseMutex (output_mutex))
|
||||||
{
|
{
|
||||||
#ifndef DEBUGGING
|
#ifndef DEBUGGING
|
||||||
if (strace.active ())
|
if (strace.active ())
|
||||||
strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex(%p) released", ln, output_mutex);
|
strace.prntf (_STRACE_TERMIOS, fn, "(%d): pty output_mutex(%p) released", ln, output_mutex);
|
||||||
#else
|
#else
|
||||||
if (osi > 0)
|
if (osi > 0)
|
||||||
osi--;
|
osi--;
|
||||||
|
@ -156,7 +108,7 @@ fhandler_tty_common::__release_output_mutex (const char *fn, int ln)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process tty input. */
|
/* Process pty input. */
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_pty_master::doecho (const void *str, DWORD len)
|
fhandler_pty_master::doecho (const void *str, DWORD len)
|
||||||
|
@ -164,7 +116,6 @@ fhandler_pty_master::doecho (const void *str, DWORD len)
|
||||||
acquire_output_mutex (INFINITE);
|
acquire_output_mutex (INFINITE);
|
||||||
if (!WriteFile (to_master, str, len, &len, NULL))
|
if (!WriteFile (to_master, str, len, &len, NULL))
|
||||||
termios_printf ("Write to %p failed, %E", to_master);
|
termios_printf ("Write to %p failed, %E", to_master);
|
||||||
// WaitForSingleObject (output_done_event, INFINITE);
|
|
||||||
release_output_mutex ();
|
release_output_mutex ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,21 +167,6 @@ fhandler_pty_master::accept_input ()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI
|
|
||||||
process_input (void *)
|
|
||||||
{
|
|
||||||
char rawbuf[INP_BUFFER_SIZE];
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
size_t nraw = INP_BUFFER_SIZE;
|
|
||||||
tty_master->console->read ((void *) rawbuf, nraw);
|
|
||||||
if (tty_master->line_edit (rawbuf, nraw, tty_master->get_ttyp ()->ti)
|
|
||||||
== line_edit_signalled)
|
|
||||||
tty_master->console->eat_readahead (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fhandler_pty_master::hit_eof ()
|
fhandler_pty_master::hit_eof ()
|
||||||
{
|
{
|
||||||
|
@ -245,7 +181,7 @@ fhandler_pty_master::hit_eof ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process tty output requests */
|
/* Process pty output requests */
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on)
|
fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on)
|
||||||
|
@ -311,12 +247,6 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
||||||
if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
|
if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (is_tty_master ())
|
|
||||||
{
|
|
||||||
Sleep (10);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_nonblocking ())
|
if (is_nonblocking ())
|
||||||
{
|
{
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
|
@ -342,8 +272,6 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
||||||
|
|
||||||
termios_printf ("bytes read %u", n);
|
termios_printf ("bytes read %u", n);
|
||||||
get_ttyp ()->write_error = 0;
|
get_ttyp ()->write_error = 0;
|
||||||
if (output_done_event != NULL)
|
|
||||||
SetEvent (output_done_event);
|
|
||||||
|
|
||||||
if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
|
if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
|
||||||
continue;
|
continue;
|
||||||
|
@ -424,69 +352,23 @@ out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI
|
/* pty slave stuff */
|
||||||
process_output (void *)
|
|
||||||
{
|
|
||||||
char buf[OUT_BUFFER_SIZE * 2];
|
|
||||||
|
|
||||||
for (;;)
|
fhandler_pty_slave::fhandler_pty_slave (int unit)
|
||||||
{
|
: fhandler_pty_common (), inuse (NULL)
|
||||||
int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0);
|
|
||||||
if (n > 0)
|
|
||||||
{
|
|
||||||
n = tty_master->console->write ((void *) buf, (size_t) n);
|
|
||||||
tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (n < 0)
|
|
||||||
termios_printf ("ReadFile %E");
|
|
||||||
ExitThread (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Process tty ioctl requests */
|
|
||||||
|
|
||||||
static void WINAPI
|
|
||||||
process_ioctl (void *)
|
|
||||||
{
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
WaitForSingleObject (tty_master->ioctl_request_event, INFINITE);
|
|
||||||
termios_printf ("ioctl() request");
|
|
||||||
tty *ttyp = tty_master->get_ttyp ();
|
|
||||||
ttyp->ioctl_retval =
|
|
||||||
tty_master->console->ioctl (ttyp->cmd,
|
|
||||||
(ttyp->cmd == KDSKBMETA)
|
|
||||||
? (void *) ttyp->arg.value
|
|
||||||
: (void *) &ttyp->arg);
|
|
||||||
SetEvent (tty_master->ioctl_done_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************/
|
|
||||||
/* Tty slave stuff */
|
|
||||||
|
|
||||||
fhandler_tty_slave::fhandler_tty_slave (int unit)
|
|
||||||
: fhandler_tty_common (), inuse (NULL)
|
|
||||||
{
|
{
|
||||||
if (unit >= 0)
|
if (unit >= 0)
|
||||||
dev ().parse (DEV_TTYS_MAJOR, unit);
|
dev ().parse (DEV_TTYS_MAJOR, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: This function needs to close handles when it has
|
|
||||||
a failing condition. */
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::open (int flags, mode_t)
|
fhandler_pty_slave::open (int flags, mode_t)
|
||||||
{
|
{
|
||||||
HANDLE tty_owner, from_master_local, to_master_local;
|
HANDLE pty_owner, from_master_local, to_master_local;
|
||||||
HANDLE *handles[] =
|
HANDLE *handles[] =
|
||||||
{
|
{
|
||||||
&from_master_local, &input_available_event, &input_mutex, &inuse,
|
&from_master_local, &input_available_event, &input_mutex, &inuse,
|
||||||
&ioctl_done_event, &ioctl_request_event, &output_done_event,
|
&output_mutex, &to_master_local, &pty_owner,
|
||||||
&output_mutex, &to_master_local, &tty_owner,
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -502,14 +384,6 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
/* Create synchronisation events */
|
/* Create synchronisation events */
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
/* output_done_event may or may not exist. It will exist if the tty
|
|
||||||
was opened by fhandler_tty_master::init, normally called at
|
|
||||||
startup if use_tty is non-zero. It will not exist if this is a
|
|
||||||
pty opened by fhandler_pty_master::open. In the former case, tty
|
|
||||||
output is handled by a separate thread which controls output. */
|
|
||||||
shared_name (buf, OUTPUT_DONE_EVENT, get_unit ());
|
|
||||||
output_done_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf);
|
|
||||||
|
|
||||||
const char *errmsg = NULL;
|
const char *errmsg = NULL;
|
||||||
|
|
||||||
if (!(output_mutex = get_ttyp ()->open_output_mutex (MAXIMUM_ALLOWED)))
|
if (!(output_mutex = get_ttyp ()->open_output_mutex (MAXIMUM_ALLOWED)))
|
||||||
|
@ -529,13 +403,6 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The ioctl events may or may not exist. See output_done_event,
|
|
||||||
above. */
|
|
||||||
shared_name (buf, IOCTL_REQUEST_EVENT, get_unit ());
|
|
||||||
ioctl_request_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf);
|
|
||||||
shared_name (buf, IOCTL_DONE_EVENT, get_unit ());
|
|
||||||
ioctl_done_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf);
|
|
||||||
|
|
||||||
/* FIXME: Needs a method to eliminate tty races */
|
/* FIXME: Needs a method to eliminate tty races */
|
||||||
{
|
{
|
||||||
/* Create security attribute. Default permissions are 0620. */
|
/* Create security attribute. Default permissions are 0620. */
|
||||||
|
@ -555,7 +422,7 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
|
|
||||||
if (!get_ttyp ()->from_master || !get_ttyp ()->to_master)
|
if (!get_ttyp ()->from_master || !get_ttyp ()->to_master)
|
||||||
{
|
{
|
||||||
errmsg = "tty handles have been closed";
|
errmsg = "pty handles have been closed";
|
||||||
set_errno (EACCES);
|
set_errno (EACCES);
|
||||||
goto err_no_errno;
|
goto err_no_errno;
|
||||||
}
|
}
|
||||||
|
@ -578,23 +445,23 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
{
|
{
|
||||||
/* This is the most common case, just calling openpty. */
|
/* This is the most common case, just calling openpty. */
|
||||||
termios_printf ("dup handles within myself.");
|
termios_printf ("dup handles within myself.");
|
||||||
tty_owner = GetCurrentProcess ();
|
pty_owner = GetCurrentProcess ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pinfo p (get_ttyp ()->master_pid);
|
pinfo p (get_ttyp ()->master_pid);
|
||||||
if (!p)
|
if (!p)
|
||||||
termios_printf ("*** couldn't find tty master");
|
termios_printf ("*** couldn't find pty master");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE, p->dwProcessId);
|
pty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE, p->dwProcessId);
|
||||||
if (tty_owner)
|
if (pty_owner)
|
||||||
termios_printf ("dup handles directly since I'm allmighty.");
|
termios_printf ("dup handles directly since I'm allmighty.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tty_owner)
|
if (pty_owner)
|
||||||
{
|
{
|
||||||
if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master,
|
if (!DuplicateHandle (pty_owner, get_ttyp ()->from_master,
|
||||||
GetCurrentProcess (), &from_master_local, 0, TRUE,
|
GetCurrentProcess (), &from_master_local, 0, TRUE,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
|
@ -603,15 +470,15 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
goto err_no_msg;
|
goto err_no_msg;
|
||||||
}
|
}
|
||||||
if (!DuplicateHandle (tty_owner, get_ttyp ()->to_master,
|
if (!DuplicateHandle (pty_owner, get_ttyp ()->to_master,
|
||||||
GetCurrentProcess (), &to_master_local, 0, TRUE,
|
GetCurrentProcess (), &to_master_local, 0, TRUE,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
errmsg = "can't duplicate output, %E";
|
errmsg = "can't duplicate output, %E";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (tty_owner != GetCurrentProcess ())
|
if (pty_owner != GetCurrentProcess ())
|
||||||
CloseHandle (tty_owner);
|
CloseHandle (pty_owner);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -619,7 +486,7 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
pipe_reply repl;
|
pipe_reply repl;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl",
|
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
||||||
&installation_key, get_unit ());
|
&installation_key, get_unit ());
|
||||||
termios_printf ("dup handles via master control pipe %s", buf);
|
termios_printf ("dup handles via master control pipe %s", buf);
|
||||||
if (!CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl,
|
if (!CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl,
|
||||||
|
@ -640,9 +507,9 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
VerifyHandle (from_master_local);
|
VerifyHandle (from_master_local);
|
||||||
VerifyHandle (to_master_local);
|
VerifyHandle (to_master_local);
|
||||||
|
|
||||||
termios_printf ("duplicated from_master %p->%p from tty_owner",
|
termios_printf ("duplicated from_master %p->%p from pty_owner",
|
||||||
get_ttyp ()->from_master, from_master_local);
|
get_ttyp ()->from_master, from_master_local);
|
||||||
termios_printf ("duplicated to_master %p->%p from tty_owner",
|
termios_printf ("duplicated to_master %p->%p from pty_owner",
|
||||||
get_ttyp ()->to_master, to_master_local);
|
get_ttyp ()->to_master, to_master_local);
|
||||||
|
|
||||||
set_io_handle (from_master_local);
|
set_io_handle (from_master_local);
|
||||||
|
@ -650,8 +517,7 @@ fhandler_tty_slave::open (int flags, mode_t)
|
||||||
set_close_on_exec (!!(flags & O_CLOEXEC));
|
set_close_on_exec (!!(flags & O_CLOEXEC));
|
||||||
|
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1
|
if (cygheap->manage_console_count ("fhandler_pty_slave::open", 1) == 1)
|
||||||
&& !output_done_event)
|
|
||||||
fhandler_console::need_invisible ();
|
fhandler_console::need_invisible ();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -667,37 +533,37 @@ err_no_msg:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_tty_slave::open_setup (int flags)
|
fhandler_pty_slave::open_setup (int flags)
|
||||||
{
|
{
|
||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
myself->set_ctty (get_ttyp (), flags, this);
|
myself->set_ctty (get_ttyp (), flags, this);
|
||||||
cygheap->manage_console_count ("fhandler_tty_slave::setup", 1);
|
cygheap->manage_console_count ("fhandler_pty_slave::setup", 1);
|
||||||
report_tty_counts (this, "opened", "");
|
report_tty_counts (this, "opened", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_tty_slave::cleanup ()
|
fhandler_pty_slave::cleanup ()
|
||||||
{
|
{
|
||||||
/* This used to always call fhandler_tty_common::close when hExeced but that
|
/* This used to always call fhandler_pty_common::close when hExeced but that
|
||||||
caused multiple closes of the handles associated with this tty. Since
|
caused multiple closes of the handles associated with this pty. Since
|
||||||
close_all_files is not called until after the cygwin process has synced
|
close_all_files is not called until after the cygwin process has synced
|
||||||
or before a non-cygwin process has exited, it should be safe to just
|
or before a non-cygwin process has exited, it should be safe to just
|
||||||
close this normally. cgf 2006-05-20 */
|
close this normally. cgf 2006-05-20 */
|
||||||
cygheap->manage_console_count ("fhandler_tty_slave::close", -1);
|
cygheap->manage_console_count ("fhandler_pty_slave::close", -1);
|
||||||
report_tty_counts (this, "closed", "");
|
report_tty_counts (this, "closed", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::close ()
|
fhandler_pty_slave::close ()
|
||||||
{
|
{
|
||||||
termios_printf ("closing last open %s handle", ttyname ());
|
termios_printf ("closing last open %s handle", ttyname ());
|
||||||
if (inuse && !CloseHandle (inuse))
|
if (inuse && !CloseHandle (inuse))
|
||||||
termios_printf ("CloseHandle (inuse), %E");
|
termios_printf ("CloseHandle (inuse), %E");
|
||||||
return fhandler_tty_common::close ();
|
return fhandler_pty_common::close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::init (HANDLE h, DWORD a, mode_t)
|
fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
|
@ -715,12 +581,12 @@ fhandler_tty_slave::init (HANDLE h, DWORD a, mode_t)
|
||||||
{
|
{
|
||||||
/* This only occurs when called from dtable::init_std_file_from_handle
|
/* This only occurs when called from dtable::init_std_file_from_handle
|
||||||
We have been started from a non-Cygwin process. So we should become
|
We have been started from a non-Cygwin process. So we should become
|
||||||
tty process group leader.
|
pty process group leader.
|
||||||
TODO: Investigate how SIGTTIN should be handled with pure-windows
|
TODO: Investigate how SIGTTIN should be handled with pure-windows
|
||||||
programs. */
|
programs. */
|
||||||
pinfo p (tc ()->getpgid ());
|
pinfo p (tc ()->getpgid ());
|
||||||
/* We should only grab this when the process group owner for this
|
/* We should only grab this when the process group owner for this
|
||||||
tty is a non-cygwin process or we've been started directly
|
pty is a non-cygwin process or we've been started directly
|
||||||
from a non-Cygwin process with no Cygwin ancestry. */
|
from a non-Cygwin process with no Cygwin ancestry. */
|
||||||
if (!p || ISSTATE (p, PID_NOTCYGWIN))
|
if (!p || ISSTATE (p, PID_NOTCYGWIN))
|
||||||
{
|
{
|
||||||
|
@ -737,7 +603,7 @@ fhandler_tty_slave::init (HANDLE h, DWORD a, mode_t)
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
fhandler_tty_slave::write (const void *ptr, size_t len)
|
fhandler_pty_slave::write (const void *ptr, size_t len)
|
||||||
{
|
{
|
||||||
DWORD n, towrite = len;
|
DWORD n, towrite = len;
|
||||||
|
|
||||||
|
@ -759,7 +625,7 @@ fhandler_tty_slave::write (const void *ptr, size_t len)
|
||||||
len -= n;
|
len -= n;
|
||||||
|
|
||||||
/* Previous write may have set write_error to != 0. Check it here.
|
/* Previous write may have set write_error to != 0. Check it here.
|
||||||
This is less than optimal, but the alternative slows down tty
|
This is less than optimal, but the alternative slows down pty
|
||||||
writes enormously. */
|
writes enormously. */
|
||||||
if (get_ttyp ()->write_error)
|
if (get_ttyp ()->write_error)
|
||||||
{
|
{
|
||||||
|
@ -783,21 +649,13 @@ fhandler_tty_slave::write (const void *ptr, size_t len)
|
||||||
towrite = (DWORD) -1;
|
towrite = (DWORD) -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_done_event != NULL)
|
|
||||||
{
|
|
||||||
DWORD rc;
|
|
||||||
DWORD x = n * 1000;
|
|
||||||
rc = WaitForSingleObject (output_done_event, x);
|
|
||||||
termios_printf ("waited %d ms for output_done_event, WFSO %d", x, rc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
release_output_mutex ();
|
release_output_mutex ();
|
||||||
return towrite;
|
return towrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
void __stdcall
|
||||||
fhandler_tty_slave::read (void *ptr, size_t& len)
|
fhandler_pty_slave::read (void *ptr, size_t& len)
|
||||||
{
|
{
|
||||||
int totalread = 0;
|
int totalread = 0;
|
||||||
int vmin = 0;
|
int vmin = 0;
|
||||||
|
@ -1030,9 +888,9 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::dup (fhandler_base *child)
|
fhandler_pty_slave::dup (fhandler_base *child)
|
||||||
{
|
{
|
||||||
cygheap->manage_console_count ("fhandler_tty_slave::dup", 1);
|
cygheap->manage_console_count ("fhandler_pty_slave::dup", 1);
|
||||||
report_tty_counts (child, "duped slave", "");
|
report_tty_counts (child, "duped slave", "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1045,14 +903,14 @@ fhandler_pty_master::dup (fhandler_base *child)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::tcgetattr (struct termios *t)
|
fhandler_pty_slave::tcgetattr (struct termios *t)
|
||||||
{
|
{
|
||||||
*t = get_ttyp ()->ti;
|
*t = get_ttyp ()->ti;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::tcsetattr (int, const struct termios *t)
|
fhandler_pty_slave::tcsetattr (int, const struct termios *t)
|
||||||
{
|
{
|
||||||
acquire_output_mutex (INFINITE);
|
acquire_output_mutex (INFINITE);
|
||||||
get_ttyp ()->ti = *t;
|
get_ttyp ()->ti = *t;
|
||||||
|
@ -1061,7 +919,7 @@ fhandler_tty_slave::tcsetattr (int, const struct termios *t)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::tcflush (int queue)
|
fhandler_pty_slave::tcflush (int queue)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -1083,7 +941,7 @@ fhandler_tty_slave::tcflush (int queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::ioctl (unsigned int cmd, void *arg)
|
fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
termios_printf ("ioctl (%x)", cmd);
|
termios_printf ("ioctl (%x)", cmd);
|
||||||
|
|
||||||
|
@ -1139,11 +997,7 @@ fhandler_tty_slave::ioctl (unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
case TIOCGWINSZ:
|
case TIOCGWINSZ:
|
||||||
get_ttyp ()->arg.winsize = get_ttyp ()->winsize;
|
get_ttyp ()->arg.winsize = get_ttyp ()->winsize;
|
||||||
if (ioctl_request_event)
|
|
||||||
SetEvent (ioctl_request_event);
|
|
||||||
*(struct winsize *) arg = get_ttyp ()->arg.winsize;
|
*(struct winsize *) arg = get_ttyp ()->arg.winsize;
|
||||||
if (ioctl_done_event)
|
|
||||||
WaitForSingleObject (ioctl_done_event, INFINITE);
|
|
||||||
get_ttyp ()->winsize = get_ttyp ()->arg.winsize;
|
get_ttyp ()->winsize = get_ttyp ()->arg.winsize;
|
||||||
break;
|
break;
|
||||||
case TIOCSWINSZ:
|
case TIOCSWINSZ:
|
||||||
|
@ -1151,52 +1005,19 @@ fhandler_tty_slave::ioctl (unsigned int cmd, void *arg)
|
||||||
|| get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
|
|| get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
|
||||||
{
|
{
|
||||||
get_ttyp ()->arg.winsize = *(struct winsize *) arg;
|
get_ttyp ()->arg.winsize = *(struct winsize *) arg;
|
||||||
if (ioctl_request_event)
|
|
||||||
{
|
|
||||||
get_ttyp ()->ioctl_retval = -EINVAL;
|
|
||||||
SetEvent (ioctl_request_event);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
get_ttyp ()->winsize = *(struct winsize *) arg;
|
get_ttyp ()->winsize = *(struct winsize *) arg;
|
||||||
killsys (-get_ttyp ()->getpgid (), SIGWINCH);
|
killsys (-get_ttyp ()->getpgid (), SIGWINCH);
|
||||||
}
|
}
|
||||||
if (ioctl_done_event)
|
|
||||||
WaitForSingleObject (ioctl_done_event, INFINITE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case TIOCLINUX:
|
case TIOCLINUX:
|
||||||
val = *(unsigned char *) arg;
|
val = *(unsigned char *) arg;
|
||||||
if (val != 6 || !ioctl_request_event || !ioctl_done_event)
|
if (val != 6)
|
||||||
get_ttyp ()->ioctl_retval = -EINVAL;
|
get_ttyp ()->ioctl_retval = -EINVAL;
|
||||||
else
|
|
||||||
{
|
|
||||||
get_ttyp ()->arg.value = val;
|
|
||||||
SetEvent (ioctl_request_event);
|
|
||||||
WaitForSingleObject (ioctl_done_event, INFINITE);
|
|
||||||
*(unsigned char *) arg = (unsigned char) (get_ttyp ()->arg.value);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KDGKBMETA:
|
case KDGKBMETA:
|
||||||
if (ioctl_request_event)
|
|
||||||
{
|
|
||||||
SetEvent (ioctl_request_event);
|
|
||||||
if (ioctl_done_event)
|
|
||||||
WaitForSingleObject (ioctl_done_event, INFINITE);
|
|
||||||
*(int *) arg = get_ttyp ()->arg.value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
get_ttyp ()->ioctl_retval = -EINVAL;
|
get_ttyp ()->ioctl_retval = -EINVAL;
|
||||||
break;
|
break;
|
||||||
case KDSKBMETA:
|
case KDSKBMETA:
|
||||||
if (ioctl_request_event)
|
|
||||||
{
|
|
||||||
get_ttyp ()->arg.value = (int) arg;
|
|
||||||
SetEvent (ioctl_request_event);
|
|
||||||
if (ioctl_done_event)
|
|
||||||
WaitForSingleObject (ioctl_done_event, INFINITE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
get_ttyp ()->ioctl_retval = -EINVAL;
|
get_ttyp ()->ioctl_retval = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1215,7 +1036,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_tty_slave::fstat (struct __stat64 *st)
|
fhandler_pty_slave::fstat (struct __stat64 *st)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (st);
|
fhandler_base::fstat (st);
|
||||||
|
|
||||||
|
@ -1246,7 +1067,7 @@ fhandler_tty_slave::fstat (struct __stat64 *st)
|
||||||
/* Helper function for fchmod and fchown, which just opens all handles
|
/* Helper function for fchmod and fchown, which just opens all handles
|
||||||
and signals success via bool return. */
|
and signals success via bool return. */
|
||||||
bool
|
bool
|
||||||
fhandler_tty_slave::fch_open_handles ()
|
fhandler_pty_slave::fch_open_handles ()
|
||||||
{
|
{
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
@ -1262,20 +1083,13 @@ fhandler_tty_slave::fch_open_handles ()
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* These members are optional, no error checking */
|
|
||||||
shared_name (buf, OUTPUT_DONE_EVENT, get_unit ());
|
|
||||||
output_done_event = OpenEvent (WRITE_DAC | WRITE_OWNER, TRUE, buf);
|
|
||||||
shared_name (buf, IOCTL_REQUEST_EVENT, get_unit ());
|
|
||||||
ioctl_request_event = OpenEvent (WRITE_DAC | WRITE_OWNER, TRUE, buf);
|
|
||||||
shared_name (buf, IOCTL_DONE_EVENT, get_unit ());
|
|
||||||
ioctl_done_event = OpenEvent (WRITE_DAC | WRITE_OWNER, TRUE, buf);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function for fchmod and fchown, which sets the new security
|
/* Helper function for fchmod and fchown, which sets the new security
|
||||||
descriptor on all objects representing the tty. */
|
descriptor on all objects representing the pty. */
|
||||||
int
|
int
|
||||||
fhandler_tty_slave::fch_set_sd (security_descriptor &sd, bool chown)
|
fhandler_pty_slave::fch_set_sd (security_descriptor &sd, bool chown)
|
||||||
{
|
{
|
||||||
security_descriptor sd_old;
|
security_descriptor sd_old;
|
||||||
|
|
||||||
|
@ -1283,37 +1097,22 @@ fhandler_tty_slave::fch_set_sd (security_descriptor &sd, bool chown)
|
||||||
if (!set_object_sd (input_available_event, sd, chown)
|
if (!set_object_sd (input_available_event, sd, chown)
|
||||||
&& !set_object_sd (output_mutex, sd, chown)
|
&& !set_object_sd (output_mutex, sd, chown)
|
||||||
&& !set_object_sd (input_mutex, sd, chown)
|
&& !set_object_sd (input_mutex, sd, chown)
|
||||||
&& !set_object_sd (inuse, sd, chown)
|
&& !set_object_sd (inuse, sd, chown))
|
||||||
&& (!output_done_event
|
|
||||||
|| !set_object_sd (output_done_event, sd, chown))
|
|
||||||
&& (!ioctl_request_event
|
|
||||||
|| !set_object_sd (ioctl_request_event, sd, chown))
|
|
||||||
&& (!ioctl_done_event
|
|
||||||
|| !set_object_sd (ioctl_done_event, sd, chown)))
|
|
||||||
return 0;
|
return 0;
|
||||||
set_object_sd (input_available_event, sd_old, chown);
|
set_object_sd (input_available_event, sd_old, chown);
|
||||||
set_object_sd (output_mutex, sd_old, chown);
|
set_object_sd (output_mutex, sd_old, chown);
|
||||||
set_object_sd (input_mutex, sd_old, chown);
|
set_object_sd (input_mutex, sd_old, chown);
|
||||||
set_object_sd (inuse, sd_old, chown);
|
set_object_sd (inuse, sd_old, chown);
|
||||||
if (!output_done_event)
|
|
||||||
set_object_sd (output_done_event, sd_old, chown);
|
|
||||||
if (!ioctl_request_event)
|
|
||||||
set_object_sd (ioctl_request_event, sd_old, chown);
|
|
||||||
if (!ioctl_done_event)
|
|
||||||
set_object_sd (ioctl_done_event, sd_old, chown);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function for fchmod and fchown, which closes all object handles in
|
/* Helper function for fchmod and fchown, which closes all object handles in
|
||||||
the tty. */
|
the pty. */
|
||||||
void
|
void
|
||||||
fhandler_tty_slave::fch_close_handles ()
|
fhandler_pty_slave::fch_close_handles ()
|
||||||
{
|
{
|
||||||
close_maybe (get_io_handle ());
|
close_maybe (get_io_handle ());
|
||||||
close_maybe (get_output_handle ());
|
close_maybe (get_output_handle ());
|
||||||
close_maybe (output_done_event);
|
|
||||||
close_maybe (ioctl_done_event);
|
|
||||||
close_maybe (ioctl_request_event);
|
|
||||||
close_maybe (input_available_event);
|
close_maybe (input_available_event);
|
||||||
close_maybe (output_mutex);
|
close_maybe (output_mutex);
|
||||||
close_maybe (input_mutex);
|
close_maybe (input_mutex);
|
||||||
|
@ -1321,7 +1120,7 @@ fhandler_tty_slave::fch_close_handles ()
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_tty_slave::fchmod (mode_t mode)
|
fhandler_pty_slave::fchmod (mode_t mode)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
bool to_close = false;
|
bool to_close = false;
|
||||||
|
@ -1347,7 +1146,7 @@ errout:
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_tty_slave::fchown (__uid32_t uid, __gid32_t gid)
|
fhandler_pty_slave::fchown (__uid32_t uid, __gid32_t gid)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
bool to_close = false;
|
bool to_close = false;
|
||||||
|
@ -1385,7 +1184,7 @@ errout:
|
||||||
fhandler_pty_master
|
fhandler_pty_master
|
||||||
*/
|
*/
|
||||||
fhandler_pty_master::fhandler_pty_master ()
|
fhandler_pty_master::fhandler_pty_master ()
|
||||||
: fhandler_tty_common (), pktmode (0), need_nl (0), dwProcessId (0)
|
: fhandler_pty_common (), pktmode (0), need_nl (0), dwProcessId (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1393,12 +1192,12 @@ int
|
||||||
fhandler_pty_master::open (int flags, mode_t)
|
fhandler_pty_master::open (int flags, mode_t)
|
||||||
{
|
{
|
||||||
/* Note that allocate returns with the tty lock set if it was successful. */
|
/* Note that allocate returns with the tty lock set if it was successful. */
|
||||||
int unit = cygwin_shared->tty.allocate (false);
|
int unit = cygwin_shared->tty.allocate ();
|
||||||
if (unit < 0)
|
if (unit < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev().parse (DEV_TTYM_MAJOR, unit);
|
dev().parse (DEV_TTYM_MAJOR, unit);
|
||||||
if (!setup (true))
|
if (!setup ())
|
||||||
{
|
{
|
||||||
lock_ttys::release ();
|
lock_ttys::release ();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1416,22 +1215,16 @@ fhandler_pty_master::open (int flags, mode_t)
|
||||||
}
|
}
|
||||||
|
|
||||||
_off64_t
|
_off64_t
|
||||||
fhandler_tty_common::lseek (_off64_t, int)
|
fhandler_pty_common::lseek (_off64_t, int)
|
||||||
{
|
{
|
||||||
set_errno (ESPIPE);
|
set_errno (ESPIPE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_tty_common::close ()
|
fhandler_pty_common::close ()
|
||||||
{
|
{
|
||||||
termios_printf ("tty%d <%p,%p> closing", get_unit (), get_handle (), get_output_handle ());
|
termios_printf ("tty%d <%p,%p> closing", get_unit (), get_handle (), get_output_handle ());
|
||||||
if (output_done_event && !CloseHandle (output_done_event))
|
|
||||||
termios_printf ("CloseHandle (output_done_event), %E");
|
|
||||||
if (ioctl_done_event && !CloseHandle (ioctl_done_event))
|
|
||||||
termios_printf ("CloseHandle (ioctl_done_event), %E");
|
|
||||||
if (ioctl_request_event && !CloseHandle (ioctl_request_event))
|
|
||||||
termios_printf ("CloseHandle (ioctl_request_event), %E");
|
|
||||||
if (!ForceCloseHandle (input_mutex))
|
if (!ForceCloseHandle (input_mutex))
|
||||||
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
|
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
|
||||||
if (!ForceCloseHandle (output_mutex))
|
if (!ForceCloseHandle (output_mutex))
|
||||||
|
@ -1472,7 +1265,7 @@ fhandler_pty_master::close ()
|
||||||
pipe_reply repl;
|
pipe_reply repl;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl",
|
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
||||||
&installation_key, get_unit ());
|
&installation_key, get_unit ());
|
||||||
CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
|
CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
|
||||||
CloseHandle (master_ctl);
|
CloseHandle (master_ctl);
|
||||||
|
@ -1483,7 +1276,7 @@ fhandler_pty_master::close ()
|
||||||
if (!ForceCloseHandle (to_master))
|
if (!ForceCloseHandle (to_master))
|
||||||
termios_printf ("error closing from_master %p, %E", to_master);
|
termios_printf ("error closing from_master %p, %E", to_master);
|
||||||
}
|
}
|
||||||
fhandler_tty_common::close ();
|
fhandler_pty_common::close ();
|
||||||
|
|
||||||
if (hExeced || get_ttyp ()->master_pid != myself->pid)
|
if (hExeced || get_ttyp ()->master_pid != myself->pid)
|
||||||
termios_printf ("not clearing: %d, master_pid %d", hExeced, get_ttyp ()->master_pid);
|
termios_printf ("not clearing: %d, master_pid %d", hExeced, get_ttyp ()->master_pid);
|
||||||
|
@ -1608,42 +1401,27 @@ fhandler_pty_master::ptsname ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_tty_common::set_close_on_exec (bool val)
|
fhandler_pty_common::set_close_on_exec (bool val)
|
||||||
{
|
{
|
||||||
// Cygwin processes will handle this specially on exec.
|
// Cygwin processes will handle this specially on exec.
|
||||||
close_on_exec (val);
|
close_on_exec (val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_tty_slave::fixup_after_fork (HANDLE parent)
|
fhandler_pty_slave::fixup_after_fork (HANDLE parent)
|
||||||
{
|
{
|
||||||
// fork_fixup (parent, inuse, "inuse");
|
// fork_fixup (parent, inuse, "inuse");
|
||||||
// fhandler_tty_common::fixup_after_fork (parent);
|
// fhandler_pty_common::fixup_after_fork (parent);
|
||||||
report_tty_counts (this, "inherited", "");
|
report_tty_counts (this, "inherited", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_tty_slave::fixup_after_exec ()
|
fhandler_pty_slave::fixup_after_exec ()
|
||||||
{
|
{
|
||||||
if (!close_on_exec ())
|
if (!close_on_exec ())
|
||||||
fixup_after_fork (NULL);
|
fixup_after_fork (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_tty_master::init_console ()
|
|
||||||
{
|
|
||||||
console = (fhandler_console *) build_fh_dev (*console_dev, "/dev/ttym_console");
|
|
||||||
if (console == NULL)
|
|
||||||
{
|
|
||||||
termios_printf ("console creation failed?");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
console->init (NULL, GENERIC_READ | GENERIC_WRITE, O_BINARY);
|
|
||||||
cygheap->manage_console_count ("fhandler_tty_master::init_console", -1, true);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" BOOL WINAPI GetNamedPipeClientProcessId (HANDLE, PULONG);
|
extern "C" BOOL WINAPI GetNamedPipeClientProcessId (HANDLE, PULONG);
|
||||||
|
|
||||||
/* This thread function handles the master control pipe. It waits for a
|
/* This thread function handles the master control pipe. It waits for a
|
||||||
|
@ -1791,7 +1569,7 @@ pty_master_thread (VOID *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fhandler_pty_master::setup (bool ispty)
|
fhandler_pty_master::setup ()
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
security_descriptor sd;
|
security_descriptor sd;
|
||||||
|
@ -1806,11 +1584,11 @@ fhandler_pty_master::setup (bool ispty)
|
||||||
DWORD pipe_mode = PIPE_NOWAIT;
|
DWORD pipe_mode = PIPE_NOWAIT;
|
||||||
|
|
||||||
/* Create communication pipes */
|
/* Create communication pipes */
|
||||||
char pipename[sizeof("ttyNNNN-from-master")];
|
char pipename[sizeof("ptyNNNN-from-master")];
|
||||||
__small_sprintf (pipename, "tty%d-from-master", get_unit ());
|
__small_sprintf (pipename, "pty%d-from-master", get_unit ());
|
||||||
res = fhandler_pipe::create_selectable (ispty ? &sec_none : &sec_none_nih,
|
res = fhandler_pipe::create_selectable (&sec_none, from_master,
|
||||||
from_master, get_output_handle (),
|
get_output_handle (), 128 * 1024,
|
||||||
128 * 1024, pipename);
|
pipename);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
errstr = "input pipe";
|
errstr = "input pipe";
|
||||||
|
@ -1821,10 +1599,9 @@ fhandler_pty_master::setup (bool ispty)
|
||||||
termios_printf ("can't set output_handle(%p) to non-blocking mode",
|
termios_printf ("can't set output_handle(%p) to non-blocking mode",
|
||||||
get_output_handle ());
|
get_output_handle ());
|
||||||
|
|
||||||
__small_sprintf (pipename, "tty%d-to-master", get_unit ());
|
__small_sprintf (pipename, "pty%d-to-master", get_unit ());
|
||||||
res = fhandler_pipe::create_selectable (ispty ? &sec_none : &sec_none_nih,
|
res = fhandler_pipe::create_selectable (&sec_none, get_io_handle (),
|
||||||
get_io_handle (), to_master,
|
to_master, 128 * 1024, pipename);
|
||||||
128 * 1024, pipename);
|
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
errstr = "output pipe";
|
errstr = "output pipe";
|
||||||
|
@ -1841,19 +1618,6 @@ fhandler_pty_master::setup (bool ispty)
|
||||||
sd))
|
sd))
|
||||||
sa.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR) sd;
|
sa.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR) sd;
|
||||||
|
|
||||||
/* Create synchronisation events */
|
|
||||||
|
|
||||||
if (!ispty)
|
|
||||||
{
|
|
||||||
if (!(output_done_event = t.get_event (errstr = OUTPUT_DONE_EVENT, &sa)))
|
|
||||||
goto err;
|
|
||||||
if (!(ioctl_done_event = t.get_event (errstr = IOCTL_DONE_EVENT, &sa)))
|
|
||||||
goto err;
|
|
||||||
if (!(ioctl_request_event = t.get_event (errstr = IOCTL_REQUEST_EVENT,
|
|
||||||
&sa)))
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Carefully check that the input_available_event didn't already exist.
|
/* Carefully check that the input_available_event didn't already exist.
|
||||||
This is a measure to make sure that the event security descriptor
|
This is a measure to make sure that the event security descriptor
|
||||||
isn't occupied by a malicious process. We must make sure that the
|
isn't occupied by a malicious process. We must make sure that the
|
||||||
|
@ -1874,7 +1638,7 @@ fhandler_pty_master::setup (bool ispty)
|
||||||
|
|
||||||
/* Create master control pipe which allows the master to duplicate
|
/* Create master control pipe which allows the master to duplicate
|
||||||
the pty pipe handles to processes which deserve it. */
|
the pty pipe handles to processes which deserve it. */
|
||||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl",
|
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
||||||
&installation_key, get_unit ());
|
&installation_key, get_unit ());
|
||||||
master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX,
|
master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX,
|
||||||
PIPE_WAIT | PIPE_TYPE_MESSAGE
|
PIPE_WAIT | PIPE_TYPE_MESSAGE
|
||||||
|
@ -1894,8 +1658,6 @@ fhandler_pty_master::setup (bool ispty)
|
||||||
|
|
||||||
t.from_master = from_master;
|
t.from_master = from_master;
|
||||||
t.to_master = to_master;
|
t.to_master = to_master;
|
||||||
// /* screws up tty master */ ProtectHandle1INH (output_mutex, output_mutex);
|
|
||||||
// /* screws up tty master */ ProtectHandle1INH (input_mutex, input_mutex);
|
|
||||||
t.winsize.ws_col = 80;
|
t.winsize.ws_col = 80;
|
||||||
t.winsize.ws_row = 25;
|
t.winsize.ws_row = 25;
|
||||||
t.master_pid = myself->pid;
|
t.master_pid = myself->pid;
|
||||||
|
@ -1908,9 +1670,6 @@ err:
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
close_maybe (get_io_handle ());
|
close_maybe (get_io_handle ());
|
||||||
close_maybe (get_output_handle ());
|
close_maybe (get_output_handle ());
|
||||||
close_maybe (output_done_event);
|
|
||||||
close_maybe (ioctl_done_event);
|
|
||||||
close_maybe (ioctl_request_event);
|
|
||||||
close_maybe (input_available_event);
|
close_maybe (input_available_event);
|
||||||
close_maybe (output_mutex);
|
close_maybe (output_mutex);
|
||||||
close_maybe (input_mutex);
|
close_maybe (input_mutex);
|
||||||
|
@ -1925,7 +1684,7 @@ void
|
||||||
fhandler_pty_master::fixup_after_fork (HANDLE parent)
|
fhandler_pty_master::fixup_after_fork (HANDLE parent)
|
||||||
{
|
{
|
||||||
DWORD wpid = GetCurrentProcessId ();
|
DWORD wpid = GetCurrentProcessId ();
|
||||||
fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
|
fhandler_pty_master *arch = (fhandler_pty_master *) archetype;
|
||||||
if (arch->dwProcessId != wpid)
|
if (arch->dwProcessId != wpid)
|
||||||
{
|
{
|
||||||
tty& t = *get_ttyp ();
|
tty& t = *get_ttyp ();
|
||||||
|
|
|
@ -162,9 +162,7 @@ enum
|
||||||
PID_MYSELF = 0x00200, /* Flag that pid is me. */
|
PID_MYSELF = 0x00200, /* Flag that pid is me. */
|
||||||
PID_NOCLDSTOP = 0x00400, /* Set if no SIGCHLD signal on stop. */
|
PID_NOCLDSTOP = 0x00400, /* Set if no SIGCHLD signal on stop. */
|
||||||
PID_INITIALIZING = 0x00800, /* Set until ready to receive signals. */
|
PID_INITIALIZING = 0x00800, /* Set until ready to receive signals. */
|
||||||
PID_USETTY = 0x01000, /* Setting this enables or disables cygwin's
|
PID_UNUSED1 = 0x01000, /* Available. */
|
||||||
tty support. This is inherited by
|
|
||||||
all execed or forked processes. */
|
|
||||||
PID_ALLPIDS = 0x02000, /* used by pinfo scanner */
|
PID_ALLPIDS = 0x02000, /* used by pinfo scanner */
|
||||||
PID_EXECED = 0x04000, /* redirect to original pid info block */
|
PID_EXECED = 0x04000, /* redirect to original pid info block */
|
||||||
PID_NOREDIR = 0x08000, /* don't redirect if execed */
|
PID_NOREDIR = 0x08000, /* don't redirect if execed */
|
||||||
|
|
|
@ -886,7 +886,7 @@ fhandler_console::select_except (select_stuff *ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
select_record *
|
select_record *
|
||||||
fhandler_tty_common::select_read (select_stuff *ss)
|
fhandler_pty_common::select_read (select_stuff *ss)
|
||||||
{
|
{
|
||||||
if (!ss->device_specific_pipe
|
if (!ss->device_specific_pipe
|
||||||
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
||||||
|
@ -903,7 +903,7 @@ fhandler_tty_common::select_read (select_stuff *ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
select_record *
|
select_record *
|
||||||
fhandler_tty_common::select_write (select_stuff *ss)
|
fhandler_pty_common::select_write (select_stuff *ss)
|
||||||
{
|
{
|
||||||
if (!ss->device_specific_pipe
|
if (!ss->device_specific_pipe
|
||||||
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
||||||
|
@ -919,7 +919,7 @@ fhandler_tty_common::select_write (select_stuff *ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
select_record *
|
select_record *
|
||||||
fhandler_tty_common::select_except (select_stuff *ss)
|
fhandler_pty_common::select_except (select_stuff *ss)
|
||||||
{
|
{
|
||||||
if (!ss->device_specific_pipe
|
if (!ss->device_specific_pipe
|
||||||
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
||||||
|
@ -944,7 +944,7 @@ verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
|
||||||
}
|
}
|
||||||
|
|
||||||
select_record *
|
select_record *
|
||||||
fhandler_tty_slave::select_read (select_stuff *ss)
|
fhandler_pty_slave::select_read (select_stuff *ss)
|
||||||
{
|
{
|
||||||
select_record *s = ss->start.next;
|
select_record *s = ss->start.next;
|
||||||
s->h = input_available_event;
|
s->h = input_available_event;
|
||||||
|
|
|
@ -231,7 +231,7 @@ proc_subproc (DWORD what, DWORD val)
|
||||||
vchild->sid = myself->sid;
|
vchild->sid = myself->sid;
|
||||||
vchild->ctty = myself->ctty;
|
vchild->ctty = myself->ctty;
|
||||||
vchild->cygstarted = true;
|
vchild->cygstarted = true;
|
||||||
vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY);
|
vchild->process_state |= PID_INITIALIZING;
|
||||||
}
|
}
|
||||||
if (what == PROC_DETACHED_CHILD)
|
if (what == PROC_DETACHED_CHILD)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -23,7 +23,7 @@ details. */
|
||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
|
|
||||||
extern fhandler_tty_master *tty_master;
|
HANDLE NO_COPY tty_list::mutex = NULL;
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
posix_openpt (int oflags)
|
posix_openpt (int oflags)
|
||||||
|
@ -53,21 +53,18 @@ revoke (char *ttyname)
|
||||||
extern "C" int
|
extern "C" int
|
||||||
ttyslot (void)
|
ttyslot (void)
|
||||||
{
|
{
|
||||||
if (NOTSTATE (myself, PID_USETTY))
|
if (myself->ctty <= 0 || iscons_dev (myself->ctty))
|
||||||
return -1;
|
return -1;
|
||||||
return device::minor (myself->ctty);
|
return device::minor (myself->ctty);
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE NO_COPY tty_list::mutex = NULL;
|
|
||||||
|
|
||||||
void __stdcall
|
void __stdcall
|
||||||
tty_list::init_session ()
|
tty_list::init_session ()
|
||||||
{
|
{
|
||||||
char mutex_name[MAX_PATH];
|
char mutex_name[MAX_PATH];
|
||||||
/* tty_list::mutex is used while searching for a tty slot. It's necessary
|
|
||||||
while finding console window handle */
|
|
||||||
|
|
||||||
char *name = shared_name (mutex_name, "tty_list::mutex", 0);
|
char *name = shared_name (mutex_name, "tty_list::mutex", 0);
|
||||||
|
|
||||||
|
/* tty_list::mutex is used while searching for a tty slot */
|
||||||
if (!(mutex = CreateMutex (&sec_all_nih, FALSE, name)))
|
if (!(mutex = CreateMutex (&sec_all_nih, FALSE, name)))
|
||||||
api_fatal ("can't create tty_list::mutex '%s', %E", name);
|
api_fatal ("can't create tty_list::mutex '%s', %E", name);
|
||||||
ProtectHandle (mutex);
|
ProtectHandle (mutex);
|
||||||
|
@ -78,50 +75,6 @@ tty::init_session ()
|
||||||
{
|
{
|
||||||
if (!myself->cygstarted && NOTSTATE (myself, PID_CYGPARENT))
|
if (!myself->cygstarted && NOTSTATE (myself, PID_CYGPARENT))
|
||||||
cygheap->fdtab.get_debugger_info ();
|
cygheap->fdtab.get_debugger_info ();
|
||||||
|
|
||||||
if (NOTSTATE (myself, PID_USETTY))
|
|
||||||
return;
|
|
||||||
if (myself->ctty != -1)
|
|
||||||
/* nothing to do */;
|
|
||||||
else if (NOTSTATE (myself, PID_CYGPARENT))
|
|
||||||
myself->ctty = cygwin_shared->tty.attach (myself->ctty);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
if (myself->ctty == -1)
|
|
||||||
termios_printf ("Can't attach to tty");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create session's master tty */
|
|
||||||
|
|
||||||
void __stdcall
|
|
||||||
tty::create_master (int ttynum)
|
|
||||||
{
|
|
||||||
device ttym = *ttym_dev;
|
|
||||||
ttym.setunit (ttynum); /* CGF FIXME device */
|
|
||||||
tty_master = (fhandler_tty_master *) build_fh_dev (ttym);
|
|
||||||
if (tty_master->init ())
|
|
||||||
api_fatal ("can't create master tty");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Log utmp entry */
|
|
||||||
struct utmp our_utmp;
|
|
||||||
DWORD len = sizeof our_utmp.ut_host;
|
|
||||||
|
|
||||||
bzero ((char *) &our_utmp, sizeof (utmp));
|
|
||||||
time (&our_utmp.ut_time);
|
|
||||||
strncpy (our_utmp.ut_name, getlogin (), sizeof (our_utmp.ut_name));
|
|
||||||
GetComputerName (our_utmp.ut_host, &len);
|
|
||||||
__small_sprintf (our_utmp.ut_line, "tty%d", ttynum);
|
|
||||||
if ((len = strlen (our_utmp.ut_line)) >= UT_IDLEN)
|
|
||||||
len -= UT_IDLEN;
|
|
||||||
else
|
|
||||||
len = 0;
|
|
||||||
strncpy (our_utmp.ut_id, our_utmp.ut_line + len, UT_IDLEN);
|
|
||||||
our_utmp.ut_type = USER_PROCESS;
|
|
||||||
our_utmp.ut_pid = myself->pid;
|
|
||||||
myself->ctty = FHDEV (DEV_TTYS_MAJOR, ttynum);
|
|
||||||
login (&our_utmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
|
@ -132,56 +85,11 @@ tty_list::attach (int n)
|
||||||
res = -1;
|
res = -1;
|
||||||
else if (n != -1)
|
else if (n != -1)
|
||||||
res = connect (device::minor (n));
|
res = connect (device::minor (n));
|
||||||
else if (ISSTATE (myself, PID_USETTY))
|
|
||||||
res = allocate (true);
|
|
||||||
else
|
else
|
||||||
res = -1;
|
res = -1;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
tty_list::terminate ()
|
|
||||||
{
|
|
||||||
if (NOTSTATE (myself, PID_USETTY))
|
|
||||||
return;
|
|
||||||
int ttynum = device::minor (myself->ctty);
|
|
||||||
|
|
||||||
/* Keep master running till there are connected clients */
|
|
||||||
if (myself->ctty != -1 && tty_master && ttys[ttynum].master_pid == myself->pid)
|
|
||||||
{
|
|
||||||
tty *t = ttys + ttynum;
|
|
||||||
/* Wait for children which rely on tty handling in this process to
|
|
||||||
go away */
|
|
||||||
for (int i = 0; ; i++)
|
|
||||||
{
|
|
||||||
if (!t->slave_alive ())
|
|
||||||
break;
|
|
||||||
if (i >= 100)
|
|
||||||
{
|
|
||||||
small_printf ("waiting for children using tty%d to terminate\n",
|
|
||||||
ttynum);
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sleep (200);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_ttys here ();
|
|
||||||
CloseHandle (tty_master->from_master);
|
|
||||||
CloseHandle (tty_master->to_master);
|
|
||||||
|
|
||||||
termios_printf ("tty %d master about to finish", ttynum);
|
|
||||||
CloseHandle (tty_master->get_io_handle ());
|
|
||||||
CloseHandle (tty_master->get_output_handle ());
|
|
||||||
|
|
||||||
t->init ();
|
|
||||||
|
|
||||||
char buf[20];
|
|
||||||
__small_sprintf (buf, "tty%d", ttynum);
|
|
||||||
logout (buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
tty_list::connect (int ttynum)
|
tty_list::connect (int ttynum)
|
||||||
{
|
{
|
||||||
|
@ -209,83 +117,33 @@ tty_list::init ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search for tty class for our console. Allocate new tty if our process is
|
/* Search for a free tty and allocate it.
|
||||||
the only cygwin process in the current console.
|
|
||||||
Return tty number or -1 if error.
|
Return tty number or -1 if error.
|
||||||
If with_console == 0, just find a free tty.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
tty_list::allocate (bool with_console)
|
tty_list::allocate ()
|
||||||
{
|
{
|
||||||
HWND console;
|
|
||||||
int freetty = -1;
|
|
||||||
HANDLE hmaster = NULL;
|
|
||||||
|
|
||||||
lock_ttys here;
|
lock_ttys here;
|
||||||
|
int freetty = -1;
|
||||||
|
|
||||||
if (!with_console)
|
tty *t = NULL;
|
||||||
console = NULL;
|
|
||||||
else if (!(console = GetConsoleWindow ()))
|
|
||||||
{
|
|
||||||
termios_printf ("Can't find console window");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is a tty allocated for console? */
|
|
||||||
for (int i = 0; i < NTTYS; i++)
|
for (int i = 0; i < NTTYS; i++)
|
||||||
{
|
|
||||||
if (!ttys[i].exists ())
|
if (!ttys[i].exists ())
|
||||||
{
|
{
|
||||||
if (freetty < 0) /* Scanning? */
|
t = ttys + i;
|
||||||
freetty = i; /* Yes. */
|
t->init ();
|
||||||
if (!with_console) /* Do we want to attach this to a console? */
|
t->setsid (-1);
|
||||||
break; /* No. We've got one. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Is this right? We can potentially query a "nonexistent"
|
|
||||||
tty slot after falling through from the above? */
|
|
||||||
if (with_console && ttys[i].gethwnd () == console)
|
|
||||||
{
|
|
||||||
termios_printf ("console %x already associated with tty%d",
|
|
||||||
console, i);
|
|
||||||
/* Is the master alive? */
|
|
||||||
hmaster = OpenProcess (PROCESS_DUP_HANDLE, FALSE, ttys[i].master_pid);
|
|
||||||
if (hmaster)
|
|
||||||
{
|
|
||||||
CloseHandle (hmaster);
|
|
||||||
freetty = i;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* Master is dead */
|
|
||||||
freetty = i;
|
freetty = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* There is no tty allocated to console; allocate the first free found */
|
|
||||||
if (freetty == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
tty *t;
|
|
||||||
t = ttys + freetty;
|
|
||||||
t->init ();
|
|
||||||
t->setsid (-1);
|
|
||||||
t->sethwnd (console);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (freetty < 0)
|
if (freetty < 0)
|
||||||
system_printf ("No tty allocated");
|
system_printf ("No tty allocated");
|
||||||
else if (!with_console)
|
else
|
||||||
{
|
{
|
||||||
termios_printf ("tty%d allocated", freetty);
|
termios_printf ("tty%d allocated", freetty);
|
||||||
here.dont_release (); /* exit with mutex still held -- caller has more work to do */
|
here.dont_release (); /* exit with mutex still held -- caller has more work to do */
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
termios_printf ("console %p associated with tty%d", console, freetty);
|
|
||||||
if (!hmaster)
|
|
||||||
tty::create_master (freetty);
|
|
||||||
}
|
|
||||||
return freetty;
|
return freetty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +216,9 @@ tty::init ()
|
||||||
output_stopped = 0;
|
output_stopped = 0;
|
||||||
setsid (0);
|
setsid (0);
|
||||||
pgid = 0;
|
pgid = 0;
|
||||||
hwnd = NULL;
|
was_opened = false;
|
||||||
was_opened = 0;
|
|
||||||
master_pid = 0;
|
master_pid = 0;
|
||||||
|
is_console = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
|
|
|
@ -19,9 +19,6 @@ details. */
|
||||||
|
|
||||||
/* Input/Output/ioctl events */
|
/* Input/Output/ioctl events */
|
||||||
|
|
||||||
#define OUTPUT_DONE_EVENT "cygtty.output.done"
|
|
||||||
#define IOCTL_REQUEST_EVENT "cygtty.ioctl.request"
|
|
||||||
#define IOCTL_DONE_EVENT "cygtty.ioctl.done"
|
|
||||||
#define RESTART_OUTPUT_EVENT "cygtty.output.restart"
|
#define RESTART_OUTPUT_EVENT "cygtty.output.restart"
|
||||||
#define INPUT_AVAILABLE_EVENT "cygtty.input.avail"
|
#define INPUT_AVAILABLE_EVENT "cygtty.input.avail"
|
||||||
#define OUTPUT_MUTEX "cygtty.output.mutex"
|
#define OUTPUT_MUTEX "cygtty.output.mutex"
|
||||||
|
@ -50,7 +47,7 @@ public:
|
||||||
int output_stopped;
|
int output_stopped;
|
||||||
fh_devices ntty;
|
fh_devices ntty;
|
||||||
DWORD last_ctrl_c; /* tick count of last ctrl-c */
|
DWORD last_ctrl_c; /* tick count of last ctrl-c */
|
||||||
HWND hwnd; /* Console window handle tty belongs to */
|
bool is_console;
|
||||||
|
|
||||||
IMPLEMENT_STATUS_FLAG (bool, initialized)
|
IMPLEMENT_STATUS_FLAG (bool, initialized)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, rstcons)
|
IMPLEMENT_STATUS_FLAG (bool, rstcons)
|
||||||
|
@ -82,8 +79,6 @@ public:
|
||||||
void setsid (pid_t tsid) {sid = tsid;}
|
void setsid (pid_t tsid) {sid = tsid;}
|
||||||
void kill_pgrp (int);
|
void kill_pgrp (int);
|
||||||
int is_orphaned_process_group (int);
|
int is_orphaned_process_group (int);
|
||||||
HWND gethwnd () const {return hwnd;}
|
|
||||||
void sethwnd (HWND wnd) {hwnd = wnd;}
|
|
||||||
const char *ttyname () __attribute ((regparm (1)));
|
const char *ttyname () __attribute ((regparm (1)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,9 +120,8 @@ class tty_list
|
||||||
|
|
||||||
public:
|
public:
|
||||||
tty * operator [](int n) {return ttys + device::minor (n);}
|
tty * operator [](int n) {return ttys + device::minor (n);}
|
||||||
int allocate (bool); /* true if allocate a tty, pty otherwise */
|
int allocate (); /* allocate a pty */
|
||||||
int connect (int);
|
int connect (int);
|
||||||
void terminate ();
|
|
||||||
void init ();
|
void init ();
|
||||||
tty_min *get_cttyp ();
|
tty_min *get_cttyp ();
|
||||||
int __stdcall attach (int n) __attribute__ ((regparm (2)));
|
int __stdcall attach (int n) __attribute__ ((regparm (2)));
|
||||||
|
|
Loading…
Reference in New Issue