* 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> 2011-10-15 Corinna Vinschen <corinna@vinschen.de>
* fhandler_process.cc (dos_drive_mappings::fixup_if_match): Convert * fhandler_process.cc (dos_drive_mappings::fixup_if_match): Convert
@ -63,6 +177,11 @@
(fhandler_base::tcgetsid): New function. (fhandler_base::tcgetsid): New function.
* fhandler.h ((fhandler_base::tcgetsid): Declare new function. * fhandler.h ((fhandler_base::tcgetsid): Declare new function.
(fhandler_base::is_dev_tty): Ditto. (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::opened_as_dev_tty): Declare new field.
(fhandler_termios::is_dev_tty): Declare new function. (fhandler_termios::is_dev_tty): Declare new function.
(fhandler_termios::tcgetsid): Ditto. (fhandler_termios::tcgetsid): Ditto.

View File

@ -25,7 +25,7 @@ int __stdcall geterrno_from_nt_status (NTSTATUS status, int deferrno = 13 /*EACC
inline int inline int
__set_errno (const char *fn, int ln, int val) __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; return errno = _impure_ptr->_errno = val;
} }
#define set_errno(val) __set_errno (__PRETTY_FUNCTION__, __LINE__, (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 _minor(dev) ((dev) & ((1 << (sizeof (_minor_t) * 8)) - 1))
#define _major(dev) ((dev) >> (sizeof (_major_t) * 8)) #define _major(dev) ((dev) >> (sizeof (_major_t) * 8))
#define MAX_CONSOLES 31 #define MAX_CONSOLES 63
enum fh_devices enum fh_devices
{ {
FH_TTY = FHDEV (5, 0), FH_TTY = FHDEV (5, 0),
FH_CONSOLE = FHDEV (5, 1), FH_CONSOLE = FHDEV (5, 1),
FH_PTYM = FHDEV (5, 2), /* /dev/ptmx */ FH_PTMX = FHDEV (5, 2),
FH_CONIN = FHDEV (5, 255), FH_CONIN = FHDEV (5, 255),
FH_CONOUT = FHDEV (5, 254), FH_CONOUT = FHDEV (5, 254),
@ -306,7 +306,7 @@ struct device
_minor_t get_minor () const {return d.minor;} _minor_t get_minor () const {return d.minor;}
_minor_t get_major () const {return d.major;} _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 fh_devices () {return d.devn_fh_devices;}
inline operator bool () {return !!d.devn_int;} inline operator bool () {return !!d.devn_int;}
inline operator DWORD& () {return d.devn_dword;} 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", 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/cons%(0-63)d", BRACK(FHDEV(DEV_CONS_MAJOR, {$1})), "/dev/cons{$1}", cons_dev
"/dev/console", BRACK(FH_CONSOLE), "/dev/console", console_dev "/dev/console", BRACK(FH_CONSOLE), "/dev/console", console_dev
"/dev/ptmx", BRACK(FH_PTYM), "/dev/ptmx" "/dev/ptmx", BRACK(FH_PTMX), "/dev/ptmx"
"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows" "/dev/windows", BRACK(FH_WINDOWS), "/dev/windows"
"/dev/dsp", BRACK(FH_OSS_DSP), "/dev/dsp" "/dev/dsp", BRACK(FH_OSS_DSP), "/dev/dsp"
"/dev/conin", BRACK(FH_CONIN), "/dev/conin" "/dev/conin", BRACK(FH_CONIN), "/dev/conin"

View File

@ -113,7 +113,7 @@ dtable::get_debugger_info ()
extern bool jit_debug; extern bool jit_debug;
if (!jit_debug && being_debugged ()) 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'; std[0][0] = std[1][0] = std [2][0] = '\0';
char buf[sizeof ("cYgstd %x") + 32]; char buf[sizeof ("cYgstd %x") + 32];
sprintf (buf, "cYgstd %x %x %x", (unsigned) &std, sizeof (std[0]), 3); 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; \ 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 * fhandler_base *
build_fh_name (const char *name, unsigned opt, suffix_info *si) 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) #define fh_unset ((fhandler_base *) 1)
static fhandler_base * static fhandler_base *
fh_alloc (device dev) fh_alloc (path_conv& pc)
{ {
fhandler_base *fh = fh_unset; fhandler_base *fh = fh_unset;
fhandler_base *fhraw = NULL;
switch (dev.get_major ()) switch (pc.dev.get_major ())
{ {
case DEV_TTYS_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; break;
case DEV_CYGDRIVE_MAJOR: case DEV_CYGDRIVE_MAJOR:
fh = cnew (fhandler_cygdrive); fh = cnew (fhandler_cygdrive);
@ -461,18 +472,21 @@ fh_alloc (device dev)
fh = cnew (fhandler_serial); fh = cnew (fhandler_serial);
break; break;
case DEV_CONS_MAJOR: case DEV_CONS_MAJOR:
fh = cnew (fhandler_console, dev); fh = cnew (fhandler_console, pc.dev);
break; break;
default: default:
switch ((int) dev) switch ((int) pc.dev)
{ {
case FH_CONSOLE: case FH_CONSOLE:
case FH_CONIN: case FH_CONIN:
case FH_CONOUT: case FH_CONOUT:
fh = cnew (fhandler_console, dev); fh = cnew (fhandler_console, pc.dev);
break; break;
case FH_PTYM: case FH_PTMX:
fh = cnew (fhandler_pty_master); if (pc.isopen ())
fh = cnew (fhandler_pty_master, -1);
else
fhraw = cnew_no_ctor (fhandler_pty_master, -1);
break; break;
case FH_WINDOWS: case FH_WINDOWS:
fh = cnew (fhandler_windows); fh = cnew (fhandler_windows);
@ -540,40 +554,52 @@ fh_alloc (device dev)
fh = cnew (fhandler_netdrive); fh = cnew (fhandler_netdrive);
break; break;
case FH_TTY: case FH_TTY:
{ if (!pc.isopen ())
if (myself->ctty > 0) fhraw = cnew_no_ctor (fhandler_console, -1);
{ else if (myself->ctty <= 0
if (iscons_dev (myself->ctty)) && !myself->set_ctty (fhandler_termios::last, 0))
fh = cnew (fhandler_console, dev); /* no tty assigned */;
else if (iscons_dev (myself->ctty))
fh = cnew (fhandler_console, pc.dev);
else else
fh = cnew (fhandler_pty_slave, myself->ctty); fh = cnew (fhandler_pty_slave, myself->ctty);
}
((fhandler_termios *) fh)->is_dev_tty (true);
break; break;
}
case FH_KMSG: case FH_KMSG:
fh = cnew (fhandler_mailslot); fh = cnew (fhandler_mailslot);
break; 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) if (fh == fh_unset)
fh = cnew (fhandler_nodevice); fh = cnew (fhandler_nodevice);
else if (fh->dev () == FH_ERROR)
{
delete fh;
fh = NULL;
}
return fh; return fh;
} }
fhandler_base * fhandler_base *
build_fh_pc (path_conv& pc, bool set_name) build_fh_pc (path_conv& pc, bool set_name)
{ {
fhandler_base *fh = fh_alloc (pc.dev); fhandler_base *fh = fh_alloc (pc);
if (!fh) if (!fh)
{ {
set_errno (EMFILE); set_errno (ENXIO);
goto out; goto out;
} }
else if (fh->dev () == FH_ERROR)
goto out;
else if (fh->dev () != FH_NADA) else if (fh->dev () != FH_NADA)
fh->set_name (fh->dev ().name); fh->set_name (fh->dev ().name);
else if (set_name) else if (set_name)
@ -582,18 +608,25 @@ build_fh_pc (path_conv& pc, bool set_name)
if (!fh->use_archetype ()) if (!fh->use_archetype ())
/* doesn't use archetypes */; /* doesn't use archetypes */;
else if ((fh->archetype = cygheap->fdtab.find_archetype (fh->dev ()))) 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 else
{ {
debug_printf ("creating an archetype for %s(%d/%d)", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ()); fh->archetype = fh->clone ();
fh->archetype = fh_alloc (fh->pc.dev); 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 = *fh;
fh->archetype->archetype = NULL; fh->archetype->archetype = NULL;
*cygheap->fdtab.add_archetype () = fh->archetype; *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: out:
debug_printf ("fh %p", fh); debug_printf ("fh %p, dev %p", fh, (DWORD) fh->dev ());
return fh; 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 /* Don't call set_name in build_fh_pc. It will be called in
fhandler_base::operator= below. Calling it twice will result fhandler_base::operator= below. Calling it twice will result
in double allocation. */ in double allocation. */
fhandler_base *newfh = build_fh_pc (oldfh->pc, false); fhandler_base *newfh = oldfh->clone ();
if (!newfh) if (!newfh)
debug_printf ("build_fh_pc failed"); debug_printf ("build_fh_pc failed");
else else
{ {
*newfh = *oldfh;
if (!oldfh->archetype) if (!oldfh->archetype)
newfh->set_io_handle (NULL); newfh->set_io_handle (NULL);
newfh->pc.reset_conv_handle (); newfh->pc.reset_conv_handle ();
if (oldfh->dup (newfh)) if (oldfh->dup (newfh, flags))
{ {
delete newfh; delete newfh;
newfh = NULL; newfh = NULL;
@ -625,6 +658,14 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
/* The O_CLOEXEC flag enforces close-on-exec behaviour. */ /* The O_CLOEXEC flag enforces close-on-exec behaviour. */
newfh->set_close_on_exec (!!(flags & O_CLOEXEC)); 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 ()); 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; return newfh;
@ -659,6 +700,13 @@ dtable::dup3 (int oldfd, int newfd, int flags)
return -1; 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) if ((newfh = dup_worker (fds[oldfd], flags)) == NULL)
{ {
res = -1; res = -1;
@ -817,7 +865,7 @@ static void
decode_tty (char *buf, WCHAR *w32) decode_tty (char *buf, WCHAR *w32)
{ {
int ttyn = wcstol (w32, NULL, 10); 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 /* 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; struct __cygwin_perfile *perfile_table;
inline fhandler_base& void
fhandler_base::operator =(fhandler_base& x) fhandler_base::reset (const fhandler_base *from)
{ {
memcpy (this, &x, size ()); pc = from->pc;
pc = x.pc;
rabuf = NULL; rabuf = NULL;
ralen = 0; ralen = 0;
raixget = 0; raixget = 0;
raixput = 0; raixput = 0;
rabuflen = 0; rabuflen = 0;
return *this;
} }
int int
@ -462,17 +460,17 @@ fhandler_base::open_with_arch (int flags, mode_t mode)
} }
else if (archetype) else if (archetype)
{ {
if (!archetype->io_handle) if (!archetype->get_io_handle ())
{ {
usecount = 0; copyto (archetype);
*archetype = *this;
archetype_usecount (1); archetype_usecount (1);
archetype->archetype = NULL; archetype->archetype = NULL;
usecount = 0;
} }
else else
{ {
fhandler_base *arch = archetype; fhandler_base *arch = archetype;
*this = *archetype; archetype->copyto (this);
archetype = arch; archetype = arch;
archetype_usecount (1); archetype_usecount (1);
usecount = 0; usecount = 0;
@ -1259,7 +1257,7 @@ fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
} }
int int
fhandler_base::dup (fhandler_base *child) fhandler_base::dup (fhandler_base *child, int)
{ {
debug_printf ("in fhandler_base dup"); debug_printf ("in fhandler_base dup");
@ -1283,9 +1281,9 @@ fhandler_base::dup (fhandler_base *child)
} }
int 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 (); ((fhandler_base_overlapped *) child)->setup_overlapped ();
return res; return res;
} }

View File

@ -181,6 +181,7 @@ class fhandler_base
path_conv pc; path_conv pc;
void reset (const fhandler_base *);
virtual bool use_archetype () const {return false;} virtual bool use_archetype () const {return false;}
virtual void set_name (path_conv &pc); virtual void set_name (path_conv &pc);
virtual void set_name (const char *s) virtual void set_name (const char *s)
@ -194,9 +195,6 @@ class fhandler_base
int pc_binmode () const {return pc.binmode ();} int pc_binmode () const {return pc.binmode ();}
device& dev () {return pc.dev;} device& dev () {return pc.dev;}
operator DWORD& () {return (DWORD&) pc;} operator DWORD& () {return (DWORD&) pc;}
virtual size_t size () const {return sizeof (*this);}
virtual fhandler_base& operator =(fhandler_base &x);
fhandler_base (); fhandler_base ();
virtual ~fhandler_base (); virtual ~fhandler_base ();
@ -354,7 +352,7 @@ public:
virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3))); virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
virtual _off64_t lseek (_off64_t offset, int whence); virtual _off64_t lseek (_off64_t offset, int whence);
virtual int lock (int, struct __flock64 *); 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 int fpathconf (int);
virtual HANDLE mmap (caddr_t *addr, size_t len, int prot, virtual HANDLE mmap (caddr_t *addr, size_t len, int prot,
@ -427,7 +425,22 @@ public:
bool device_access_denied (int) __attribute__ ((regparm (2))); bool device_access_denied (int) __attribute__ ((regparm (2)));
int fhaccess (int flags, bool) __attribute__ ((regparm (3))); int fhaccess (int flags, bool) __attribute__ ((regparm (3)));
virtual bool __stdcall has_ongoing_io () __attribute__ ((regparm (1))) {return false;} 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 struct wsa_event
@ -552,7 +565,7 @@ class fhandler_socket: public fhandler_base
int shutdown (int how); int shutdown (int how);
int close (); int close ();
void hclose (HANDLE) {close ();} void hclose (HANDLE) {close ();}
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
void set_close_on_exec (bool val); void set_close_on_exec (bool val);
int fixup_before_fork_exec (DWORD); 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 fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3))); int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
int __stdcall link (const char *) __attribute__ ((regparm (2))); 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 class fhandler_base_overlapped: public fhandler_base
@ -615,8 +643,23 @@ public:
void fixup_after_exec (); void fixup_after_exec ();
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
virtual size_t size () const { return sizeof (*this);} /* probably not needed */
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 class fhandler_pipe: public fhandler_base_overlapped
@ -637,7 +680,7 @@ public:
select_record *select_except (select_stuff *); select_record *select_except (select_stuff *);
char *get_proc_fd_name (char *buf); char *get_proc_fd_name (char *buf);
int open (int flags, mode_t mode = 0); 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 ioctl (unsigned int cmd, void *);
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3))); 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 (fhandler_pipe *[2], unsigned, int);
static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL); static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL);
friend class fhandler_fifo; 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 class fhandler_fifo: public fhandler_base_overlapped
@ -673,14 +731,29 @@ public:
ssize_t __stdcall raw_write (const void *, size_t) __attribute__ ((regparm (3))); ssize_t __stdcall raw_write (const void *, size_t) __attribute__ ((regparm (3)));
int open (int, mode_t); int open (int, mode_t);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
bool isfifo () const { return true; } bool isfifo () const { return true; }
void set_close_on_exec (bool val); void set_close_on_exec (bool val);
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
select_record *select_read (select_stuff *); select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (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 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))); ssize_t __stdcall raw_write (const void *, size_t) __attribute__ ((regparm (3)));
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
select_record *select_read (select_stuff *); 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 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 __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); int ioctl (unsigned int cmd, void *buf);
void fixup_after_fork (HANDLE); void fixup_after_fork (HANDLE);
void fixup_after_exec (); 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 #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 open (int flags, mode_t mode = 0);
int close (); 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))); 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))); ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
_off64_t lseek (_off64_t offset, int whence); _off64_t lseek (_off64_t offset, int whence);
int ioctl (unsigned int cmd, void *buf); 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 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 __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 fixup_after_fork (HANDLE parent);
virtual void set_close_on_exec (bool val); virtual void set_close_on_exec (bool val);
virtual int ioctl (unsigned int cmd, void *buf); 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 */ /* Standard disk file */
@ -820,7 +953,7 @@ class fhandler_disk_file: public fhandler_base
int open (int flags, mode_t mode); int open (int flags, mode_t mode);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
int lock (int, struct __flock64 *); int lock (int, struct __flock64 *);
bool isdevice () const { return false; } 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 pread (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
ssize_t __stdcall pwrite (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 class fhandler_cygdrive: public fhandler_disk_file
@ -874,7 +1022,22 @@ class fhandler_cygdrive: public fhandler_disk_file
void rewinddir (DIR *); void rewinddir (DIR *);
int closedir (DIR *); int closedir (DIR *);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); 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 class fhandler_serial: public fhandler_base
@ -898,7 +1061,7 @@ class fhandler_serial: public fhandler_base
int close (); int close ();
int init (HANDLE h, DWORD a, mode_t flags); int init (HANDLE h, DWORD a, mode_t flags);
void overlapped_setup (); 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))); 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))); ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
int tcsendbreak (int); int tcsendbreak (int);
@ -922,7 +1085,22 @@ class fhandler_serial: public fhandler_base
select_record *select_read (select_stuff *); select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (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) \ #define acquire_output_mutex(ms) \
@ -935,29 +1113,33 @@ class tty;
class tty_min; class tty_min;
class fhandler_termios: public fhandler_base class fhandler_termios: public fhandler_base
{ {
protected: private:
bool opened_as_dev_tty;
HANDLE output_handle; HANDLE output_handle;
protected:
virtual void doecho (const void *, DWORD) {}; virtual void doecho (const void *, DWORD) {};
virtual int accept_input () {return 1;}; virtual int accept_input () {return 1;};
int ioctl_termios (int, int); int ioctl (int, void *);
public:
bool is_dev_tty () const { return opened_as_dev_tty; }
bool is_dev_tty (bool val) { return opened_as_dev_tty = val; }
tty_min *_tc; 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_termios () :
fhandler_base () fhandler_base ()
{ {
opened_as_dev_tty = false;
need_fork_fixup (true); need_fork_fixup (true);
last = this;
}
~fhandler_termios ()
{
if (this == last)
last = NULL;
} }
HANDLE& get_output_handle () { return output_handle; } HANDLE& get_output_handle () { return output_handle; }
line_edit_status line_edit (const char *rptr, int nread, termios&); line_edit_status line_edit (const char *rptr, int nread, termios&);
void set_output_handle (HANDLE h) { output_handle = h; } void set_output_handle (HANDLE h) { output_handle = h; }
void tcinit (bool force); void tcinit (bool force);
bool is_tty () const { return true; } bool is_tty () const { return true; }
tty *get_ttyp () { return (tty *) tc (); }
void sigflush (); void sigflush ();
int tcgetpgrp (); int tcgetpgrp ();
int tcsetpgrp (int pid); int tcsetpgrp (int pid);
@ -967,7 +1149,22 @@ class fhandler_termios: public fhandler_base
void echo_erase (int force = 0); void echo_erase (int force = 0);
virtual _off64_t lseek (_off64_t, int); virtual _off64_t lseek (_off64_t, int);
int tcgetsid (); 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 enum ansi_intensity
@ -1105,7 +1302,6 @@ private:
static bool create_invisible_console (HWINSTA); static bool create_invisible_console (HWINSTA);
static bool create_invisible_console_workaround (); static bool create_invisible_console_workaround ();
static console_state *open_shared_console (HWND, HANDLE&, bool&); static console_state *open_shared_console (HWND, HANDLE&, bool&);
tty_min *tc () const {return &(shared_console_info->tty_min_state);}
public: public:
static pid_t tc_getpgid () {return shared_console_info->tty_min_state.getpgid ();} 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); int open (int flags, mode_t mode);
void open_setup (int flags); void open_setup (int flags);
int dup (fhandler_base *, int);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
ssize_t __stdcall write (const void *ptr, size_t len); ssize_t __stdcall write (const void *ptr, size_t len);
@ -1146,11 +1343,26 @@ private:
void set_close_on_exec (bool val); void set_close_on_exec (bool val);
void set_input_state (); void set_input_state ();
void send_winch_maybe (); void send_winch_maybe ();
void get_tty_stuff (); void setup ();
bool set_unit (); bool set_unit ();
static bool need_invisible (); static bool need_invisible ();
static bool has_a () {return !invisible_console;} 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 (); 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_read (select_stuff *);
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (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 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 ioctl (unsigned int cmd, void *);
int close (); int close ();
void cleanup (); void cleanup ();
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
void fixup_after_exec (); 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 fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); 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 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. int pktmode; // non-zero if pty in a packet mode.
HANDLE master_ctl; // Control socket for handle duplication HANDLE master_ctl; // Control socket for handle duplication
cygthread *master_thread; // Master control thread cygthread *master_thread; // Master control thread
HANDLE from_master, to_master;
DWORD dwProcessId; // Owner of master handles
public: public:
int need_nl; // Next read should start with \n int need_nl; // Next read should start with \n
DWORD dwProcessId; // Owner of master handles
HANDLE from_master, to_master;
/* Constructor */ /* Constructor */
fhandler_pty_master (); fhandler_pty_master (int);
DWORD pty_master_thread (); DWORD pty_master_thread ();
int process_slave_output (char *buf, size_t len, int pktmode_on); int process_slave_output (char *buf, size_t len, int pktmode_on);
void doecho (const void *str, DWORD len); void doecho (const void *str, DWORD len);
int accept_input (); int accept_input ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
void open_setup (int flags);
ssize_t __stdcall write (const void *ptr, size_t len); ssize_t __stdcall write (const void *ptr, size_t len);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
int close (); int close ();
@ -1251,11 +1494,27 @@ public:
bool hit_eof (); bool hit_eof ();
bool setup (); bool setup ();
int dup (fhandler_base *); int dup (fhandler_base *, int);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
void fixup_after_exec (); void fixup_after_exec ();
int tcgetpgrp (); 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 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_read (select_stuff *);
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (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 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, virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
_off64_t offset, DWORD size, _off64_t offset, DWORD size,
void *address); 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 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))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
_off64_t lseek (_off64_t offset, int whence); _off64_t lseek (_off64_t offset, int whence);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
size_t size () const { return sizeof (*this);}
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 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); int msync (HANDLE h, caddr_t addr, size_t len, int flags);
bool fixup_mmap_after_fork (HANDLE h, int prot, int flags, bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
_off64_t offset, DWORD size, void *address); _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 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); _off64_t lseek (_off64_t offset, int whence);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
void fixup_after_exec (); 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 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_read (select_stuff *);
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (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 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_in ();
void close_audio_out (bool immediately = false); void close_audio_out (bool immediately = false);
bool use_archetype () const {return true;} 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 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); ssize_t __stdcall write (const void *ptr, size_t len);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
_off64_t lseek (_off64_t, int); _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 open (int flags, mode_t mode = 0);
int close (); int close ();
int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
@ -1440,7 +1804,22 @@ class fhandler_virtual : public fhandler_base
virtual bool fill_filebuf (); virtual bool fill_filebuf ();
char *get_filebuf () { return filebuf; } char *get_filebuf () { return filebuf; }
void fixup_after_exec (); 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 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 open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf (); 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 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); ssize_t __stdcall write (const void *ptr, size_t len);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf (); 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 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 open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf (); 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 class fhandler_netdrive: public fhandler_virtual
@ -1503,7 +1927,22 @@ class fhandler_netdrive: public fhandler_virtual
int closedir (DIR *); int closedir (DIR *);
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); 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 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))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf (); bool fill_filebuf ();
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, int);
size_t size () const { return sizeof (*this);}
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; class pinfo;
@ -1543,7 +1997,22 @@ class fhandler_process: public fhandler_proc
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf (); 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 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 open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf (); 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 struct fhandler_nodevice: public fhandler_base
{ {
fhandler_nodevice (); fhandler_nodevice ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
// int __stdcall fstat (struct __stat64 *buf, path_conv *);
}; };
#define report_tty_counts(fh, call, use_op) \ #define report_tty_counts(fh, call, use_op) \

