* cygerrno.h (__set_errno): Modify debugging output to make searching strace
logs easier. Throughout, change /dev/tty* to /dev/pty*. Throughout, add flags argument to fhandler_*::dup methods. * devices.in: Rename (temporarily?) /dev/ttyN to /dev/ptyN. Add /dev/ptymN devices for pty masters. * devices.cc: Regenerate. * devices.h (MAX_CONSOLES): Set to max number supported by devices.in. (fh_devices::FH_PTMX): Rename from FH_PTYM. (device::operator int): Return by reference. * dtable.cc (fh_alloc): Take pc as an argument rather than just the device. This makes debugging easier since more information is available. Actually implement handling for already-allocated pty master devices. Make different decisions when generating fhandler for not-opened devices. Add kludge to deal with opening /dev/tty. (cnew_no_ctor): New macro. (build_fh_pc): Make debugging output more verbose. Use new clone() fhandler interface to duplicate archetypes. Reset last term opened. (dtable::dup_worker): Use Use new clone() fhandler interface to duplicate archetypes. Pass flags to child dup handler. (dtable::dup3): Set O_NOCTTY flag if newfd is not stdin/stdout/stderr. * fhandler.cc (fhandler_base::reset): Rename from operator =() and reduce functionality and sense of copy direction. (fhandler_base::open_with_arch): Use published interface to query io_handle(). Use new copyto() fhandler method to copy from/to found archetype. * fhandler.h: Throughout, delete size(), add copyout, clone, and fhandler_* (void *) methods. (fhandler_base::reset): Rename from operator =(). (fhandler_termios::is_dev_tty): Delete. (fhandler_termios): change "protected" region to "private". (fhandler_termios::is_dev_tty): Delete. (fhandler_termios): Rearrange protected/public. (fhandler_termios::fhandler_termios): Remember last fhandler_termios "opened". (fhandler_termios::~fhandler_termios): Forget last fhandler_termios opened. (ioctl): Rename from ioctl_termios. Take a void * argument. Reflect argument change in pinfo::set_ctty. (fhandler_console::dup): Declare new function. Set ctty here if appropriate. (fhandler_pty_master::from_master): Privatize. (fhandler_pty_master::to_master): Ditto. (fhandler_pty_master::dwProcessId): Ditto. (fhandler_pty_master::fhandler_pty_master): Add an `int' argument. (fhandler_pty_master::open_setup): Declare new function. (fhandler_pty_master::~fhandler_pty_master): Declare new method. (fhandler_nodevice): Remove commented out function declaration. * fhandler_console.cc: Use get_ttyp() instead of tc() throughout. (fhandler_console::dup): Define new function to set controlling ctty on dup, as appropriate. (fhandler_console::ioctl): Reflect ioctl_termios name change. (fhandler_console::setup): Rename from get_tty_stuff. (fhandler_console::open_setup): Reflect argument change in pinfo::set_ctty. (fhandler_console::fhandler_console): Set _tc here. * fhandler_termios.cc (handler_termios::ioctl): Rename. Take a void * arg like other ioctl functions. * fhandler_tty.cc (fhandler_pty_slave::dup): Call myself->set_ctty to potentially reset the controlling terminal. (fhandler_pty_slave::ioctl): Reflect name/arg change for ioctl_termios. (fhandler_pty_slave::fhandler_pty_slave): Take a "unit" argument. Call setup() here so that we will know the unit number of this fhandler as soon as possible. Set the unit as appropriate. (handler_pty_master::open): Move most stuff to constructor and open_setup. (handler_pty_slave::open_setup): Reflect argument change in pinfo::set_ctty. (handler_pty_master::open_setup): Define new function. (fhandler_pty_master::cleanup): Clear handles as a flag that the destructor does not have to do "close" operations. (fhandler_pty_master::close): Ditto. (fhandler_pty_master::~fhandler_pty_master): Define new method. (fhandler_pty_master::ioctl): Reflect name/arg change for ioctl_termios. (fhandler_pty_master::setup): Allocate tty here. Rely on handles being returned from allocated test rather than opening them here. Avoid setting _need_nl here since it is already zeroed in the constructor. Set up device information with DEV_TTYM_MAJOR. * path.h (path_conv &operator =): Take a const argument. (path_conv::dup): Ditto. (pathconv_arg::PC_OPEN): New enum. (pathconv_arg::PC_CTTY): Ditto. (path_types::PATH_CTTY): Ditto. (path_types::PATH_OPEN): Ditto. (path_conv::isopen): New method. (path_conv::isctty_capable): Ditto. * path.cc (path_conv::check): Set PATH_OPEN and PATH_CTTY as appropriate. * pipe.cc (fhandler_pipe::open): Use copyto to copy pipe handle. * syscall.cc (open): Reinstate fd > 2 check to disallow resetting ctty on non-std* handles. * tty.cc (tty_list::allocate): Pass out handles for allocated tty. use `not_allocated' to find unallocated ttys. Avoid keeping the lock since the allocation of the tty should be sufficient to prevent multiple access. (tty::not_allocated): Clarify comment. Rename. Return handles when an unused tty is found. Simply test for existing tty. (tty::exists): Rewrite to use `not_allocated'. * tty.h (NTTYS): Reset down to actual number supported by devices.in. (tty::not_allocated): Declare new function. (tty_list::allocate): Pass out read/write tty handles. Zero them when not found. * fhandler_proc.cc: Reflect name change from FH_PTYM -> FH_PTMX. * pinfo.h (pinfo::set_ctty): Reduce/reorder arguments passed in. * pinfo.cc (pinfo::set_ctty): Ditto. Just use tc() built into the passed-in fhandler_termios pointer. Return true if ctty is assigned. * syscalls.cc (open): Call build_fh_pc with PC_OPEN flag. Set PC_CTTY if appropriate. (stat_worker): Remove is_dev_tty () stuff.
This commit is contained in:
parent
a9cc13a8e0
commit
23771fa1f7
|
@ -1,3 +1,117 @@
|
|||
2011-10-15 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||
|
||||
* cygerrno.h (__set_errno): Modify debugging output to make searching
|
||||
strace logs easier.
|
||||
|
||||
Throughout, change /dev/tty* to /dev/pty*.
|
||||
Throughout, add flags argument to fhandler_*::dup methods.
|
||||
* devices.in: Rename (temporarily?) /dev/ttyN to /dev/ptyN. Add
|
||||
/dev/ptymN devices for pty masters.
|
||||
* devices.cc: Regenerate.
|
||||
* devices.h (MAX_CONSOLES): Set to max number supported by devices.in.
|
||||
(fh_devices::FH_PTMX): Rename from FH_PTYM.
|
||||
(device::operator int): Return by reference.
|
||||
* dtable.cc (fh_alloc): Take pc as an argument rather than just the
|
||||
device. This makes debugging easier since more information is
|
||||
available. Actually implement handling for already-allocated pty
|
||||
master devices. Make different decisions when generating fhandler for
|
||||
not-opened devices. Add kludge to deal with opening /dev/tty.
|
||||
(cnew_no_ctor): New macro.
|
||||
(build_fh_pc): Make debugging output more verbose. Use new clone()
|
||||
fhandler interface to duplicate archetypes. Reset last term opened.
|
||||
(dtable::dup_worker): Use Use new clone() fhandler interface to
|
||||
duplicate archetypes. Pass flags to child dup handler.
|
||||
(dtable::dup3): Set O_NOCTTY flag if newfd is not stdin/stdout/stderr.
|
||||
* fhandler.cc (fhandler_base::reset): Rename from operator =() and
|
||||
reduce functionality and sense of copy direction.
|
||||
(fhandler_base::open_with_arch): Use published interface to query
|
||||
io_handle(). Use new copyto() fhandler method to copy from/to found
|
||||
archetype.
|
||||
* fhandler.h: Throughout, delete size(), add copyout, clone, and
|
||||
fhandler_* (void *) methods.
|
||||
(fhandler_base::reset): Rename from operator =().
|
||||
(fhandler_termios::is_dev_tty): Delete.
|
||||
(fhandler_termios): change "protected" region to "private".
|
||||
(fhandler_termios::is_dev_tty): Delete.
|
||||
(fhandler_termios): Rearrange protected/public.
|
||||
(fhandler_termios::fhandler_termios): Remember last fhandler_termios
|
||||
"opened".
|
||||
(fhandler_termios::~fhandler_termios): Forget last fhandler_termios
|
||||
opened.
|
||||
(ioctl): Rename from ioctl_termios. Take a void * argument. Reflect
|
||||
argument change in pinfo::set_ctty.
|
||||
(fhandler_console::dup): Declare new function. Set ctty here if
|
||||
appropriate.
|
||||
(fhandler_pty_master::from_master): Privatize.
|
||||
(fhandler_pty_master::to_master): Ditto.
|
||||
(fhandler_pty_master::dwProcessId): Ditto.
|
||||
(fhandler_pty_master::fhandler_pty_master): Add an `int' argument.
|
||||
(fhandler_pty_master::open_setup): Declare new function.
|
||||
(fhandler_pty_master::~fhandler_pty_master): Declare new method.
|
||||
(fhandler_nodevice): Remove commented out function declaration.
|
||||
* fhandler_console.cc: Use get_ttyp() instead of tc() throughout.
|
||||
(fhandler_console::dup): Define new function to set controlling ctty on
|
||||
dup, as appropriate.
|
||||
(fhandler_console::ioctl): Reflect ioctl_termios name change.
|
||||
(fhandler_console::setup): Rename from get_tty_stuff.
|
||||
(fhandler_console::open_setup): Reflect argument change in
|
||||
pinfo::set_ctty.
|
||||
(fhandler_console::fhandler_console): Set _tc here.
|
||||
* fhandler_termios.cc (handler_termios::ioctl): Rename. Take a void *
|
||||
arg like other ioctl functions.
|
||||
* fhandler_tty.cc (fhandler_pty_slave::dup): Call myself->set_ctty to
|
||||
potentially reset the controlling terminal.
|
||||
(fhandler_pty_slave::ioctl): Reflect name/arg change for ioctl_termios.
|
||||
(fhandler_pty_slave::fhandler_pty_slave): Take a "unit" argument. Call
|
||||
setup() here so that we will know the unit number of this fhandler as
|
||||
soon as possible. Set the unit as appropriate.
|
||||
(handler_pty_master::open): Move most stuff to constructor and
|
||||
open_setup.
|
||||
(handler_pty_slave::open_setup): Reflect argument change in
|
||||
pinfo::set_ctty.
|
||||
(handler_pty_master::open_setup): Define new function.
|
||||
(fhandler_pty_master::cleanup): Clear handles as a flag that the
|
||||
destructor does not have to do "close" operations.
|
||||
(fhandler_pty_master::close): Ditto.
|
||||
(fhandler_pty_master::~fhandler_pty_master): Define new method.
|
||||
(fhandler_pty_master::ioctl): Reflect name/arg change for
|
||||
ioctl_termios.
|
||||
(fhandler_pty_master::setup): Allocate tty here. Rely on handles being
|
||||
returned from allocated test rather than opening them here. Avoid
|
||||
setting _need_nl here since it is already zeroed in the constructor.
|
||||
Set up device information with DEV_TTYM_MAJOR.
|
||||
* path.h (path_conv &operator =): Take a const argument.
|
||||
(path_conv::dup): Ditto.
|
||||
(pathconv_arg::PC_OPEN): New enum.
|
||||
(pathconv_arg::PC_CTTY): Ditto.
|
||||
(path_types::PATH_CTTY): Ditto.
|
||||
(path_types::PATH_OPEN): Ditto.
|
||||
(path_conv::isopen): New method.
|
||||
(path_conv::isctty_capable): Ditto.
|
||||
* path.cc (path_conv::check): Set PATH_OPEN and PATH_CTTY as
|
||||
appropriate.
|
||||
* pipe.cc (fhandler_pipe::open): Use copyto to copy pipe handle.
|
||||
* syscall.cc (open): Reinstate fd > 2 check to disallow resetting ctty
|
||||
on non-std* handles.
|
||||
* tty.cc (tty_list::allocate): Pass out handles for allocated tty. use
|
||||
`not_allocated' to find unallocated ttys. Avoid keeping the lock since
|
||||
the allocation of the tty should be sufficient to prevent multiple
|
||||
access.
|
||||
(tty::not_allocated): Clarify comment. Rename. Return handles when an
|
||||
unused tty is found. Simply test for existing tty.
|
||||
(tty::exists): Rewrite to use `not_allocated'.
|
||||
* tty.h (NTTYS): Reset down to actual number supported by devices.in.
|
||||
(tty::not_allocated): Declare new function.
|
||||
(tty_list::allocate): Pass out read/write tty handles. Zero them when
|
||||
not found.
|
||||
* fhandler_proc.cc: Reflect name change from FH_PTYM -> FH_PTMX.
|
||||
* pinfo.h (pinfo::set_ctty): Reduce/reorder arguments passed in.
|
||||
* pinfo.cc (pinfo::set_ctty): Ditto. Just use tc() built into the
|
||||
passed-in fhandler_termios pointer. Return true if ctty is assigned.
|
||||
* syscalls.cc (open): Call build_fh_pc with PC_OPEN flag. Set PC_CTTY
|
||||
if appropriate.
|
||||
(stat_worker): Remove is_dev_tty () stuff.
|
||||
|
||||
2011-10-15 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_process.cc (dos_drive_mappings::fixup_if_match): Convert
|
||||
|
@ -63,6 +177,11 @@
|
|||
(fhandler_base::tcgetsid): New function.
|
||||
* fhandler.h ((fhandler_base::tcgetsid): Declare new function.
|
||||
(fhandler_base::is_dev_tty): Ditto.
|
||||
(fhandler_termios): Rearrange protected/public.
|
||||
(fhandler_termios::fhandler_termios): Remember last fhandler_termios
|
||||
"opened".
|
||||
(fhandler_termios::~fhandler_termios): Forget last fhandler_termios
|
||||
opened.
|
||||
(fhandler_termios::opened_as_dev_tty): Declare new field.
|
||||
(fhandler_termios::is_dev_tty): Declare new function.
|
||||
(fhandler_termios::tcgetsid): Ditto.
|
||||
|
|
|
@ -25,7 +25,7 @@ int __stdcall geterrno_from_nt_status (NTSTATUS status, int deferrno = 13 /*EACC
|
|||
inline int
|
||||
__set_errno (const char *fn, int ln, int val)
|
||||
{
|
||||
debug_printf ("%s:%d val %d", fn, ln, val);
|
||||
debug_printf ("%s:%d setting errno %d", fn, ln, val);
|
||||
return errno = _impure_ptr->_errno = val;
|
||||
}
|
||||
#define set_errno(val) __set_errno (__PRETTY_FUNCTION__, __LINE__, (val))
|
||||
|
|
17091
winsup/cygwin/devices.cc
17091
winsup/cygwin/devices.cc
File diff suppressed because it is too large
Load Diff
|
@ -20,12 +20,12 @@ typedef __dev32_t _dev_t;
|
|||
#define _minor(dev) ((dev) & ((1 << (sizeof (_minor_t) * 8)) - 1))
|
||||
#define _major(dev) ((dev) >> (sizeof (_major_t) * 8))
|
||||
|
||||
#define MAX_CONSOLES 31
|
||||
#define MAX_CONSOLES 63
|
||||
enum fh_devices
|
||||
{
|
||||
FH_TTY = FHDEV (5, 0),
|
||||
FH_CONSOLE = FHDEV (5, 1),
|
||||
FH_PTYM = FHDEV (5, 2), /* /dev/ptmx */
|
||||
FH_PTMX = FHDEV (5, 2),
|
||||
FH_CONIN = FHDEV (5, 255),
|
||||
FH_CONOUT = FHDEV (5, 254),
|
||||
|
||||
|
@ -306,7 +306,7 @@ struct device
|
|||
_minor_t get_minor () const {return d.minor;}
|
||||
_minor_t get_major () const {return d.major;}
|
||||
|
||||
inline operator int () {return d.devn_int;}
|
||||
inline operator int& () {return d.devn_int;}
|
||||
inline operator fh_devices () {return d.devn_fh_devices;}
|
||||
inline operator bool () {return !!d.devn_int;}
|
||||
inline operator DWORD& () {return d.devn_dword;}
|
||||
|
|
|
@ -66,10 +66,11 @@ const device dev_error_storage =
|
|||
}
|
||||
%%
|
||||
"/dev/tty", BRACK(FH_TTY), "/dev/tty"
|
||||
"/dev/tty%(0-63)d", BRACK(FHDEV(DEV_TTYS_MAJOR, {$1})), "/dev/tty{$1}", ttys_dev
|
||||
"/dev/pty%(0-63)d", BRACK(FHDEV(DEV_TTYS_MAJOR, {$1})), "/dev/pty{$1}", ttys_dev
|
||||
"/dev/ptym%(0-63)d", BRACK(FHDEV(DEV_TTYM_MAJOR, {$1})), "/dev/ptym{$1}", ttym_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/ptmx", BRACK(FH_PTYM), "/dev/ptmx"
|
||||
"/dev/ptmx", BRACK(FH_PTMX), "/dev/ptmx"
|
||||
"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows"
|
||||
"/dev/dsp", BRACK(FH_OSS_DSP), "/dev/dsp"
|
||||
"/dev/conin", BRACK(FH_CONIN), "/dev/conin"
|
||||
|
|
|
@ -113,7 +113,7 @@ dtable::get_debugger_info ()
|
|||
extern bool jit_debug;
|
||||
if (!jit_debug && being_debugged ())
|
||||
{
|
||||
char std[3][sizeof ("/dev/ttyNNNN")];
|
||||
char std[3][sizeof ("/dev/ptyNNNN")];
|
||||
std[0][0] = std[1][0] = std [2][0] = '\0';
|
||||
char buf[sizeof ("cYgstd %x") + 32];
|
||||
sprintf (buf, "cYgstd %x %x %x", (unsigned) &std, sizeof (std[0]), 3);
|
||||
|
@ -401,6 +401,12 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||
ptr ? new (ptr) name (__VA_ARGS__) : NULL; \
|
||||
})
|
||||
|
||||
#define cnew_no_ctor(name, ...) \
|
||||
({ \
|
||||
void* ptr = (void*) ccalloc (HEAP_FHANDLER, 1, sizeof (name)); \
|
||||
ptr ? new (ptr) name (ptr) : NULL; \
|
||||
})
|
||||
|
||||
fhandler_base *
|
||||
build_fh_name (const char *name, unsigned opt, suffix_info *si)
|
||||
{
|
||||
|
@ -429,15 +435,20 @@ build_fh_dev (const device& dev, const char *unix_name)
|
|||
}
|
||||
|
||||
#define fh_unset ((fhandler_base *) 1)
|
||||
|
||||
static fhandler_base *
|
||||
fh_alloc (device dev)
|
||||
fh_alloc (path_conv& pc)
|
||||
{
|
||||
fhandler_base *fh = fh_unset;
|
||||
fhandler_base *fhraw = NULL;
|
||||
|
||||
switch (dev.get_major ())
|
||||
switch (pc.dev.get_major ())
|
||||
{
|
||||
case DEV_TTYS_MAJOR:
|
||||
fh = cnew (fhandler_pty_slave, dev.get_minor ());
|
||||
fh = cnew (fhandler_pty_slave, pc.dev.get_minor ());
|
||||
break;
|
||||
case DEV_TTYM_MAJOR:
|
||||
fh = cnew (fhandler_pty_master, pc.dev.get_minor ());
|
||||
break;
|
||||
case DEV_CYGDRIVE_MAJOR:
|
||||
fh = cnew (fhandler_cygdrive);
|
||||
|
@ -461,18 +472,21 @@ fh_alloc (device dev)
|
|||
fh = cnew (fhandler_serial);
|
||||
break;
|
||||
case DEV_CONS_MAJOR:
|
||||
fh = cnew (fhandler_console, dev);
|
||||
fh = cnew (fhandler_console, pc.dev);
|
||||
break;
|
||||
default:
|
||||
switch ((int) dev)
|
||||
switch ((int) pc.dev)
|
||||
{
|
||||
case FH_CONSOLE:
|
||||
case FH_CONIN:
|
||||
case FH_CONOUT:
|
||||
fh = cnew (fhandler_console, dev);
|
||||
fh = cnew (fhandler_console, pc.dev);
|
||||
break;
|
||||
case FH_PTYM:
|
||||
fh = cnew (fhandler_pty_master);
|
||||
case FH_PTMX:
|
||||
if (pc.isopen ())
|
||||
fh = cnew (fhandler_pty_master, -1);
|
||||
else
|
||||
fhraw = cnew_no_ctor (fhandler_pty_master, -1);
|
||||
break;
|
||||
case FH_WINDOWS:
|
||||
fh = cnew (fhandler_windows);
|
||||
|
@ -540,40 +554,52 @@ fh_alloc (device dev)
|
|||
fh = cnew (fhandler_netdrive);
|
||||
break;
|
||||
case FH_TTY:
|
||||
{
|
||||
if (myself->ctty > 0)
|
||||
{
|
||||
if (iscons_dev (myself->ctty))
|
||||
fh = cnew (fhandler_console, dev);
|
||||
else
|
||||
fh = cnew (fhandler_pty_slave, myself->ctty);
|
||||
}
|
||||
((fhandler_termios *) fh)->is_dev_tty (true);
|
||||
break;
|
||||
}
|
||||
if (!pc.isopen ())
|
||||
fhraw = cnew_no_ctor (fhandler_console, -1);
|
||||
else if (myself->ctty <= 0
|
||||
&& !myself->set_ctty (fhandler_termios::last, 0))
|
||||
/* no tty assigned */;
|
||||
else if (iscons_dev (myself->ctty))
|
||||
fh = cnew (fhandler_console, pc.dev);
|
||||
else
|
||||
fh = cnew (fhandler_pty_slave, myself->ctty);
|
||||
break;
|
||||
case FH_KMSG:
|
||||
fh = cnew (fhandler_mailslot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If `fhraw' is set that means that this fhandler is just a dummy
|
||||
set up for stat(). Mock it up for use by stat without actually
|
||||
trying to do any real initialization. */
|
||||
if (fhraw)
|
||||
{
|
||||
fh = fhraw;
|
||||
fh->set_name (pc);
|
||||
if (fh->use_archetype ())
|
||||
fh->archetype = fh;
|
||||
}
|
||||
if (fh == fh_unset)
|
||||
fh = cnew (fhandler_nodevice);
|
||||
else if (fh->dev () == FH_ERROR)
|
||||
{
|
||||
delete fh;
|
||||
fh = NULL;
|
||||
}
|
||||
return fh;
|
||||
}
|
||||
|
||||
fhandler_base *
|
||||
build_fh_pc (path_conv& pc, bool set_name)
|
||||
{
|
||||
fhandler_base *fh = fh_alloc (pc.dev);
|
||||
fhandler_base *fh = fh_alloc (pc);
|
||||
|
||||
if (!fh)
|
||||
{
|
||||
set_errno (EMFILE);
|
||||
set_errno (ENXIO);
|
||||
goto out;
|
||||
}
|
||||
else if (fh->dev () == FH_ERROR)
|
||||
goto out;
|
||||
else if (fh->dev () != FH_NADA)
|
||||
fh->set_name (fh->dev ().name);
|
||||
else if (set_name)
|
||||
|
@ -582,18 +608,25 @@ build_fh_pc (path_conv& pc, bool set_name)
|
|||
if (!fh->use_archetype ())
|
||||
/* doesn't use archetypes */;
|
||||
else if ((fh->archetype = cygheap->fdtab.find_archetype (fh->dev ())))
|
||||
debug_printf ("found an archetype for %s(%d/%d)", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ());
|
||||
debug_printf ("found an archetype for %s(%d/%d) io_handle %p", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor (),
|
||||
fh->archetype->get_io_handle ());
|
||||
else
|
||||
{
|
||||
debug_printf ("creating an archetype for %s(%d/%d)", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ());
|
||||
fh->archetype = fh_alloc (fh->pc.dev);
|
||||
*fh->archetype = *fh;
|
||||
fh->archetype = fh->clone ();
|
||||
debug_printf ("created an archetype (%p) for %s(%d/%d)", fh->archetype, fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ());
|
||||
fh->archetype->archetype = NULL;
|
||||
*cygheap->fdtab.add_archetype () = fh->archetype;
|
||||
}
|
||||
|
||||
/* The fhandler_termios constructor keeps track of the last tty-like thing
|
||||
opened but we're only interested in this if we don't have a controlling
|
||||
terminal since we could potentially want to open it if /dev/tty is
|
||||
referenced. */
|
||||
if (myself->ctty > 0 || !fh->is_tty () || !pc.isctty_capable ())
|
||||
fhandler_termios::last = NULL;
|
||||
|
||||
out:
|
||||
debug_printf ("fh %p", fh);
|
||||
debug_printf ("fh %p, dev %p", fh, (DWORD) fh->dev ());
|
||||
return fh;
|
||||
}
|
||||
|
||||
|
@ -603,16 +636,16 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
|
|||
/* Don't call set_name in build_fh_pc. It will be called in
|
||||
fhandler_base::operator= below. Calling it twice will result
|
||||
in double allocation. */
|
||||
fhandler_base *newfh = build_fh_pc (oldfh->pc, false);
|
||||
fhandler_base *newfh = oldfh->clone ();
|
||||
if (!newfh)
|
||||
debug_printf ("build_fh_pc failed");
|
||||
else
|
||||
{
|
||||
*newfh = *oldfh;
|
||||
if (!oldfh->archetype)
|
||||
newfh->set_io_handle (NULL);
|
||||
|
||||
newfh->pc.reset_conv_handle ();
|
||||
if (oldfh->dup (newfh))
|
||||
if (oldfh->dup (newfh, flags))
|
||||
{
|
||||
delete newfh;
|
||||
newfh = NULL;
|
||||
|
@ -625,6 +658,14 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
|
|||
/* The O_CLOEXEC flag enforces close-on-exec behaviour. */
|
||||
newfh->set_close_on_exec (!!(flags & O_CLOEXEC));
|
||||
debug_printf ("duped '%s' old %p, new %p", oldfh->get_name (), oldfh->get_io_handle (), newfh->get_io_handle ());
|
||||
#ifdef DEBUGGING
|
||||
debug_printf ("duped output_handles old %p, new %p",
|
||||
oldfh->get_output_handle (),
|
||||
newfh->get_output_handle ());
|
||||
debug_printf ("duped output_handles archetype old %p, archetype new %p",
|
||||
oldfh->archetype->get_output_handle (),
|
||||
newfh->archetype->get_output_handle ());
|
||||
#endif /*DEBUGGING*/
|
||||
}
|
||||
}
|
||||
return newfh;
|
||||
|
@ -659,6 +700,13 @@ dtable::dup3 (int oldfd, int newfd, int flags)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* This is a temporary kludge until all utilities can catch up with
|
||||
a change in behavior that implements linux functionality: opening
|
||||
a tty should not automatically cause it to become the controlling
|
||||
tty for the process. */
|
||||
if (newfd > 2)
|
||||
flags |= O_NOCTTY;
|
||||
|
||||
if ((newfh = dup_worker (fds[oldfd], flags)) == NULL)
|
||||
{
|
||||
res = -1;
|
||||
|
@ -817,7 +865,7 @@ static void
|
|||
decode_tty (char *buf, WCHAR *w32)
|
||||
{
|
||||
int ttyn = wcstol (w32, NULL, 10);
|
||||
__small_sprintf (buf, "/dev/tty%d", ttyn);
|
||||
__small_sprintf (buf, "/dev/pty%d", ttyn);
|
||||
}
|
||||
|
||||
/* Try to derive posix filename from given handle. Return true if
|
||||
|
|
|
@ -37,17 +37,15 @@ static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
|||
|
||||
struct __cygwin_perfile *perfile_table;
|
||||
|
||||
inline fhandler_base&
|
||||
fhandler_base::operator =(fhandler_base& x)
|
||||
void
|
||||
fhandler_base::reset (const fhandler_base *from)
|
||||
{
|
||||
memcpy (this, &x, size ());
|
||||
pc = x.pc;
|
||||
pc = from->pc;
|
||||
rabuf = NULL;
|
||||
ralen = 0;
|
||||
raixget = 0;
|
||||
raixput = 0;
|
||||
rabuflen = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -462,17 +460,17 @@ fhandler_base::open_with_arch (int flags, mode_t mode)
|
|||
}
|
||||
else if (archetype)
|
||||
{
|
||||
if (!archetype->io_handle)
|
||||
if (!archetype->get_io_handle ())
|
||||
{
|
||||
usecount = 0;
|
||||
*archetype = *this;
|
||||
copyto (archetype);
|
||||
archetype_usecount (1);
|
||||
archetype->archetype = NULL;
|
||||
usecount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fhandler_base *arch = archetype;
|
||||
*this = *archetype;
|
||||
archetype->copyto (this);
|
||||
archetype = arch;
|
||||
archetype_usecount (1);
|
||||
usecount = 0;
|
||||
|
@ -1259,7 +1257,7 @@ fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_base::dup (fhandler_base *child)
|
||||
fhandler_base::dup (fhandler_base *child, int)
|
||||
{
|
||||
debug_printf ("in fhandler_base dup");
|
||||
|
||||
|
@ -1283,9 +1281,9 @@ fhandler_base::dup (fhandler_base *child)
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_base_overlapped::dup (fhandler_base *child)
|
||||
fhandler_base_overlapped::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
int res = fhandler_base::dup (child) ||
|
||||
int res = fhandler_base::dup (child, flags) ||
|
||||
((fhandler_base_overlapped *) child)->setup_overlapped ();
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,7 @@ class fhandler_base
|
|||
|
||||
path_conv pc;
|
||||
|
||||
void reset (const fhandler_base *);
|
||||
virtual bool use_archetype () const {return false;}
|
||||
virtual void set_name (path_conv &pc);
|
||||
virtual void set_name (const char *s)
|
||||
|
@ -194,9 +195,6 @@ class fhandler_base
|
|||
int pc_binmode () const {return pc.binmode ();}
|
||||
device& dev () {return pc.dev;}
|
||||
operator DWORD& () {return (DWORD&) pc;}
|
||||
virtual size_t size () const {return sizeof (*this);}
|
||||
|
||||
virtual fhandler_base& operator =(fhandler_base &x);
|
||||
fhandler_base ();
|
||||
virtual ~fhandler_base ();
|
||||
|
||||
|
@ -354,7 +352,7 @@ public:
|
|||
virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
|
||||
virtual _off64_t lseek (_off64_t offset, int whence);
|
||||
virtual int lock (int, struct __flock64 *);
|
||||
virtual int dup (fhandler_base *child);
|
||||
virtual int dup (fhandler_base *child, int flags);
|
||||
virtual int fpathconf (int);
|
||||
|
||||
virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
|
||||
|
@ -427,7 +425,22 @@ public:
|
|||
bool device_access_denied (int) __attribute__ ((regparm (2)));
|
||||
int fhaccess (int flags, bool) __attribute__ ((regparm (3)));
|
||||
virtual bool __stdcall has_ongoing_io () __attribute__ ((regparm (1))) {return false;}
|
||||
virtual bool is_dev_tty () const { return false; }
|
||||
|
||||
fhandler_base (void *) {}
|
||||
|
||||
virtual void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_base *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
virtual fhandler_base *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_base));
|
||||
fhandler_base *fh = new (ptr) fhandler_base (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
struct wsa_event
|
||||
|
@ -552,7 +565,7 @@ class fhandler_socket: public fhandler_base
|
|||
int shutdown (int how);
|
||||
int close ();
|
||||
void hclose (HANDLE) {close ();}
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
|
||||
void set_close_on_exec (bool val);
|
||||
int fixup_before_fork_exec (DWORD);
|
||||
|
@ -578,7 +591,22 @@ class fhandler_socket: public fhandler_base
|
|||
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||
int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
|
||||
int __stdcall link (const char *) __attribute__ ((regparm (2)));
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_socket (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_socket *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_socket *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_socket));
|
||||
fhandler_socket *fh = new (ptr) fhandler_socket (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_base_overlapped: public fhandler_base
|
||||
|
@ -615,8 +643,23 @@ public:
|
|||
void fixup_after_exec ();
|
||||
|
||||
int close ();
|
||||
int dup (fhandler_base *child);
|
||||
virtual size_t size () const { return sizeof (*this);} /* probably not needed */
|
||||
int dup (fhandler_base *child, int);
|
||||
|
||||
fhandler_base_overlapped (void *) {}
|
||||
|
||||
virtual void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_base_overlapped *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
virtual fhandler_base_overlapped *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_base_overlapped));
|
||||
fhandler_base_overlapped *fh = new (ptr) fhandler_base_overlapped (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_pipe: public fhandler_base_overlapped
|
||||
|
@ -637,7 +680,7 @@ public:
|
|||
select_record *select_except (select_stuff *);
|
||||
char *get_proc_fd_name (char *buf);
|
||||
int open (int flags, mode_t mode = 0);
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
int ioctl (unsigned int cmd, void *);
|
||||
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||
int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
|
||||
|
@ -646,7 +689,22 @@ public:
|
|||
static int create (fhandler_pipe *[2], unsigned, int);
|
||||
static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL);
|
||||
friend class fhandler_fifo;
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_pipe (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_pipe *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_pipe *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_pipe));
|
||||
fhandler_pipe *fh = new (ptr) fhandler_pipe (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_fifo: public fhandler_base_overlapped
|
||||
|
@ -673,14 +731,29 @@ public:
|
|||
ssize_t __stdcall raw_write (const void *, size_t) __attribute__ ((regparm (3)));
|
||||
int open (int, mode_t);
|
||||
int close ();
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
bool isfifo () const { return true; }
|
||||
void set_close_on_exec (bool val);
|
||||
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_fifo (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_fifo *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_fifo *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_fifo));
|
||||
fhandler_fifo *fh = new (ptr) fhandler_fifo (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_mailslot : public fhandler_base_overlapped
|
||||
|
@ -693,7 +766,22 @@ class fhandler_mailslot : public fhandler_base_overlapped
|
|||
ssize_t __stdcall raw_write (const void *, size_t) __attribute__ ((regparm (3)));
|
||||
int ioctl (unsigned int cmd, void *);
|
||||
select_record *select_read (select_stuff *);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_mailslot (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_mailslot *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_mailslot *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_mailslot));
|
||||
fhandler_mailslot *fh = new (ptr) fhandler_mailslot (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_raw: public fhandler_base
|
||||
|
@ -721,12 +809,27 @@ class fhandler_dev_raw: public fhandler_base
|
|||
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
int ioctl (unsigned int cmd, void *buf);
|
||||
|
||||
void fixup_after_fork (HANDLE);
|
||||
void fixup_after_exec ();
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_raw (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_raw *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_raw *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_raw));
|
||||
fhandler_dev_raw *fh = new (ptr) fhandler_dev_raw (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
#define MAX_PARTITIONS 15
|
||||
|
@ -765,12 +868,27 @@ class fhandler_dev_floppy: public fhandler_dev_raw
|
|||
|
||||
int open (int flags, mode_t mode = 0);
|
||||
int close ();
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
|
||||
ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
|
||||
_off64_t lseek (_off64_t offset, int whence);
|
||||
int ioctl (unsigned int cmd, void *buf);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_floppy (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_floppy *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_floppy *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_floppy));
|
||||
fhandler_dev_floppy *fh = new (ptr) fhandler_dev_floppy (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_tape: public fhandler_dev_raw
|
||||
|
@ -798,11 +916,26 @@ class fhandler_dev_tape: public fhandler_dev_raw
|
|||
|
||||
virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
|
||||
virtual int dup (fhandler_base *child);
|
||||
virtual int dup (fhandler_base *child, int);
|
||||
virtual void fixup_after_fork (HANDLE parent);
|
||||
virtual void set_close_on_exec (bool val);
|
||||
virtual int ioctl (unsigned int cmd, void *buf);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_tape (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_tape *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_tape *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_tape));
|
||||
fhandler_dev_tape *fh = new (ptr) fhandler_dev_tape (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
/* Standard disk file */
|
||||
|
@ -820,7 +953,7 @@ class fhandler_disk_file: public fhandler_base
|
|||
|
||||
int open (int flags, mode_t mode);
|
||||
int close ();
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
void fixup_after_fork (HANDLE parent);
|
||||
int lock (int, struct __flock64 *);
|
||||
bool isdevice () const { return false; }
|
||||
|
@ -852,7 +985,22 @@ class fhandler_disk_file: public fhandler_base
|
|||
|
||||
ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
|
||||
ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_disk_file (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_disk_file *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_disk_file *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_disk_file));
|
||||
fhandler_disk_file *fh = new (ptr) fhandler_disk_file (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_cygdrive: public fhandler_disk_file
|
||||
|
@ -874,7 +1022,22 @@ class fhandler_cygdrive: public fhandler_disk_file
|
|||
void rewinddir (DIR *);
|
||||
int closedir (DIR *);
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_cygdrive (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_cygdrive *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_cygdrive *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_cygdrive));
|
||||
fhandler_cygdrive *fh = new (ptr) fhandler_cygdrive (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_serial: public fhandler_base
|
||||
|
@ -898,7 +1061,7 @@ class fhandler_serial: public fhandler_base
|
|||
int close ();
|
||||
int init (HANDLE h, DWORD a, mode_t flags);
|
||||
void overlapped_setup ();
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
|
||||
ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
|
||||
int tcsendbreak (int);
|
||||
|
@ -922,7 +1085,22 @@ class fhandler_serial: public fhandler_base
|
|||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_serial (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_serial *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_serial *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_serial));
|
||||
fhandler_serial *fh = new (ptr) fhandler_serial (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
#define acquire_output_mutex(ms) \
|
||||
|
@ -935,29 +1113,33 @@ class tty;
|
|||
class tty_min;
|
||||
class fhandler_termios: public fhandler_base
|
||||
{
|
||||
protected:
|
||||
bool opened_as_dev_tty;
|
||||
private:
|
||||
HANDLE output_handle;
|
||||
protected:
|
||||
virtual void doecho (const void *, DWORD) {};
|
||||
virtual int accept_input () {return 1;};
|
||||
int ioctl_termios (int, int);
|
||||
public:
|
||||
bool is_dev_tty () const { return opened_as_dev_tty; }
|
||||
bool is_dev_tty (bool val) { return opened_as_dev_tty = val; }
|
||||
int ioctl (int, void *);
|
||||
tty_min *_tc;
|
||||
virtual tty_min *tc () const {return _tc; }
|
||||
tty *get_ttyp () {return (tty *) tc ();}
|
||||
public:
|
||||
static fhandler_termios *last;
|
||||
tty_min*& tc () {return _tc;}
|
||||
fhandler_termios () :
|
||||
fhandler_base ()
|
||||
{
|
||||
opened_as_dev_tty = false;
|
||||
need_fork_fixup (true);
|
||||
last = this;
|
||||
}
|
||||
~fhandler_termios ()
|
||||
{
|
||||
if (this == last)
|
||||
last = NULL;
|
||||
}
|
||||
HANDLE& get_output_handle () { return output_handle; }
|
||||
line_edit_status line_edit (const char *rptr, int nread, termios&);
|
||||
void set_output_handle (HANDLE h) { output_handle = h; }
|
||||
void tcinit (bool force);
|
||||
bool is_tty () const { return true; }
|
||||
tty *get_ttyp () { return (tty *) tc (); }
|
||||
void sigflush ();
|
||||
int tcgetpgrp ();
|
||||
int tcsetpgrp (int pid);
|
||||
|
@ -967,7 +1149,22 @@ class fhandler_termios: public fhandler_base
|
|||
void echo_erase (int force = 0);
|
||||
virtual _off64_t lseek (_off64_t, int);
|
||||
int tcgetsid ();
|
||||
virtual size_t size () const { return sizeof (*this);} /* probably not needed */
|
||||
|
||||
fhandler_termios (void *) {}
|
||||
|
||||
virtual void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_termios *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
virtual fhandler_termios *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_termios));
|
||||
fhandler_termios *fh = new (ptr) fhandler_termios (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
enum ansi_intensity
|
||||
|
@ -1105,7 +1302,6 @@ private:
|
|||
static bool create_invisible_console (HWINSTA);
|
||||
static bool create_invisible_console_workaround ();
|
||||
static console_state *open_shared_console (HWND, HANDLE&, bool&);
|
||||
tty_min *tc () const {return &(shared_console_info->tty_min_state);}
|
||||
|
||||
public:
|
||||
static pid_t tc_getpgid () {return shared_console_info->tty_min_state.getpgid ();}
|
||||
|
@ -1122,6 +1318,7 @@ private:
|
|||
|
||||
int open (int flags, mode_t mode);
|
||||
void open_setup (int flags);
|
||||
int dup (fhandler_base *, int);
|
||||
|
||||
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
|
||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||
|
@ -1146,11 +1343,26 @@ private:
|
|||
void set_close_on_exec (bool val);
|
||||
void set_input_state ();
|
||||
void send_winch_maybe ();
|
||||
void get_tty_stuff ();
|
||||
void setup ();
|
||||
bool set_unit ();
|
||||
static bool need_invisible ();
|
||||
static bool has_a () {return !invisible_console;}
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_console (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_console *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_console *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_console));
|
||||
fhandler_console *fh = new (ptr) fhandler_console (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
friend tty_min * tty_list::get_cttyp ();
|
||||
};
|
||||
|
||||
|
@ -1177,7 +1389,22 @@ class fhandler_pty_common: public fhandler_termios
|
|||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
virtual size_t size () const { return sizeof (*this);} /* probably not needed */
|
||||
|
||||
fhandler_pty_common (void *) {}
|
||||
|
||||
virtual void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_pty_common *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
virtual fhandler_pty_common *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_pty_common));
|
||||
fhandler_pty_common *fh = new (ptr) fhandler_pty_common (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_pty_slave: public fhandler_pty_common
|
||||
|
@ -1205,7 +1432,7 @@ class fhandler_pty_slave: public fhandler_pty_common
|
|||
int ioctl (unsigned int cmd, void *);
|
||||
int close ();
|
||||
void cleanup ();
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
void fixup_after_fork (HANDLE parent);
|
||||
void fixup_after_exec ();
|
||||
|
||||
|
@ -1215,7 +1442,22 @@ class fhandler_pty_slave: public fhandler_pty_common
|
|||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_pty_slave (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_pty_slave *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_pty_slave *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_pty_slave));
|
||||
fhandler_pty_slave *fh = new (ptr) fhandler_pty_slave (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_pty_master: public fhandler_pty_common
|
||||
|
@ -1223,20 +1465,21 @@ class fhandler_pty_master: public fhandler_pty_common
|
|||
int pktmode; // non-zero if pty in a packet mode.
|
||||
HANDLE master_ctl; // Control socket for handle duplication
|
||||
cygthread *master_thread; // Master control thread
|
||||
HANDLE from_master, to_master;
|
||||
DWORD dwProcessId; // Owner of master handles
|
||||
|
||||
public:
|
||||
int need_nl; // Next read should start with \n
|
||||
DWORD dwProcessId; // Owner of master handles
|
||||
HANDLE from_master, to_master;
|
||||
|
||||
/* Constructor */
|
||||
fhandler_pty_master ();
|
||||
fhandler_pty_master (int);
|
||||
|
||||
DWORD pty_master_thread ();
|
||||
int process_slave_output (char *buf, size_t len, int pktmode_on);
|
||||
void doecho (const void *str, DWORD len);
|
||||
int accept_input ();
|
||||
int open (int flags, mode_t mode = 0);
|
||||
void open_setup (int flags);
|
||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
|
||||
int close ();
|
||||
|
@ -1251,11 +1494,27 @@ public:
|
|||
|
||||
bool hit_eof ();
|
||||
bool setup ();
|
||||
int dup (fhandler_base *);
|
||||
int dup (fhandler_base *, int);
|
||||
void fixup_after_fork (HANDLE parent);
|
||||
void fixup_after_exec ();
|
||||
int tcgetpgrp ();
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_pty_master (void *) {}
|
||||
~fhandler_pty_master ();
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_pty_master *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_pty_master *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_pty_master));
|
||||
fhandler_pty_master *fh = new (ptr) fhandler_pty_master (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_null: public fhandler_base
|
||||
|
@ -1266,7 +1525,22 @@ class fhandler_dev_null: public fhandler_base
|
|||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_null (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_null *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_null *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_null));
|
||||
fhandler_dev_null *fh = new (ptr) fhandler_dev_null (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_zero: public fhandler_base
|
||||
|
@ -1285,7 +1559,22 @@ class fhandler_dev_zero: public fhandler_base
|
|||
virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
||||
_off64_t offset, DWORD size,
|
||||
void *address);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_zero (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_zero *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_zero *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_zero));
|
||||
fhandler_dev_zero *fh = new (ptr) fhandler_dev_zero (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_random: public fhandler_base
|
||||
|
@ -1306,8 +1595,23 @@ class fhandler_dev_random: public fhandler_base
|
|||
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
|
||||
_off64_t lseek (_off64_t offset, int whence);
|
||||
int close ();
|
||||
int dup (fhandler_base *child);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
int dup (fhandler_base *child, int);
|
||||
|
||||
fhandler_dev_random (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_random *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_random *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_random));
|
||||
fhandler_dev_random *fh = new (ptr) fhandler_dev_random (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_mem: public fhandler_base
|
||||
|
@ -1331,7 +1635,22 @@ class fhandler_dev_mem: public fhandler_base
|
|||
int msync (HANDLE h, caddr_t addr, size_t len, int flags);
|
||||
bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
|
||||
_off64_t offset, DWORD size, void *address);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_mem (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_mem *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_mem *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_mem));
|
||||
fhandler_dev_mem *fh = new (ptr) fhandler_dev_mem (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_clipboard: public fhandler_base
|
||||
|
@ -1349,9 +1668,24 @@ class fhandler_dev_clipboard: public fhandler_base
|
|||
_off64_t lseek (_off64_t offset, int whence);
|
||||
int close ();
|
||||
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
void fixup_after_exec ();
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_clipboard (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_clipboard *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_clipboard *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_clipboard));
|
||||
fhandler_dev_clipboard *fh = new (ptr) fhandler_dev_clipboard (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_windows: public fhandler_base
|
||||
|
@ -1374,7 +1708,22 @@ class fhandler_windows: public fhandler_base
|
|||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_windows (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_windows *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_windows *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_windows));
|
||||
fhandler_windows *fh = new (ptr) fhandler_windows (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_dev_dsp: public fhandler_base
|
||||
|
@ -1405,7 +1754,22 @@ class fhandler_dev_dsp: public fhandler_base
|
|||
void close_audio_in ();
|
||||
void close_audio_out (bool immediately = false);
|
||||
bool use_archetype () const {return true;}
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_dev_dsp (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_dev_dsp *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_dev_dsp *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_dev_dsp));
|
||||
fhandler_dev_dsp *fh = new (ptr) fhandler_dev_dsp (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_virtual : public fhandler_base
|
||||
|
@ -1429,7 +1793,7 @@ class fhandler_virtual : public fhandler_base
|
|||
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
|
||||
_off64_t lseek (_off64_t, int);
|
||||
int dup (fhandler_base *child);
|
||||
int dup (fhandler_base *child, int);
|
||||
int open (int flags, mode_t mode = 0);
|
||||
int close ();
|
||||
int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
|
||||
|
@ -1440,7 +1804,22 @@ class fhandler_virtual : public fhandler_base
|
|||
virtual bool fill_filebuf ();
|
||||
char *get_filebuf () { return filebuf; }
|
||||
void fixup_after_exec ();
|
||||
virtual size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_virtual (void *) {}
|
||||
|
||||
virtual void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_virtual *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
virtual fhandler_virtual *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_virtual));
|
||||
fhandler_virtual *fh = new (ptr) fhandler_virtual (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_proc: public fhandler_virtual
|
||||
|
@ -1456,7 +1835,22 @@ class fhandler_proc: public fhandler_virtual
|
|||
int open (int flags, mode_t mode = 0);
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
bool fill_filebuf ();
|
||||
virtual size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_proc (void *) {}
|
||||
|
||||
virtual void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_proc *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
virtual fhandler_proc *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_proc));
|
||||
fhandler_proc *fh = new (ptr) fhandler_proc (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_procsys: public fhandler_virtual
|
||||
|
@ -1476,7 +1870,22 @@ class fhandler_procsys: public fhandler_virtual
|
|||
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
bool fill_filebuf ();
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_procsys (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_procsys *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_procsys *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_procsys));
|
||||
fhandler_procsys *fh = new (ptr) fhandler_procsys (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_procsysvipc: public fhandler_proc
|
||||
|
@ -1489,7 +1898,22 @@ class fhandler_procsysvipc: public fhandler_proc
|
|||
int open (int flags, mode_t mode = 0);
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
bool fill_filebuf ();
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_procsysvipc (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_procsysvipc *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_procsysvipc *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_procsysvipc));
|
||||
fhandler_procsysvipc *fh = new (ptr) fhandler_procsysvipc (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_netdrive: public fhandler_virtual
|
||||
|
@ -1503,7 +1927,22 @@ class fhandler_netdrive: public fhandler_virtual
|
|||
int closedir (DIR *);
|
||||
int open (int flags, mode_t mode = 0);
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_netdrive (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_netdrive *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_netdrive *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_netdrive));
|
||||
fhandler_netdrive *fh = new (ptr) fhandler_netdrive (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_registry: public fhandler_proc
|
||||
|
@ -1526,8 +1965,23 @@ class fhandler_registry: public fhandler_proc
|
|||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
bool fill_filebuf ();
|
||||
int close ();
|
||||
int dup (fhandler_base *child);
|
||||
size_t size () const { return sizeof (*this);}
|
||||
int dup (fhandler_base *child, int);
|
||||
|
||||
fhandler_registry (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_registry *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_registry *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_registry));
|
||||
fhandler_registry *fh = new (ptr) fhandler_registry (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class pinfo;
|
||||
|
@ -1543,7 +1997,22 @@ class fhandler_process: public fhandler_proc
|
|||
int open (int flags, mode_t mode = 0);
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
bool fill_filebuf ();
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_process (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_process *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_process *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_process));
|
||||
fhandler_process *fh = new (ptr) fhandler_process (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_procnet: public fhandler_proc
|
||||
|
@ -1556,14 +2025,28 @@ class fhandler_procnet: public fhandler_proc
|
|||
int open (int flags, mode_t mode = 0);
|
||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||
bool fill_filebuf ();
|
||||
size_t size () const { return sizeof (*this);}
|
||||
|
||||
fhandler_procnet (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
*reinterpret_cast<fhandler_procnet *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_procnet *clone ()
|
||||
{
|
||||
void *ptr = (void *) cmalloc (HEAP_FHANDLER, sizeof (fhandler_procnet));
|
||||
fhandler_procnet *fh = new (ptr) fhandler_procnet (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
struct fhandler_nodevice: public fhandler_base
|
||||
{
|
||||
fhandler_nodevice ();
|
||||
int open (int flags, mode_t mode = 0);
|
||||
// int __stdcall fstat (struct __stat64 *buf, path_conv *);
|
||||
};
|
||||
|
||||
#define report_tty_counts(fh, call, use_op) \
|
||||
|
|
|
@ -44,7 +44,7 @@ fhandler_dev_clipboard::fhandler_dev_clipboard ()
|
|||
*/
|
||||
|
||||
int
|
||||
fhandler_dev_clipboard::dup (fhandler_base * child)
|
||||
fhandler_dev_clipboard::dup (fhandler_base * child, int)
|
||||
{
|
||||
fhandler_dev_clipboard *fhc = (fhandler_dev_clipboard *) child;
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ fhandler_console::set_unit ()
|
|||
|
||||
/* Allocate and initialize the shared record for the current console. */
|
||||
void
|
||||
fhandler_console::get_tty_stuff ()
|
||||
fhandler_console::setup ()
|
||||
{
|
||||
if (set_unit ())
|
||||
{
|
||||
|
@ -268,7 +268,7 @@ fhandler_console::send_winch_maybe ()
|
|||
{
|
||||
dev_state.scroll_region.Top = 0;
|
||||
dev_state.scroll_region.Bottom = -1;
|
||||
tc ()->kill_pgrp (SIGWINCH);
|
||||
get_ttyp ()->kill_pgrp (SIGWINCH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +336,7 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||
DWORD timeout = is_nonblocking () ? 0 : INFINITE;
|
||||
char tmp[60];
|
||||
|
||||
termios ti = tc ()->ti;
|
||||
termios ti = get_ttyp ()->ti;
|
||||
for (;;)
|
||||
{
|
||||
int bgres;
|
||||
|
@ -684,8 +684,8 @@ sig_exit:
|
|||
void
|
||||
fhandler_console::set_input_state ()
|
||||
{
|
||||
if (tc ()->rstcons ())
|
||||
input_tcsetattr (0, &tc ()->ti);
|
||||
if (get_ttyp ()->rstcons ())
|
||||
input_tcsetattr (0, &get_ttyp ()->ti);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -759,6 +759,13 @@ fhandler_console::scroll_screen (int x1, int y1, int x2, int y2, int xn, int yn)
|
|||
clear_screen (0, sr1.Top, sr2.Right, dest.Y - 1);
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_console::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
myself->set_ctty (this, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_console::open (int flags, mode_t)
|
||||
{
|
||||
|
@ -806,7 +813,7 @@ fhandler_console::open (int flags, mode_t)
|
|||
dev_state.set_default_attr ();
|
||||
}
|
||||
|
||||
tc ()->rstcons (false);
|
||||
get_ttyp ()->rstcons (false);
|
||||
set_open_status ();
|
||||
|
||||
DWORD cflags;
|
||||
|
@ -825,7 +832,7 @@ fhandler_console::open_setup (int flags)
|
|||
{
|
||||
cygheap->manage_console_count ("fhandler_console::open", 1);
|
||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||
myself->set_ctty (&shared_console_info->tty_min_state, flags, this);
|
||||
myself->set_ctty (this, flags);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -841,7 +848,7 @@ fhandler_console::close ()
|
|||
int
|
||||
fhandler_console::ioctl (unsigned int cmd, void *arg)
|
||||
{
|
||||
int res = ioctl_termios (cmd, (int) arg);
|
||||
int res = fhandler_termios::ioctl (cmd, arg);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
switch (cmd)
|
||||
|
@ -970,8 +977,8 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
|
|||
available. We've got ECHO and ICANON, they've
|
||||
got ENABLE_ECHO_INPUT and ENABLE_LINE_INPUT. */
|
||||
|
||||
termios_printf ("this %p, tc () %p, t %p", this, tc (), t);
|
||||
tc ()->ti = *t;
|
||||
termios_printf ("this %p, get_ttyp () %p, t %p", this, get_ttyp (), t);
|
||||
get_ttyp ()->ti = *t;
|
||||
|
||||
if (t->c_lflag & ECHO)
|
||||
{
|
||||
|
@ -1010,7 +1017,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
|
|||
res, t, flags, t->c_lflag, t->c_iflag);
|
||||
}
|
||||
|
||||
tc ()->rstcons (false);
|
||||
get_ttyp ()->rstcons (false);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1027,7 +1034,7 @@ int
|
|||
fhandler_console::tcgetattr (struct termios *t)
|
||||
{
|
||||
int res;
|
||||
*t = tc ()->ti;
|
||||
*t = get_ttyp ()->ti;
|
||||
|
||||
t->c_cflag |= CS8;
|
||||
|
||||
|
@ -1067,8 +1074,9 @@ fhandler_console::fhandler_console (fh_devices unit) :
|
|||
{
|
||||
if (unit > 0)
|
||||
dev ().parse (unit);
|
||||
get_tty_stuff ();
|
||||
setup ();
|
||||
trunc_buf.len = 0;
|
||||
_tc = &(shared_console_info->tty_min_state);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1866,7 +1874,7 @@ do_print:
|
|||
y--;
|
||||
}
|
||||
}
|
||||
cursor_set (false, ((tc ()->ti.c_oflag & ONLCR) ? 0 : x), y + 1);
|
||||
cursor_set (false, ((get_ttyp ()->ti.c_oflag & ONLCR) ? 0 : x), y + 1);
|
||||
break;
|
||||
case BAK:
|
||||
cursor_rel (-1, 0);
|
||||
|
@ -2192,13 +2200,13 @@ fhandler_console::init (HANDLE h, DWORD a, mode_t bin)
|
|||
if (h && h != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (h); /* Reopened by open */
|
||||
|
||||
return !tcsetattr (0, &tc ()->ti);
|
||||
return !tcsetattr (0, &get_ttyp ()->ti);
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_console::igncr_enabled ()
|
||||
{
|
||||
return tc ()->ti.c_iflag & IGNCR;
|
||||
return get_ttyp ()->ti.c_iflag & IGNCR;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1390,11 +1390,11 @@ fhandler_disk_file::close ()
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_disk_file::dup (fhandler_base *child)
|
||||
fhandler_disk_file::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
fhandler_disk_file *fhc = (fhandler_disk_file *) child;
|
||||
|
||||
int ret = fhandler_base::dup (child);
|
||||
int ret = fhandler_base::dup (child, flags);
|
||||
if (!ret && prw_handle
|
||||
&& !DuplicateHandle (GetCurrentProcess (), prw_handle,
|
||||
GetCurrentProcess (), &fhc->prw_handle,
|
||||
|
|
|
@ -303,9 +303,9 @@ fhandler_fifo::close ()
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_fifo::dup (fhandler_base *child)
|
||||
fhandler_fifo::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
int res = fhandler_base_overlapped::dup (child);
|
||||
int res = fhandler_base_overlapped::dup (child, flags);
|
||||
fhandler_fifo *fifo_child = (fhandler_fifo *) child;
|
||||
if (res == 0 && dummy_client)
|
||||
{
|
||||
|
|
|
@ -405,9 +405,9 @@ fhandler_dev_floppy::close ()
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_dev_floppy::dup (fhandler_base *child)
|
||||
fhandler_dev_floppy::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
int ret = fhandler_dev_raw::dup (child);
|
||||
int ret = fhandler_dev_raw::dup (child, flags);
|
||||
|
||||
if (!ret && partitions)
|
||||
InterlockedIncrement (&partitions->refcnt);
|
||||
|
|
|
@ -1371,7 +1371,7 @@ format_proc_devices (void *, char *&destbuf)
|
|||
"%3d sd\n"
|
||||
"%3d sd\n",
|
||||
DEV_MEM_MAJOR, DEV_CONS_MAJOR, _major (FH_TTY),
|
||||
_major (FH_CONSOLE), _major (FH_PTYM),
|
||||
_major (FH_CONSOLE), _major (FH_PTMX),
|
||||
DEV_TAPE_MAJOR, DEV_MISC_MAJOR, DEV_SOUND_MAJOR,
|
||||
DEV_SERIAL_MAJOR, DEV_TTYS_MAJOR, DEV_FLOPPY_MAJOR,
|
||||
DEV_SD_MAJOR, DEV_CDROM_MAJOR, DEV_SD1_MAJOR,
|
||||
|
|
|
@ -178,7 +178,7 @@ fhandler_dev_random::close ()
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_dev_random::dup (fhandler_base *child)
|
||||
fhandler_dev_random::dup (fhandler_base *child, int)
|
||||
{
|
||||
fhandler_dev_random *fhr = (fhandler_dev_random *) child;
|
||||
fhr->crypt_prov = (HCRYPTPROV)NULL;
|
||||
|
|
|
@ -81,9 +81,9 @@ fhandler_dev_raw::open (int flags, mode_t)
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_dev_raw::dup (fhandler_base *child)
|
||||
fhandler_dev_raw::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
int ret = fhandler_base::dup (child);
|
||||
int ret = fhandler_base::dup (child, flags);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
|
|
@ -1026,12 +1026,12 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_registry::dup (fhandler_base *child)
|
||||
fhandler_registry::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
debug_printf ("here");
|
||||
fhandler_registry *fhs = (fhandler_registry *) child;
|
||||
|
||||
int ret = fhandler_virtual::dup (fhs);
|
||||
int ret = fhandler_virtual::dup (fhs, flags);
|
||||
/* Pseudo registry handles can't be duplicated using DuplicateHandle.
|
||||
Therefore those fhandlers are marked with the nohandle flag. This
|
||||
allows fhandler_base::dup to succeed as usual for nohandle fhandlers.
|
||||
|
|
|
@ -1172,9 +1172,9 @@ fhandler_serial::fixup_after_exec ()
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_serial::dup (fhandler_base *child)
|
||||
fhandler_serial::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
fhandler_serial *fhc = (fhandler_serial *) child;
|
||||
fhc->overlapped_setup ();
|
||||
return fhandler_base::dup (child);
|
||||
return fhandler_base::dup (child, flags);
|
||||
}
|
||||
|
|
|
@ -750,7 +750,7 @@ fhandler_socket::fixup_after_exec ()
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_socket::dup (fhandler_base *child)
|
||||
fhandler_socket::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
debug_printf ("here");
|
||||
fhandler_socket *fhs = (fhandler_socket *) child;
|
||||
|
@ -777,7 +777,7 @@ fhandler_socket::dup (fhandler_base *child)
|
|||
}
|
||||
if (!need_fixup_before ())
|
||||
{
|
||||
int ret = fhandler_base::dup (child);
|
||||
int ret = fhandler_base::dup (child, flags);
|
||||
if (ret)
|
||||
{
|
||||
NtClose (fhs->wsock_evt);
|
||||
|
|
|
@ -1444,7 +1444,7 @@ fhandler_dev_tape::fstat (struct __stat64 *buf)
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_dev_tape::dup (fhandler_base *child)
|
||||
fhandler_dev_tape::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
lock (-1);
|
||||
fhandler_dev_tape *fh = (fhandler_dev_tape *) child;
|
||||
|
@ -1468,7 +1468,7 @@ fhandler_dev_tape::dup (fhandler_base *child)
|
|||
__seterrno ();
|
||||
return unlock (-1);
|
||||
}
|
||||
return unlock (fhandler_dev_raw::dup (child));
|
||||
return unlock (fhandler_dev_raw::dup (child, flags));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -21,6 +21,8 @@ details. */
|
|||
#include "cygtls.h"
|
||||
#include "ntdll.h"
|
||||
|
||||
fhandler_termios *fhandler_termios::last;
|
||||
|
||||
/* Common functions shared by tty/console */
|
||||
|
||||
void
|
||||
|
@ -411,11 +413,13 @@ fhandler_termios::tcgetsid ()
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_termios::ioctl_termios (int cmd, int arg)
|
||||
fhandler_termios::ioctl (int cmd, void *varg)
|
||||
{
|
||||
if (cmd != TIOCSCTTY)
|
||||
return 1; /* Not handled by this function */
|
||||
|
||||
int arg = (int) varg;
|
||||
|
||||
if (arg != 0 && arg != 1)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
|
@ -431,6 +435,6 @@ fhandler_termios::ioctl_termios (int cmd, int arg)
|
|||
}
|
||||
|
||||
myself->ctty = -1;
|
||||
myself->set_ctty (tc (), 0, this);
|
||||
myself->set_ctty (this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -539,7 +539,7 @@ void
|
|||
fhandler_pty_slave::open_setup (int flags)
|
||||
{
|
||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||
myself->set_ctty (get_ttyp (), flags, this);
|
||||
myself->set_ctty (this, flags);
|
||||
cygheap->manage_console_count ("fhandler_pty_slave::open_setup", 1);
|
||||
report_tty_counts (this, "opened", "");
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
|
|||
if (bg <= bg_eof)
|
||||
return (ssize_t) bg;
|
||||
|
||||
termios_printf ("tty%d, write(%x, %d)", get_unit (), ptr, len);
|
||||
termios_printf ("pty%d, write(%x, %d)", get_unit (), ptr, len);
|
||||
|
||||
push_process_state process_state (PID_TTYOU);
|
||||
|
||||
|
@ -891,15 +891,16 @@ out:
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_pty_slave::dup (fhandler_base *child)
|
||||
fhandler_pty_slave::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
myself->set_ctty (this, flags);
|
||||
cygheap->manage_console_count ("fhandler_pty_slave::dup", 1);
|
||||
report_tty_counts (child, "duped slave", "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_pty_master::dup (fhandler_base *child)
|
||||
fhandler_pty_master::dup (fhandler_base *child, int)
|
||||
{
|
||||
report_tty_counts (child, "duped master", "");
|
||||
return 0;
|
||||
|
@ -947,7 +948,7 @@ int
|
|||
fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
|
||||
{
|
||||
termios_printf ("ioctl (%x)", cmd);
|
||||
int res = ioctl_termios (cmd, (int) arg);
|
||||
int res = fhandler_termios::ioctl (cmd, arg);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
|
||||
|
@ -1184,37 +1185,34 @@ errout:
|
|||
/*******************************************************
|
||||
fhandler_pty_master
|
||||
*/
|
||||
fhandler_pty_master::fhandler_pty_master ()
|
||||
: fhandler_pty_common (), pktmode (0), need_nl (0), dwProcessId (0)
|
||||
fhandler_pty_master::fhandler_pty_master (int unit)
|
||||
: fhandler_pty_common (), pktmode (0), master_ctl (NULL),
|
||||
master_thread (NULL), from_master (NULL), to_master (NULL),
|
||||
dwProcessId (0), need_nl (0)
|
||||
{
|
||||
if (unit >= 0)
|
||||
dev ().parse (DEV_TTYM_MAJOR, unit);
|
||||
else if (!setup ())
|
||||
dev ().parse (FH_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_pty_master::open (int flags, mode_t)
|
||||
{
|
||||
/* Note that allocate returns with the tty lock set if it was successful. */
|
||||
int unit = cygwin_shared->tty.allocate ();
|
||||
if (unit < 0)
|
||||
return 0;
|
||||
|
||||
dev().parse (DEV_TTYM_MAJOR, unit);
|
||||
if (!setup ())
|
||||
{
|
||||
lock_ttys::release ();
|
||||
return 0;
|
||||
}
|
||||
lock_ttys::release ();
|
||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||
set_open_status ();
|
||||
|
||||
dwProcessId = GetCurrentProcessId ();
|
||||
|
||||
char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")];
|
||||
__small_sprintf (buf, "opened pty master for tty%d", get_unit ());
|
||||
report_tty_counts (this, buf, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_pty_master::open_setup (int flags)
|
||||
{
|
||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||
char buf[sizeof ("opened pty master for ptyNNNNNNNNNNN")];
|
||||
__small_sprintf (buf, "opened pty master for pty%d", get_unit ());
|
||||
report_tty_counts (this, buf, "");
|
||||
}
|
||||
|
||||
_off64_t
|
||||
fhandler_pty_common::lseek (_off64_t, int)
|
||||
{
|
||||
|
@ -1225,7 +1223,7 @@ fhandler_pty_common::lseek (_off64_t, int)
|
|||
int
|
||||
fhandler_pty_common::close ()
|
||||
{
|
||||
termios_printf ("tty%d <%p,%p> closing", get_unit (), get_handle (), get_output_handle ());
|
||||
termios_printf ("pty%d <%p,%p> closing", get_unit (), get_handle (), get_output_handle ());
|
||||
if (!ForceCloseHandle (input_mutex))
|
||||
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
|
||||
if (!ForceCloseHandle (output_mutex))
|
||||
|
@ -1245,6 +1243,8 @@ void
|
|||
fhandler_pty_master::cleanup ()
|
||||
{
|
||||
report_tty_counts (this, "closing master", "");
|
||||
if (archetype)
|
||||
from_master = to_master = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1272,11 +1272,14 @@ fhandler_pty_master::close ()
|
|||
CloseHandle (master_ctl);
|
||||
master_thread->detach ();
|
||||
}
|
||||
if (!ForceCloseHandle (from_master))
|
||||
termios_printf ("error closing from_master %p, %E", from_master);
|
||||
if (!ForceCloseHandle (to_master))
|
||||
termios_printf ("error closing from_master %p, %E", to_master);
|
||||
}
|
||||
|
||||
if (!ForceCloseHandle (from_master))
|
||||
termios_printf ("error closing from_master %p, %E", from_master);
|
||||
if (!ForceCloseHandle (to_master))
|
||||
termios_printf ("error closing from_master %p, %E", to_master);
|
||||
from_master = to_master = NULL;
|
||||
|
||||
fhandler_pty_common::close ();
|
||||
|
||||
if (hExeced || get_ttyp ()->master_pid != myself->pid)
|
||||
|
@ -1287,6 +1290,15 @@ fhandler_pty_master::close ()
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This is just to catch error conditions. Since the constructor
|
||||
ctually opens some handles, and stat() does not open an fd, they need
|
||||
to be closed when the fhandler goes away. */
|
||||
fhandler_pty_master::~fhandler_pty_master ()
|
||||
{
|
||||
if (from_master && to_master)
|
||||
close_with_arch ();
|
||||
}
|
||||
|
||||
ssize_t __stdcall
|
||||
fhandler_pty_master::write (const void *ptr, size_t len)
|
||||
{
|
||||
|
@ -1361,7 +1373,7 @@ fhandler_pty_master::tcflush (int queue)
|
|||
int
|
||||
fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
|
||||
{
|
||||
int res = ioctl_termios (cmd, (int) arg);
|
||||
int res = fhandler_termios::ioctl (cmd, arg);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
|
||||
|
@ -1408,7 +1420,7 @@ fhandler_pty_master::ptsname ()
|
|||
{
|
||||
static char buf[TTY_NAME_MAX];
|
||||
|
||||
__small_sprintf (buf, "/dev/tty%d", get_unit ());
|
||||
__small_sprintf (buf, "/dev/pty%d", get_unit ());
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -1587,32 +1599,27 @@ fhandler_pty_master::setup ()
|
|||
security_descriptor sd;
|
||||
SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE };
|
||||
|
||||
tty& t = *cygwin_shared->tty[get_unit ()];
|
||||
_tc = (tty_min *)&t;
|
||||
/* Find an unallocated pty to use. */
|
||||
int unit = cygwin_shared->tty.allocate (from_master, get_output_handle ());
|
||||
if (unit < 0)
|
||||
return false;
|
||||
|
||||
ProtectHandle1 (get_output_handle (), to_pty);
|
||||
|
||||
tty& t = *cygwin_shared->tty[unit];
|
||||
_tc = (tty_min *) &t;
|
||||
|
||||
tcinit (true); /* Set termios information. Force initialization. */
|
||||
|
||||
const char *errstr = NULL;
|
||||
DWORD pipe_mode = PIPE_NOWAIT;
|
||||
|
||||
/* Create communication pipes */
|
||||
char pipename[sizeof("ptyNNNN-from-master")];
|
||||
__small_sprintf (pipename, "pty%d-from-master", get_unit ());
|
||||
res = fhandler_pipe::create_selectable (&sec_none, from_master,
|
||||
get_output_handle (), 128 * 1024,
|
||||
pipename);
|
||||
if (res)
|
||||
{
|
||||
errstr = "input pipe";
|
||||
goto err;
|
||||
}
|
||||
|
||||
ProtectHandle1 (get_output_handle (), to_pty);
|
||||
if (!SetNamedPipeHandleState (get_output_handle (), &pipe_mode, NULL, NULL))
|
||||
termios_printf ("can't set output_handle(%p) to non-blocking mode",
|
||||
get_output_handle ());
|
||||
|
||||
__small_sprintf (pipename, "pty%d-to-master", get_unit ());
|
||||
char pipename[sizeof("ptyNNNN-from-master")];
|
||||
__small_sprintf (pipename, "pty%d-to-master", unit);
|
||||
res = fhandler_pipe::create_selectable (&sec_none, get_io_handle (),
|
||||
to_master, 128 * 1024, pipename);
|
||||
if (res)
|
||||
|
@ -1622,7 +1629,6 @@ fhandler_pty_master::setup ()
|
|||
}
|
||||
|
||||
ProtectHandle1 (get_io_handle (), from_pty);
|
||||
need_nl = 0;
|
||||
|
||||
/* Create security attribute. Default permissions are 0620. */
|
||||
sd.malloc (sizeof (SECURITY_DESCRIPTOR));
|
||||
|
@ -1642,18 +1648,18 @@ fhandler_pty_master::setup ()
|
|||
goto err;
|
||||
|
||||
char buf[MAX_PATH];
|
||||
errstr = shared_name (buf, OUTPUT_MUTEX, t.get_unit ());
|
||||
errstr = shared_name (buf, OUTPUT_MUTEX, unit);
|
||||
if (!(output_mutex = CreateMutex (&sa, FALSE, buf)))
|
||||
goto err;
|
||||
|
||||
errstr = shared_name (buf, INPUT_MUTEX, t.get_unit ());
|
||||
errstr = shared_name (buf, INPUT_MUTEX, unit);
|
||||
if (!(input_mutex = CreateMutex (&sa, FALSE, buf)))
|
||||
goto err;
|
||||
|
||||
/* Create master control pipe which allows the master to duplicate
|
||||
the pty pipe handles to processes which deserve it. */
|
||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
|
||||
&installation_key, get_unit ());
|
||||
&installation_key, unit);
|
||||
master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX,
|
||||
PIPE_WAIT | PIPE_TYPE_MESSAGE
|
||||
| PIPE_READMODE_MESSAGE, 1, 4096, 4096,
|
||||
|
@ -1676,7 +1682,9 @@ fhandler_pty_master::setup ()
|
|||
t.winsize.ws_row = 25;
|
||||
t.master_pid = myself->pid;
|
||||
|
||||
termios_printf ("tty%d opened - from_pty %p, to_pty %p", t.get_unit (),
|
||||
dev ().parse (DEV_TTYM_MAJOR, unit);
|
||||
|
||||
termios_printf ("this %p, pty%d opened - from_pty %p, to_pty %p", this, unit,
|
||||
get_io_handle (), get_output_handle ());
|
||||
return true;
|
||||
|
||||
|
@ -1690,8 +1698,7 @@ err:
|
|||
close_maybe (from_master);
|
||||
close_maybe (to_master);
|
||||
close_maybe (master_ctl);
|
||||
termios_printf ("tty%d open failed - failed to create %s", t.get_unit (),
|
||||
errstr);
|
||||
termios_printf ("pty%d open failed - failed to create %s", unit, errstr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -152,9 +152,9 @@ fhandler_virtual::lseek (_off64_t offset, int whence)
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_virtual::dup (fhandler_base * child)
|
||||
fhandler_virtual::dup (fhandler_base * child, int flags)
|
||||
{
|
||||
int ret = fhandler_base::dup (child);
|
||||
int ret = fhandler_base::dup (child, flags);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
|
|
@ -1118,6 +1118,12 @@ out:
|
|||
if (saw_symlinks)
|
||||
set_has_symlinks ();
|
||||
|
||||
if (opt & PC_OPEN)
|
||||
path_flags |= PATH_OPEN;
|
||||
|
||||
if (opt & PC_CTTY)
|
||||
path_flags |= PATH_CTTY;
|
||||
|
||||
if ((opt & PC_POSIX))
|
||||
{
|
||||
if (tail < path_end && tail > path_copy + 1)
|
||||
|
|
|
@ -51,6 +51,8 @@ enum pathconv_arg
|
|||
PC_NULLEMPTY = 0x0020,
|
||||
PC_POSIX = 0x0080,
|
||||
PC_NOWARN = 0x0100,
|
||||
PC_OPEN = 0x0200, /* use open semantics */
|
||||
PC_CTTY = 0x0400, /* could later be used as ctty */
|
||||
PC_KEEP_HANDLE = 0x00400000,
|
||||
PC_NO_ACCESS_CHECK = 0x00800000
|
||||
};
|
||||
|
@ -74,6 +76,8 @@ enum path_types
|
|||
PATH_IHASH = MOUNT_IHASH,
|
||||
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
|
||||
PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
|
||||
PATH_CTTY = 0x00400000, /* could later be used as ctty */
|
||||
PATH_OPEN = 0x00800000, /* use open semantics */
|
||||
PATH_LNK = 0x01000000,
|
||||
PATH_TEXT = 0x02000000,
|
||||
PATH_REP = 0x04000000,
|
||||
|
@ -111,7 +115,7 @@ public:
|
|||
CloseHandle (hdl);
|
||||
set (NULL);
|
||||
}
|
||||
inline void dup (path_conv_handle &pch)
|
||||
inline void dup (const path_conv_handle &pch)
|
||||
{
|
||||
if (!DuplicateHandle (GetCurrentProcess (), pch.handle (),
|
||||
GetCurrentProcess (), &hdl,
|
||||
|
@ -175,6 +179,8 @@ class path_conv
|
|||
int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
|
||||
int issocket () const {return dev.is_device (FH_UNIX);}
|
||||
int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
|
||||
int isopen () const {return path_flags & PATH_OPEN;}
|
||||
int isctty_capable () const {return path_flags & PATH_CTTY;}
|
||||
void set_cygexec (bool isset)
|
||||
{
|
||||
if (isset)
|
||||
|
@ -276,7 +282,7 @@ class path_conv
|
|||
PWCHAR get_wide_win32_path (PWCHAR wc);
|
||||
operator DWORD &() {return fileattr;}
|
||||
operator int () {return fileattr; }
|
||||
path_conv &operator =(path_conv& pc)
|
||||
path_conv &operator =(const path_conv& pc)
|
||||
{
|
||||
memcpy (this, &pc, sizeof pc);
|
||||
path = cstrdup (pc.path);
|
||||
|
|
|
@ -372,13 +372,14 @@ _pinfo::_ctty (char *buf)
|
|||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
_pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *fh)
|
||||
bool
|
||||
_pinfo::set_ctty (fhandler_termios *fh, int flags)
|
||||
{
|
||||
debug_printf ("old %s, ctty device number %p, tc->ntty device number %p flags & O_NOCTTY %p", __ctty (), ctty, tc->ntty, flags & O_NOCTTY);
|
||||
if ((ctty <= 0 || ctty == tc->ntty) && !(flags & O_NOCTTY))
|
||||
tty_min& tc = *fh->tc ();
|
||||
debug_printf ("old %s, ctty device number %p, tc.ntty device number %p flags & O_NOCTTY %p", __ctty (), ctty, tc.ntty, flags & O_NOCTTY);
|
||||
if (fh && &tc && (ctty <= 0 || ctty == tc.ntty) && !(flags & O_NOCTTY))
|
||||
{
|
||||
ctty = tc->ntty;
|
||||
ctty = tc.ntty;
|
||||
if (cygheap->ctty != fh->archetype)
|
||||
{
|
||||
debug_printf ("cygheap->ctty %p, archetype %p", cygheap->ctty, fh->archetype);
|
||||
|
@ -402,34 +403,35 @@ _pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *fh)
|
|||
|
||||
lock_ttys here;
|
||||
syscall_printf ("attaching %s sid %d, pid %d, pgid %d, tty->pgid %d, tty->sid %d",
|
||||
__ctty (), sid, pid, pgid, tc->getpgid (), tc->getsid ());
|
||||
__ctty (), sid, pid, pgid, tc.getpgid (), tc.getsid ());
|
||||
if (!cygwin_finished_initializing && !myself->cygstarted
|
||||
&& myself->pgid == myself->pid && tc->getpgid () && tc->getsid ())
|
||||
&& myself->pgid == myself->pid && tc.getpgid () && tc.getsid ())
|
||||
{
|
||||
myself->pgid = tc->getpgid ();
|
||||
myself->sid = tc->getsid ();
|
||||
myself->pgid = tc.getpgid ();
|
||||
myself->sid = tc.getsid ();
|
||||
}
|
||||
|
||||
pinfo p (tc->getsid ());
|
||||
pinfo p (tc.getsid ());
|
||||
if (sid == pid && (!p || p->pid == pid || !p->exists ()))
|
||||
{
|
||||
#ifdef DEBUGGING
|
||||
debug_printf ("resetting %s sid. Was %d, now %d. pgid was %d, now %d.",
|
||||
__ctty (), tc->getsid (), sid, tc->getpgid (), pgid);
|
||||
__ctty (), tc.getsid (), sid, tc.getpgid (), pgid);
|
||||
#else
|
||||
paranoid_printf ("resetting %s sid. Was %d, now %d. pgid was %d, now %d.",
|
||||
__ctty (), tc->getsid (), sid, tc->getpgid (), pgid);
|
||||
__ctty (), tc.getsid (), sid, tc.getpgid (), pgid);
|
||||
#endif
|
||||
/* We are the session leader */
|
||||
tc->setsid (sid);
|
||||
tc->setpgid (pgid);
|
||||
tc.setsid (sid);
|
||||
tc.setpgid (pgid);
|
||||
}
|
||||
else
|
||||
sid = tc->getsid ();
|
||||
if (tc->getpgid () == 0)
|
||||
tc->setpgid (pgid);
|
||||
sid = tc.getsid ();
|
||||
if (tc.getpgid () == 0)
|
||||
tc.setpgid (pgid);
|
||||
}
|
||||
debug_printf ("cygheap->ctty now %p, archetype %p", cygheap->ctty, fh->archetype);
|
||||
debug_printf ("cygheap->ctty now %p, archetype %p", cygheap->ctty, fh->archetype);
|
||||
return ctty > 0;
|
||||
}
|
||||
|
||||
/* Test to determine if a process really exists and is processing signals.
|
||||
|
|
|
@ -110,7 +110,7 @@ public:
|
|||
char *root (size_t &);
|
||||
char *cwd (size_t &);
|
||||
char *cmdline (size_t &);
|
||||
void set_ctty (class tty_min *, int, class fhandler_termios *);
|
||||
bool set_ctty (class fhandler_termios *, int);
|
||||
HANDLE dup_proc_pipe (HANDLE) __attribute__ ((regparm(2)));
|
||||
void sync_proc_pipe ();
|
||||
bool alert_parent (char);
|
||||
|
|
|
@ -86,10 +86,10 @@ fhandler_pipe::open (int flags, mode_t mode)
|
|||
set_errno (EACCES);
|
||||
return 0;
|
||||
}
|
||||
*this = *(fhandler_pipe *) cfd;
|
||||
cfd->copyto (this);
|
||||
set_io_handle (NULL);
|
||||
pc.reset_conv_handle ();
|
||||
if (!cfd->dup (this))
|
||||
if (!cfd->dup (this, flags))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -172,13 +172,13 @@ fhandler_pipe::get_proc_fd_name (char *buf)
|
|||
}
|
||||
|
||||
int
|
||||
fhandler_pipe::dup (fhandler_base *child)
|
||||
fhandler_pipe::dup (fhandler_base *child, int flags)
|
||||
{
|
||||
fhandler_pipe *ftp = (fhandler_pipe *) child;
|
||||
ftp->set_popen_pid (0);
|
||||
|
||||
int res;
|
||||
if (get_handle () && fhandler_base_overlapped::dup (child))
|
||||
if (get_handle () && fhandler_base_overlapped::dup (child, flags))
|
||||
res = -1;
|
||||
else
|
||||
res = 0;
|
||||
|
|
|
@ -1134,12 +1134,16 @@ open (const char *unix_path, int flags, ...)
|
|||
a change in behavior that implements linux functionality: opening
|
||||
a tty should not automatically cause it to become the controlling
|
||||
tty for the process. */
|
||||
if (0 && fd > 2)
|
||||
flags |= O_NOCTTY;
|
||||
if (!(fh = build_fh_name (unix_path,
|
||||
(flags & (O_NOFOLLOW | O_EXCL))
|
||||
? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW,
|
||||
stat_suffixes)))
|
||||
int opt = PC_OPEN | ((flags & (O_NOFOLLOW | O_EXCL))
|
||||
? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW);
|
||||
if (!(flags & O_NOCTTY)&& fd > 2)
|
||||
{
|
||||
flags |= O_NOCTTY;
|
||||
opt |= PC_CTTY; /* flag that, if opened, this fhandler could
|
||||
later be capable of being a controlling
|
||||
terminal if /dev/tty is opened. */
|
||||
}
|
||||
if (!(fh = build_fh_name (unix_path, opt, stat_suffixes)))
|
||||
res = -1; // errno already set
|
||||
else if ((flags & O_NOFOLLOW) && fh->issymlink ())
|
||||
{
|
||||
|
@ -1600,10 +1604,9 @@ stat_worker (path_conv &pc, struct __stat64 *buf)
|
|||
if (!buf->st_ino)
|
||||
buf->st_ino = fh->get_ino ();
|
||||
if (!buf->st_dev)
|
||||
buf->st_dev = fh->is_dev_tty () ? FH_TTY : fh->get_device ();
|
||||
buf->st_dev = fh->get_device ();
|
||||
if (!buf->st_rdev)
|
||||
buf->st_rdev = buf->st_dev;
|
||||
debug_printf ("is_dev_tty %d, st_dev %p\n", fh->is_dev_tty (), buf->st_dev);
|
||||
}
|
||||
delete fh;
|
||||
}
|
||||
|
@ -1620,7 +1623,8 @@ extern "C" int
|
|||
stat64 (const char *name, struct __stat64 *buf)
|
||||
{
|
||||
syscall_printf ("entering");
|
||||
path_conv pc (name, PC_SYM_FOLLOW | PC_POSIX | PC_KEEP_HANDLE, stat_suffixes);
|
||||
path_conv pc (name, PC_SYM_FOLLOW | PC_POSIX | PC_KEEP_HANDLE,
|
||||
stat_suffixes);
|
||||
return stat_worker (pc, buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ tty_list::connect (int ttynum)
|
|||
}
|
||||
if (!ttys[ttynum].exists ())
|
||||
{
|
||||
termios_printf ("tty %d was not allocated", ttynum);
|
||||
termios_printf ("pty %d was not allocated", ttynum);
|
||||
set_errno (ENXIO);
|
||||
return -1;
|
||||
}
|
||||
|
@ -124,14 +124,14 @@ tty_list::init ()
|
|||
Return tty number or -1 if error.
|
||||
*/
|
||||
int
|
||||
tty_list::allocate ()
|
||||
tty_list::allocate (HANDLE& r, HANDLE& w)
|
||||
{
|
||||
lock_ttys here;
|
||||
int freetty = -1;
|
||||
|
||||
tty *t = NULL;
|
||||
for (int i = 0; i < NTTYS; i++)
|
||||
if (!ttys[i].exists ())
|
||||
if (ttys[i].not_allocated (r, w))
|
||||
{
|
||||
t = ttys + i;
|
||||
t->init ();
|
||||
|
@ -140,38 +140,46 @@ tty_list::allocate ()
|
|||
break;
|
||||
}
|
||||
|
||||
if (freetty < 0)
|
||||
system_printf ("No tty allocated");
|
||||
if (freetty >= 0)
|
||||
termios_printf ("pty%d allocated", freetty);
|
||||
else
|
||||
{
|
||||
termios_printf ("tty%d allocated", freetty);
|
||||
here.dont_release (); /* exit with mutex still held -- caller has more work to do */
|
||||
system_printf ("No pty allocated");
|
||||
r = w = NULL;
|
||||
}
|
||||
|
||||
return freetty;
|
||||
}
|
||||
|
||||
bool
|
||||
tty::not_allocated (HANDLE& r, HANDLE& w)
|
||||
{
|
||||
/* Attempt to open the from-master side of the tty. If it is accessible
|
||||
then it exists although we may not have privileges to actually use it. */
|
||||
char pipename[sizeof("ptyNNNN-from-master")];
|
||||
__small_sprintf (pipename, "pty%d-from-master", get_unit ());
|
||||
/* fhandler_pipe::create_selectable returns 0 when creation succeeds */
|
||||
return fhandler_pipe::create_selectable (&sec_none, r, w, 128 * 1024,
|
||||
pipename) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
tty::exists ()
|
||||
{
|
||||
/* Attempt to open the from-master side of the tty. If it is accessible
|
||||
then it exists although it may have been privileges to actually use it. */
|
||||
char pipename[sizeof("ttyNNNN-from-master")];
|
||||
__small_sprintf (pipename, "tty%d-from-master", get_unit ());
|
||||
HANDLE r, w;
|
||||
int res = fhandler_pipe::create_selectable (&sec_none_nih, r, w, 0, pipename);
|
||||
if (res)
|
||||
return true;
|
||||
bool res;
|
||||
if (!not_allocated (r, w))
|
||||
res = true;
|
||||
|
||||
CloseHandle (r);
|
||||
CloseHandle (w);
|
||||
|
||||
HANDLE h = open_output_mutex (READ_CONTROL);
|
||||
if (h)
|
||||
else
|
||||
{
|
||||
CloseHandle (h);
|
||||
return true;
|
||||
/* Handles are left open when not_allocated finds a non-open "tty" */
|
||||
CloseHandle (r);
|
||||
CloseHandle (w);
|
||||
res = false;
|
||||
}
|
||||
return slave_alive ();
|
||||
debug_printf ("exists %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -14,7 +14,7 @@ details. */
|
|||
|
||||
#define INP_BUFFER_SIZE 256
|
||||
#define OUT_BUFFER_SIZE 256
|
||||
#define NTTYS 128
|
||||
#define NTTYS 64
|
||||
#define real_tty_attached(p) ((p)->ctty >= 0 && !iscons_dev ((p)->ctty))
|
||||
|
||||
/* Input/Output/ioctl events */
|
||||
|
@ -107,6 +107,7 @@ public:
|
|||
inline HANDLE open_input_mutex (ACCESS_MASK access)
|
||||
{ return open_mutex (INPUT_MUTEX, access); }
|
||||
bool exists ();
|
||||
bool not_allocated (HANDLE&, HANDLE&);
|
||||
void set_master_closed () {master_pid = -1;}
|
||||
static void __stdcall create_master (int);
|
||||
static void __stdcall init_session ();
|
||||
|
@ -120,7 +121,7 @@ class tty_list
|
|||
|
||||
public:
|
||||
tty * operator [](int n) {return ttys + device::minor (n);}
|
||||
int allocate (); /* allocate a pty */
|
||||
int allocate (HANDLE& r, HANDLE& w); /* allocate a pty */
|
||||
int connect (int);
|
||||
void init ();
|
||||
tty_min *get_cttyp ();
|
||||
|
|
Loading…
Reference in New Issue