* 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:
Christopher Faylor 2011-10-15 22:37:30 +00:00
parent a9cc13a8e0
commit 23771fa1f7
31 changed files with 10454 additions and 7870 deletions

View File

@ -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.

View File

@ -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))

File diff suppressed because it is too large Load Diff

View File

@ -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;}

View File

@ -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"

View File

@ -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

View File

@ -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;
}

View File

@ -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) \

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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)
{

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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)
{

View File

@ -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.

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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)

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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 ();