View File

@ -44,7 +44,7 @@ fhandler_dev_clipboard::fhandler_dev_clipboard ()
*/ */
int int
fhandler_dev_clipboard::dup (fhandler_base * child) fhandler_dev_clipboard::dup (fhandler_base * child, int)
{ {
fhandler_dev_clipboard *fhc = (fhandler_dev_clipboard *) child; 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. */ /* Allocate and initialize the shared record for the current console. */
void void
fhandler_console::get_tty_stuff () fhandler_console::setup ()
{ {
if (set_unit ()) if (set_unit ())
{ {
@ -268,7 +268,7 @@ fhandler_console::send_winch_maybe ()
{ {
dev_state.scroll_region.Top = 0; dev_state.scroll_region.Top = 0;
dev_state.scroll_region.Bottom = -1; 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; DWORD timeout = is_nonblocking () ? 0 : INFINITE;
char tmp[60]; char tmp[60];
termios ti = tc ()->ti; termios ti = get_ttyp ()->ti;
for (;;) for (;;)
{ {
int bgres; int bgres;
@ -684,8 +684,8 @@ sig_exit:
void void
fhandler_console::set_input_state () fhandler_console::set_input_state ()
{ {
if (tc ()->rstcons ()) if (get_ttyp ()->rstcons ())
input_tcsetattr (0, &tc ()->ti); input_tcsetattr (0, &get_ttyp ()->ti);
} }
bool 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); 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 int
fhandler_console::open (int flags, mode_t) fhandler_console::open (int flags, mode_t)
{ {
@ -806,7 +813,7 @@ fhandler_console::open (int flags, mode_t)
dev_state.set_default_attr (); dev_state.set_default_attr ();
} }
tc ()->rstcons (false); get_ttyp ()->rstcons (false);
set_open_status (); set_open_status ();
DWORD cflags; DWORD cflags;
@ -825,7 +832,7 @@ fhandler_console::open_setup (int flags)
{ {
cygheap->manage_console_count ("fhandler_console::open", 1); cygheap->manage_console_count ("fhandler_console::open", 1);
set_flags ((flags & ~O_TEXT) | O_BINARY); set_flags ((flags & ~O_TEXT) | O_BINARY);
myself->set_ctty (&shared_console_info->tty_min_state, flags, this); myself->set_ctty (this, flags);
} }
int int
@ -841,7 +848,7 @@ fhandler_console::close ()
int int
fhandler_console::ioctl (unsigned int cmd, void *arg) 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) if (res <= 0)
return res; return res;
switch (cmd) switch (cmd)
@ -970,8 +977,8 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
available. We've got ECHO and ICANON, they've available. We've got ECHO and ICANON, they've
got ENABLE_ECHO_INPUT and ENABLE_LINE_INPUT. */ got ENABLE_ECHO_INPUT and ENABLE_LINE_INPUT. */
termios_printf ("this %p, tc () %p, t %p", this, tc (), t); termios_printf ("this %p, get_ttyp () %p, t %p", this, get_ttyp (), t);
tc ()->ti = *t; get_ttyp ()->ti = *t;
if (t->c_lflag & ECHO) 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); res, t, flags, t->c_lflag, t->c_iflag);
} }
tc ()->rstcons (false); get_ttyp ()->rstcons (false);
return res; return res;
} }
@ -1027,7 +1034,7 @@ int
fhandler_console::tcgetattr (struct termios *t) fhandler_console::tcgetattr (struct termios *t)
{ {
int res; int res;
*t = tc ()->ti; *t = get_ttyp ()->ti;
t->c_cflag |= CS8; t->c_cflag |= CS8;
@ -1067,8 +1074,9 @@ fhandler_console::fhandler_console (fh_devices unit) :
{ {
if (unit > 0) if (unit > 0)
dev ().parse (unit); dev ().parse (unit);
get_tty_stuff (); setup ();
trunc_buf.len = 0; trunc_buf.len = 0;
_tc = &(shared_console_info->tty_min_state);
} }
void void
@ -1866,7 +1874,7 @@ do_print:
y--; 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; break;
case BAK: case BAK:
cursor_rel (-1, 0); cursor_rel (-1, 0);
@ -2192,13 +2200,13 @@ fhandler_console::init (HANDLE h, DWORD a, mode_t bin)
if (h && h != INVALID_HANDLE_VALUE) if (h && h != INVALID_HANDLE_VALUE)
CloseHandle (h); /* Reopened by open */ CloseHandle (h); /* Reopened by open */
return !tcsetattr (0, &tc ()->ti); return !tcsetattr (0, &get_ttyp ()->ti);
} }
int int
fhandler_console::igncr_enabled () fhandler_console::igncr_enabled ()
{ {
return tc ()->ti.c_iflag & IGNCR; return get_ttyp ()->ti.c_iflag & IGNCR;
} }
void void

View File

@ -1390,11 +1390,11 @@ fhandler_disk_file::close ()
} }
int 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; 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 if (!ret && prw_handle
&& !DuplicateHandle (GetCurrentProcess (), prw_handle, && !DuplicateHandle (GetCurrentProcess (), prw_handle,
GetCurrentProcess (), &fhc->prw_handle, GetCurrentProcess (), &fhc->prw_handle,

View File

@ -303,9 +303,9 @@ fhandler_fifo::close ()
} }
int 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; fhandler_fifo *fifo_child = (fhandler_fifo *) child;
if (res == 0 && dummy_client) if (res == 0 && dummy_client)
{ {

View File

@ -405,9 +405,9 @@ fhandler_dev_floppy::close ()
} }
int 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) if (!ret && partitions)
InterlockedIncrement (&partitions->refcnt); InterlockedIncrement (&partitions->refcnt);

View File

@ -1371,7 +1371,7 @@ format_proc_devices (void *, char *&destbuf)
"%3d sd\n" "%3d sd\n"
"%3d sd\n", "%3d sd\n",
DEV_MEM_MAJOR, DEV_CONS_MAJOR, _major (FH_TTY), 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_TAPE_MAJOR, DEV_MISC_MAJOR, DEV_SOUND_MAJOR,
DEV_SERIAL_MAJOR, DEV_TTYS_MAJOR, DEV_FLOPPY_MAJOR, DEV_SERIAL_MAJOR, DEV_TTYS_MAJOR, DEV_FLOPPY_MAJOR,
DEV_SD_MAJOR, DEV_CDROM_MAJOR, DEV_SD1_MAJOR, DEV_SD_MAJOR, DEV_CDROM_MAJOR, DEV_SD1_MAJOR,

View File

@ -178,7 +178,7 @@ fhandler_dev_random::close ()
} }
int int
fhandler_dev_random::dup (fhandler_base *child) fhandler_dev_random::dup (fhandler_base *child, int)
{ {
fhandler_dev_random *fhr = (fhandler_dev_random *) child; fhandler_dev_random *fhr = (fhandler_dev_random *) child;
fhr->crypt_prov = (HCRYPTPROV)NULL; fhr->crypt_prov = (HCRYPTPROV)NULL;

View File

@ -81,9 +81,9 @@ fhandler_dev_raw::open (int flags, mode_t)
} }
int 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) if (!ret)
{ {

View File

@ -1026,12 +1026,12 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
} }
int int
fhandler_registry::dup (fhandler_base *child) fhandler_registry::dup (fhandler_base *child, int flags)
{ {
debug_printf ("here"); debug_printf ("here");
fhandler_registry *fhs = (fhandler_registry *) child; 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. /* Pseudo registry handles can't be duplicated using DuplicateHandle.
Therefore those fhandlers are marked with the nohandle flag. This Therefore those fhandlers are marked with the nohandle flag. This
allows fhandler_base::dup to succeed as usual for nohandle fhandlers. allows fhandler_base::dup to succeed as usual for nohandle fhandlers.

View File

@ -1172,9 +1172,9 @@ fhandler_serial::fixup_after_exec ()
} }
int int
fhandler_serial::dup (fhandler_base *child) fhandler_serial::dup (fhandler_base *child, int flags)
{ {
fhandler_serial *fhc = (fhandler_serial *) child; fhandler_serial *fhc = (fhandler_serial *) child;
fhc->overlapped_setup (); 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 int
fhandler_socket::dup (fhandler_base *child) fhandler_socket::dup (fhandler_base *child, int flags)
{ {
debug_printf ("here"); debug_printf ("here");
fhandler_socket *fhs = (fhandler_socket *) child; fhandler_socket *fhs = (fhandler_socket *) child;
@ -777,7 +777,7 @@ fhandler_socket::dup (fhandler_base *child)
} }
if (!need_fixup_before ()) if (!need_fixup_before ())
{ {
int ret = fhandler_base::dup (child); int ret = fhandler_base::dup (child, flags);
if (ret) if (ret)
{ {
NtClose (fhs->wsock_evt); NtClose (fhs->wsock_evt);

View File

@ -1444,7 +1444,7 @@ fhandler_dev_tape::fstat (struct __stat64 *buf)
} }
int int
fhandler_dev_tape::dup (fhandler_base *child) fhandler_dev_tape::dup (fhandler_base *child, int flags)
{ {
lock (-1); lock (-1);
fhandler_dev_tape *fh = (fhandler_dev_tape *) child; fhandler_dev_tape *fh = (fhandler_dev_tape *) child;
@ -1468,7 +1468,7 @@ fhandler_dev_tape::dup (fhandler_base *child)
__seterrno (); __seterrno ();
return unlock (-1); return unlock (-1);
} }
return unlock (fhandler_dev_raw::dup (child)); return unlock (fhandler_dev_raw::dup (child, flags));
} }
void void

View File

@ -21,6 +21,8 @@ details. */
#include "cygtls.h" #include "cygtls.h"
#include "ntdll.h" #include "ntdll.h"
fhandler_termios *fhandler_termios::last;
/* Common functions shared by tty/console */ /* Common functions shared by tty/console */
void void
@ -411,11 +413,13 @@ fhandler_termios::tcgetsid ()
} }
int int
fhandler_termios::ioctl_termios (int cmd, int arg) fhandler_termios::ioctl (int cmd, void *varg)
{ {
if (cmd != TIOCSCTTY) if (cmd != TIOCSCTTY)
return 1; /* Not handled by this function */ return 1; /* Not handled by this function */
int arg = (int) varg;
if (arg != 0 && arg != 1) if (arg != 0 && arg != 1)
{ {
set_errno (EINVAL); set_errno (EINVAL);
@ -431,6 +435,6 @@ fhandler_termios::ioctl_termios (int cmd, int arg)
} }
myself->ctty = -1; myself->ctty = -1;
myself->set_ctty (tc (), 0, this); myself->set_ctty (this, 0);
return 0; return 0;
} }

View File

@ -539,7 +539,7 @@ void
fhandler_pty_slave::open_setup (int flags) fhandler_pty_slave::open_setup (int flags)
{ {
set_flags ((flags & ~O_TEXT) | O_BINARY); set_flags ((flags & ~O_TEXT) | O_BINARY);
myself->set_ctty (get_ttyp (), flags, this); myself->set_ctty (this, flags);
cygheap->manage_console_count ("fhandler_pty_slave::open_setup", 1); cygheap->manage_console_count ("fhandler_pty_slave::open_setup", 1);
report_tty_counts (this, "opened", ""); report_tty_counts (this, "opened", "");
} }
@ -614,7 +614,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
if (bg <= bg_eof) if (bg <= bg_eof)
return (ssize_t) bg; 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); push_process_state process_state (PID_TTYOU);
@ -891,15 +891,16 @@ out:
} }
int 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); cygheap->manage_console_count ("fhandler_pty_slave::dup", 1);
report_tty_counts (child, "duped slave", ""); report_tty_counts (child, "duped slave", "");
return 0; return 0;
} }
int int
fhandler_pty_master::dup (fhandler_base *child) fhandler_pty_master::dup (fhandler_base *child, int)
{ {
report_tty_counts (child, "duped master", ""); report_tty_counts (child, "duped master", "");
return 0; return 0;
@ -947,7 +948,7 @@ int
fhandler_pty_slave::ioctl (unsigned int cmd, void *arg) fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
{ {
termios_printf ("ioctl (%x)", cmd); termios_printf ("ioctl (%x)", cmd);
int res = ioctl_termios (cmd, (int) arg); int res = fhandler_termios::ioctl (cmd, arg);
if (res <= 0) if (res <= 0)
return res; return res;
@ -1184,37 +1185,34 @@ errout:
/******************************************************* /*******************************************************
fhandler_pty_master fhandler_pty_master
*/ */
fhandler_pty_master::fhandler_pty_master () fhandler_pty_master::fhandler_pty_master (int unit)
: fhandler_pty_common (), pktmode (0), need_nl (0), dwProcessId (0) : 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 int
fhandler_pty_master::open (int flags, mode_t) fhandler_pty_master::open (int flags, mode_t)
{ {
/* Note that allocate returns with the tty lock set if it was successful. */
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 (); set_open_status ();
dwProcessId = GetCurrentProcessId (); 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; 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 _off64_t
fhandler_pty_common::lseek (_off64_t, int) fhandler_pty_common::lseek (_off64_t, int)
{ {
@ -1225,7 +1223,7 @@ fhandler_pty_common::lseek (_off64_t, int)
int int
fhandler_pty_common::close () 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)) if (!ForceCloseHandle (input_mutex))
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex); termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
if (!ForceCloseHandle (output_mutex)) if (!ForceCloseHandle (output_mutex))
@ -1245,6 +1243,8 @@ void
fhandler_pty_master::cleanup () fhandler_pty_master::cleanup ()
{ {
report_tty_counts (this, "closing master", ""); report_tty_counts (this, "closing master", "");
if (archetype)
from_master = to_master = NULL;
} }
int int
@ -1272,11 +1272,14 @@ fhandler_pty_master::close ()
CloseHandle (master_ctl); CloseHandle (master_ctl);
master_thread->detach (); master_thread->detach ();
} }
}
if (!ForceCloseHandle (from_master)) if (!ForceCloseHandle (from_master))
termios_printf ("error closing from_master %p, %E", from_master); termios_printf ("error closing from_master %p, %E", from_master);
if (!ForceCloseHandle (to_master)) if (!ForceCloseHandle (to_master))
termios_printf ("error closing from_master %p, %E", to_master); termios_printf ("error closing from_master %p, %E", to_master);
} from_master = to_master = NULL;
fhandler_pty_common::close (); fhandler_pty_common::close ();
if (hExeced || get_ttyp ()->master_pid != myself->pid) if (hExeced || get_ttyp ()->master_pid != myself->pid)
@ -1287,6 +1290,15 @@ fhandler_pty_master::close ()
return 0; 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 ssize_t __stdcall
fhandler_pty_master::write (const void *ptr, size_t len) fhandler_pty_master::write (const void *ptr, size_t len)
{ {
@ -1361,7 +1373,7 @@ fhandler_pty_master::tcflush (int queue)
int int
fhandler_pty_master::ioctl (unsigned int cmd, void *arg) 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) if (res <= 0)
return res; return res;
@ -1408,7 +1420,7 @@ fhandler_pty_master::ptsname ()
{ {
static char buf[TTY_NAME_MAX]; static char buf[TTY_NAME_MAX];
__small_sprintf (buf, "/dev/tty%d", get_unit ()); __small_sprintf (buf, "/dev/pty%d", get_unit ());
return buf; return buf;
} }
@ -1587,32 +1599,27 @@ fhandler_pty_master::setup ()
security_descriptor sd; security_descriptor sd;
SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE }; SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE };
tty& t = *cygwin_shared->tty[get_unit ()]; /* Find an unallocated pty to use. */
_tc = (tty_min *)&t; 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. */ tcinit (true); /* Set termios information. Force initialization. */
const char *errstr = NULL; const char *errstr = NULL;
DWORD pipe_mode = PIPE_NOWAIT; 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)) if (!SetNamedPipeHandleState (get_output_handle (), &pipe_mode, NULL, NULL))
termios_printf ("can't set output_handle(%p) to non-blocking mode", termios_printf ("can't set output_handle(%p) to non-blocking mode",
get_output_handle ()); get_output_handle ());
__small_sprintf (pipename, "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 (), res = fhandler_pipe::create_selectable (&sec_none, get_io_handle (),
to_master, 128 * 1024, pipename); to_master, 128 * 1024, pipename);
if (res) if (res)
@ -1622,7 +1629,6 @@ fhandler_pty_master::setup ()
} }
ProtectHandle1 (get_io_handle (), from_pty); ProtectHandle1 (get_io_handle (), from_pty);
need_nl = 0;
/* Create security attribute. Default permissions are 0620. */ /* Create security attribute. Default permissions are 0620. */
sd.malloc (sizeof (SECURITY_DESCRIPTOR)); sd.malloc (sizeof (SECURITY_DESCRIPTOR));
@ -1642,18 +1648,18 @@ fhandler_pty_master::setup ()
goto err; goto err;
char buf[MAX_PATH]; 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))) if (!(output_mutex = CreateMutex (&sa, FALSE, buf)))
goto err; 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))) if (!(input_mutex = CreateMutex (&sa, FALSE, buf)))
goto err; goto err;
/* Create master control pipe which allows the master to duplicate /* Create master control pipe which allows the master to duplicate
the pty pipe handles to processes which deserve it. */ the pty pipe handles to processes which deserve it. */
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", __small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
&installation_key, get_unit ()); &installation_key, unit);
master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX, master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX,
PIPE_WAIT | PIPE_TYPE_MESSAGE PIPE_WAIT | PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE, 1, 4096, 4096, | PIPE_READMODE_MESSAGE, 1, 4096, 4096,
@ -1676,7 +1682,9 @@ fhandler_pty_master::setup ()
t.winsize.ws_row = 25; t.winsize.ws_row = 25;
t.master_pid = myself->pid; 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 ()); get_io_handle (), get_output_handle ());
return true; return true;
@ -1690,8 +1698,7 @@ err:
close_maybe (from_master); close_maybe (from_master);
close_maybe (to_master); close_maybe (to_master);
close_maybe (master_ctl); close_maybe (master_ctl);
termios_printf ("tty%d open failed - failed to create %s", t.get_unit (), termios_printf ("pty%d open failed - failed to create %s", unit, errstr);
errstr);
return false; return false;
} }

View File

@ -152,9 +152,9 @@ fhandler_virtual::lseek (_off64_t offset, int whence)
} }
int 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) if (!ret)
{ {

View File

@ -1118,6 +1118,12 @@ out:
if (saw_symlinks) if (saw_symlinks)
set_has_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 ((opt & PC_POSIX))
{ {
if (tail < path_end && tail > path_copy + 1) if (tail < path_end && tail > path_copy + 1)

View File

@ -51,6 +51,8 @@ enum pathconv_arg
PC_NULLEMPTY = 0x0020, PC_NULLEMPTY = 0x0020,
PC_POSIX = 0x0080, PC_POSIX = 0x0080,
PC_NOWARN = 0x0100, PC_NOWARN = 0x0100,
PC_OPEN = 0x0200, /* use open semantics */
PC_CTTY = 0x0400, /* could later be used as ctty */
PC_KEEP_HANDLE = 0x00400000, PC_KEEP_HANDLE = 0x00400000,
PC_NO_ACCESS_CHECK = 0x00800000 PC_NO_ACCESS_CHECK = 0x00800000
}; };
@ -74,6 +76,8 @@ enum path_types
PATH_IHASH = MOUNT_IHASH, PATH_IHASH = MOUNT_IHASH,
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC), PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK, 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_LNK = 0x01000000,
PATH_TEXT = 0x02000000, PATH_TEXT = 0x02000000,
PATH_REP = 0x04000000, PATH_REP = 0x04000000,
@ -111,7 +115,7 @@ public:
CloseHandle (hdl); CloseHandle (hdl);
set (NULL); set (NULL);
} }
inline void dup (path_conv_handle &pch) inline void dup (const path_conv_handle &pch)
{ {
if (!DuplicateHandle (GetCurrentProcess (), pch.handle (), if (!DuplicateHandle (GetCurrentProcess (), pch.handle (),
GetCurrentProcess (), &hdl, GetCurrentProcess (), &hdl,
@ -175,6 +179,8 @@ class path_conv
int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();} int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
int issocket () const {return dev.is_device (FH_UNIX);} int issocket () const {return dev.is_device (FH_UNIX);}
int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;} 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) void set_cygexec (bool isset)
{ {
if (isset) if (isset)
@ -276,7 +282,7 @@ class path_conv
PWCHAR get_wide_win32_path (PWCHAR wc); PWCHAR get_wide_win32_path (PWCHAR wc);
operator DWORD &() {return fileattr;} operator DWORD &() {return fileattr;}
operator int () {return fileattr; } operator int () {return fileattr; }
path_conv &operator =(path_conv& pc) path_conv &operator =(const path_conv& pc)
{ {
memcpy (this, &pc, sizeof pc); memcpy (this, &pc, sizeof pc);
path = cstrdup (pc.path); path = cstrdup (pc.path);

View File

@ -372,13 +372,14 @@ _pinfo::_ctty (char *buf)
return buf; return buf;
} }
void bool
_pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *fh) _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); tty_min& tc = *fh->tc ();
if ((ctty <= 0 || ctty == tc->ntty) && !(flags & O_NOCTTY)) 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) if (cygheap->ctty != fh->archetype)
{ {
debug_printf ("cygheap->ctty %p, archetype %p", 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; lock_ttys here;
syscall_printf ("attaching %s sid %d, pid %d, pgid %d, tty->pgid %d, tty->sid %d", 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 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->pgid = tc.getpgid ();
myself->sid = tc->getsid (); myself->sid = tc.getsid ();
} }
pinfo p (tc->getsid ()); pinfo p (tc.getsid ());
if (sid == pid && (!p || p->pid == pid || !p->exists ())) if (sid == pid && (!p || p->pid == pid || !p->exists ()))
{ {
#ifdef DEBUGGING #ifdef DEBUGGING
debug_printf ("resetting %s sid. Was %d, now %d. pgid was %d, now %d.", 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 #else
paranoid_printf ("resetting %s sid. Was %d, now %d. pgid was %d, now %d.", 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 #endif
/* We are the session leader */ /* We are the session leader */
tc->setsid (sid); tc.setsid (sid);
tc->setpgid (pgid); tc.setpgid (pgid);
} }
else else
sid = tc->getsid (); sid = tc.getsid ();
if (tc->getpgid () == 0) if (tc.getpgid () == 0)
tc->setpgid (pgid); 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. /* Test to determine if a process really exists and is processing signals.

View File

@ -110,7 +110,7 @@ public:
char *root (size_t &); char *root (size_t &);
char *cwd (size_t &); char *cwd (size_t &);
char *cmdline (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))); HANDLE dup_proc_pipe (HANDLE) __attribute__ ((regparm(2)));
void sync_proc_pipe (); void sync_proc_pipe ();
bool alert_parent (char); bool alert_parent (char);

View File

@ -86,10 +86,10 @@ fhandler_pipe::open (int flags, mode_t mode)
set_errno (EACCES); set_errno (EACCES);
return 0; return 0;
} }
*this = *(fhandler_pipe *) cfd; cfd->copyto (this);
set_io_handle (NULL); set_io_handle (NULL);
pc.reset_conv_handle (); pc.reset_conv_handle ();
if (!cfd->dup (this)) if (!cfd->dup (this, flags))
return 1; return 1;
return 0; return 0;
} }
@ -172,13 +172,13 @@ fhandler_pipe::get_proc_fd_name (char *buf)
} }
int int
fhandler_pipe::dup (fhandler_base *child) fhandler_pipe::dup (fhandler_base *child, int flags)
{ {
fhandler_pipe *ftp = (fhandler_pipe *) child; fhandler_pipe *ftp = (fhandler_pipe *) child;
ftp->set_popen_pid (0); ftp->set_popen_pid (0);
int res; int res;
if (get_handle () && fhandler_base_overlapped::dup (child)) if (get_handle () && fhandler_base_overlapped::dup (child, flags))
res = -1; res = -1;
else else
res = 0; 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 change in behavior that implements linux functionality: opening
a tty should not automatically cause it to become the controlling a tty should not automatically cause it to become the controlling
tty for the process. */ tty for the process. */
if (0 && fd > 2) int opt = PC_OPEN | ((flags & (O_NOFOLLOW | O_EXCL))
? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW);
if (!(flags & O_NOCTTY)&& fd > 2)
{
flags |= O_NOCTTY; flags |= O_NOCTTY;
if (!(fh = build_fh_name (unix_path, opt |= PC_CTTY; /* flag that, if opened, this fhandler could
(flags & (O_NOFOLLOW | O_EXCL)) later be capable of being a controlling
? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW, terminal if /dev/tty is opened. */
stat_suffixes))) }
if (!(fh = build_fh_name (unix_path, opt, stat_suffixes)))
res = -1; // errno already set res = -1; // errno already set
else if ((flags & O_NOFOLLOW) && fh->issymlink ()) else if ((flags & O_NOFOLLOW) && fh->issymlink ())
{ {
@ -1600,10 +1604,9 @@ stat_worker (path_conv &pc, struct __stat64 *buf)
if (!buf->st_ino) if (!buf->st_ino)
buf->st_ino = fh->get_ino (); buf->st_ino = fh->get_ino ();
if (!buf->st_dev) 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) if (!buf->st_rdev)
buf->st_rdev = buf->st_dev; 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; delete fh;
} }
@ -1620,7 +1623,8 @@ extern "C" int
stat64 (const char *name, struct __stat64 *buf) stat64 (const char *name, struct __stat64 *buf)
{ {
syscall_printf ("entering"); 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); return stat_worker (pc, buf);
} }

View File

@ -102,7 +102,7 @@ tty_list::connect (int ttynum)
} }
if (!ttys[ttynum].exists ()) if (!ttys[ttynum].exists ())
{ {
termios_printf ("tty %d was not allocated", ttynum); termios_printf ("pty %d was not allocated", ttynum);
set_errno (ENXIO); set_errno (ENXIO);
return -1; return -1;
} }
@ -124,14 +124,14 @@ tty_list::init ()
Return tty number or -1 if error. Return tty number or -1 if error.
*/ */
int int
tty_list::allocate () tty_list::allocate (HANDLE& r, HANDLE& w)
{ {
lock_ttys here; lock_ttys here;
int freetty = -1; int freetty = -1;
tty *t = NULL; tty *t = NULL;
for (int i = 0; i < NTTYS; i++) for (int i = 0; i < NTTYS; i++)
if (!ttys[i].exists ()) if (ttys[i].not_allocated (r, w))
{ {
t = ttys + i; t = ttys + i;
t->init (); t->init ();
@ -140,38 +140,46 @@ tty_list::allocate ()
break; break;
} }
if (freetty < 0) if (freetty >= 0)
system_printf ("No tty allocated"); termios_printf ("pty%d allocated", freetty);
else else
{ {
termios_printf ("tty%d allocated", freetty); system_printf ("No pty allocated");
here.dont_release (); /* exit with mutex still held -- caller has more work to do */ r = w = NULL;
} }
return freetty; 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 bool
tty::exists () 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; HANDLE r, w;
int res = fhandler_pipe::create_selectable (&sec_none_nih, r, w, 0, pipename); bool res;
if (res) if (!not_allocated (r, w))
return true; res = true;
else
{
/* Handles are left open when not_allocated finds a non-open "tty" */
CloseHandle (r); CloseHandle (r);
CloseHandle (w); CloseHandle (w);
res = false;
HANDLE h = open_output_mutex (READ_CONTROL);
if (h)
{
CloseHandle (h);
return true;
} }
return slave_alive (); debug_printf ("exists %d", res);
return res;
} }
bool bool

View File

@ -14,7 +14,7 @@ details. */
#define INP_BUFFER_SIZE 256 #define INP_BUFFER_SIZE 256
#define OUT_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)) #define real_tty_attached(p) ((p)->ctty >= 0 && !iscons_dev ((p)->ctty))
/* Input/Output/ioctl events */ /* Input/Output/ioctl events */
@ -107,6 +107,7 @@ public:
inline HANDLE open_input_mutex (ACCESS_MASK access) inline HANDLE open_input_mutex (ACCESS_MASK access)
{ return open_mutex (INPUT_MUTEX, access); } { return open_mutex (INPUT_MUTEX, access); }
bool exists (); bool exists ();
bool not_allocated (HANDLE&, HANDLE&);
void set_master_closed () {master_pid = -1;} void set_master_closed () {master_pid = -1;}
static void __stdcall create_master (int); static void __stdcall create_master (int);
static void __stdcall init_session (); static void __stdcall init_session ();
@ -120,7 +121,7 @@ class tty_list
public: public:
tty * operator [](int n) {return ttys + device::minor (n);} tty * operator [](int n) {return ttys + device::minor (n);}
int allocate (); /* allocate a pty */ int allocate (HANDLE& r, HANDLE& w); /* allocate a pty */
int connect (int); int connect (int);
void init (); void init ();
tty_min *get_cttyp (); tty_min *get_cttyp ();