* cygheap.cc (cygheap::close_ctty): Close ctty via close_with_arch().

* debug.cc (close_handle): Call debugger on failure.
* devices.in (device::tty_to_real_device): Delete.
* devices.h (device::tty_to_real_device): Ditto.
* devices.cc: Regenerate.
* dtable.cc: Delete old ifdef'ed vfork code.
(dtable::release): Don't handle archetype here.
(dtable::init_std_file_from_handle): Consolidate console tests.  Generate
major/minor for tty ASAP.  Fix incorrect setting of DEV_TTYS* for serial.
(fh_alloc): New function derived from build_fh_pc.  Pass current tty when
building tty.
(build_pc_pc): Use fh_alloc to create.  Set name from fh->dev if appropriate.
Generate an archetype or point to one here.
(dtable::dup_worker): Deal with archetypes.  Rely on = operator copying whole
class rather than just fhandler_base.
(dtable::fixup_after_exec): Call close_with_arch to handle closing of fhandlers
with archetypes.
* fhandler.cc (fhandler_base::operator =): Call memcpy with fhandler's size()
rather than sizeof fhandler_base.
(fhandler_base::open_with_arch): New function.  Handles opening of fhandler's
with archetypes, dealing with usecounts, etc.
(fhandler_base::close_with_arch): Ditto for close.
* fhandler.h: Many changes for archetypes.
(fhandler_base::set_name): Set both normalized path and regular path.
(fhandler_base::open_with_arch): New function.
(fhandler_base::open_setup): Ditto.
(fhandler_base::use_archetype): Ditto.
(fhandler_base::_archetype_usecount): Ditto.
(fhandler_*::size): Ditto.
(fhandler_dev_tape::open): Remove virtual decoration.
(fhandler_console::use_archetype): New function.  Return true.
(fhandler_console::open_setup): New function.
(fhandler_console::dup): Delete.
(fhandler_tty_slave::fhandler_tty_slave): Redeclare to take an argument.
(fhandler_tty_slave::use_archetype): New function.  Return true.
(fhandler_tty_slave::cleanup): New function.
(fhandler_pty_master::use_archetype): New function.  Return true.
(fhandler_pty_master::cleanup): New function.
(fhandler_pty_master::is_tty_master): New function.  Return false.
(fhandler_tty_master::is_tty_master): New function.  Return true.
(fhandler_dev_dsp::fhandler_dev_dsp): New function.  Return true.
(report_tty_counts): Only report on archetype's usecount if there is one.
* fhandler_console.cc (fhandler_console::get_tty_stuff): Remove handling of
setsid, set_ctty, set_flags, and manage_console_count.
(fhandler_console::open_setup): New function.  Implement functionality removed
from get_tty_stuff.
(fhandler_console::dup): Delete.
(fhandler_console::output_tcsetattr): Set errno on error.
(fhandler_console::fhandler_console): Set device early.
(fhandler_console::init): Use open_with_arch to open console handles.
(fhandler_console::fixup_after_fork_exec): Nuke most of the stuff for dealing
with console handles.
* fhandler_dsp.cc (fhandler_dev_dsp::open): Remove archetype handling.
(fhandler_dev_dsp::write): Ditto.
(fhandler_dev_dsp::read): Ditto.
(fhandler_dev_dsp::close): Ditto.
(fhandler_dev_dsp::dup): Ditto.
(fhandler_dev_dsp::ioctl): Ditto.
(fhandler_dev_dsp::fixup_after_fork): Ditto.
(fhandler_dev_dsp::fixup_after_exec): Ditto.
* fhandler_tty.cc (fhandler_tty_common::__acquire_output_mutex): Add a little
more debugging.
(fhandler_tty_common::__release_output_mutex): Ditto.
(fhandler_pty_master::process_slave_output): Ditto.  Don't do signal handling
or pthread_cancel handling in the tty master thread.
(process_output): Minor reorg.
(fhandler_tty_slave::fhandler_tty_slave): Set device based on new ntty
argument.
(fhandler_tty_slave::open): Remove archetype handling.  Move some processing
into open_setup().
(fhandler_tty_slave::open_setup): New function.
(fhandler_tty_slave::cleanup): New function.
(fhandler_tty_slave::close): Remove archetype handling.  Move some processing
into cleanup().
(fhandler_tty_slave::init): Rename argument from f to h.  Open device using
open_with_arch().  Remove archetype handling.
(fhandler_pty_master::dup): Ditto.
(fhandler_pty_master::open): Ditto.
(fhandler_pty_master::close): Ditto.  Move some handling to cleanup().
(fhandler_pty_master::cleanup): New function.
(fhandler_tty_master::init_console): Give unique name to captive console
fhandler.
* pinfo.cc (_pinfo::set_ctty): Rename argument from arch to fh.  Eliminate
archetype assumption.
* syscalls.cc (close_all_files): Use close_with_arch for closing.
(open): Use open_with_arch() rather than open().
(close): Use close_with_arch() rather than close().
This commit is contained in:
Christopher Faylor 2011-05-05 22:30:53 +00:00
parent d8ff96389f
commit 92ddb74290
14 changed files with 408 additions and 406 deletions

View File

@ -1,3 +1,96 @@
2011-05-05 Christopher Faylor <me.cygwin2011@cgf.cx>
* cygheap.cc (cygheap::close_ctty): Close ctty via close_with_arch().
* debug.cc (close_handle): Call debugger on failure.
* devices.in (device::tty_to_real_device): Delete.
* devices.h (device::tty_to_real_device): Ditto.
* devices.cc: Regenerate.
* dtable.cc: Delete old ifdef'ed vfork code.
(dtable::release): Don't handle archetype here.
(dtable::init_std_file_from_handle): Consolidate console tests.
Generate major/minor for tty ASAP. Fix incorrect setting of DEV_TTYS*
for serial.
(fh_alloc): New function derived from build_fh_pc. Pass current tty
when building tty.
(build_pc_pc): Use fh_alloc to create. Set name from fh->dev if
appropriate. Generate an archetype or point to one here.
(dtable::dup_worker): Deal with archetypes. Rely on = operator copying
whole class rather than just fhandler_base.
(dtable::fixup_after_exec): Call close_with_arch to handle closing of
fhandlers with archetypes.
* fhandler.cc (fhandler_base::operator =): Call memcpy with fhandler's
size() rather than sizeof fhandler_base.
(fhandler_base::open_with_arch): New function. Handles opening of
fhandler's with archetypes, dealing with usecounts, etc.
(fhandler_base::close_with_arch): Ditto for close.
* fhandler.h: Many changes for archetypes.
(fhandler_base::set_name): Set both normalized path and regular path.
(fhandler_base::open_with_arch): New function.
(fhandler_base::open_setup): Ditto.
(fhandler_base::use_archetype): Ditto.
(fhandler_base::_archetype_usecount): Ditto.
(fhandler_*::size): Ditto.
(fhandler_dev_tape::open): Remove virtual decoration.
(fhandler_console::use_archetype): New function. Return true.
(fhandler_console::open_setup): New function.
(fhandler_console::dup): Delete.
(fhandler_tty_slave::fhandler_tty_slave): Redeclare to take an
argument.
(fhandler_tty_slave::use_archetype): New function. Return true.
(fhandler_tty_slave::cleanup): New function.
(fhandler_pty_master::use_archetype): New function. Return true.
(fhandler_pty_master::cleanup): New function.
(fhandler_pty_master::is_tty_master): New function. Return false.
(fhandler_tty_master::is_tty_master): New function. Return true.
(fhandler_dev_dsp::fhandler_dev_dsp): New function. Return true.
(report_tty_counts): Only report on archetype's usecount if there is
one.
* fhandler_console.cc (fhandler_console::get_tty_stuff): Remove
handling of setsid, set_ctty, set_flags, and manage_console_count.
(fhandler_console::open_setup): New function. Implement functionality
removed from get_tty_stuff.
(fhandler_console::dup): Delete.
(fhandler_console::output_tcsetattr): Set errno on error.
(fhandler_console::fhandler_console): Set device early.
(fhandler_console::init): Use open_with_arch to open console handles.
(fhandler_console::fixup_after_fork_exec): Nuke most of the stuff for
dealing with console handles.
* fhandler_dsp.cc (fhandler_dev_dsp::open): Remove archetype handling.
(fhandler_dev_dsp::write): Ditto.
(fhandler_dev_dsp::read): Ditto.
(fhandler_dev_dsp::close): Ditto.
(fhandler_dev_dsp::dup): Ditto.
(fhandler_dev_dsp::ioctl): Ditto.
(fhandler_dev_dsp::fixup_after_fork): Ditto.
(fhandler_dev_dsp::fixup_after_exec): Ditto.
* fhandler_tty.cc (fhandler_tty_common::__acquire_output_mutex): Add a
little more debugging.
(fhandler_tty_common::__release_output_mutex): Ditto.
(fhandler_pty_master::process_slave_output): Ditto. Don't do signal
handling or pthread_cancel handling in the tty master thread.
(process_output): Minor reorg.
(fhandler_tty_slave::fhandler_tty_slave): Set device based on new ntty
argument.
(fhandler_tty_slave::open): Remove archetype handling. Move some
processing into open_setup().
(fhandler_tty_slave::open_setup): New function.
(fhandler_tty_slave::cleanup): New function.
(fhandler_tty_slave::close): Remove archetype handling. Move some
processing into cleanup().
(fhandler_tty_slave::init): Rename argument from f to h. Open device
using open_with_arch(). Remove archetype handling.
(fhandler_pty_master::dup): Ditto.
(fhandler_pty_master::open): Ditto.
(fhandler_pty_master::close): Ditto. Move some handling to cleanup().
(fhandler_pty_master::cleanup): New function.
(fhandler_tty_master::init_console): Give unique name to captive
console fhandler.
* pinfo.cc (_pinfo::set_ctty): Rename argument from arch to fh.
Eliminate archetype assumption.
* syscalls.cc (close_all_files): Use close_with_arch for closing.
(open): Use open_with_arch() rather than open().
(close): Use close_with_arch() rather than close().
2011-05-05 Corinna Vinschen <corinna@vinschen.de> 2011-05-05 Corinna Vinschen <corinna@vinschen.de>
* pinfo.h (class push_process_state): New class to push a process state * pinfo.h (class push_process_state): New class to push a process state

View File

@ -107,11 +107,7 @@ void
init_cygheap::close_ctty () init_cygheap::close_ctty ()
{ {
debug_printf ("closing cygheap->ctty %p", cygheap->ctty); debug_printf ("closing cygheap->ctty %p", cygheap->ctty);
/* FIXME: Support for console-as-ctty is limited due to the fact that cygheap->ctty->close_with_arch ();
the console doesn't use archetypes - even though they could and should */
if (cygheap->ctty->get_ttyp ()
&& cygheap->ctty->get_ttyp ()->ntty != TTY_CONSOLE)
cygheap->ctty->close ();
cygheap->ctty = NULL; cygheap->ctty = NULL;
} }

View File

@ -226,7 +226,10 @@ close_handle (const char *func, int ln, HANDLE h, const char *name, bool force)
ret = CloseHandle (h); ret = CloseHandle (h);
if (!ret) if (!ret)
small_printf ("CloseHandle(%s<%p>) failed %s:%d, %E\n", name, h, func, ln); {
system_printf ("CloseHandle(%s<%p>) failed %s:%d, %E", name, h, func, ln);
try_to_debug ();
}
return ret; return ret;
} }
#endif /*DEBUGGING*/ #endif /*DEBUGGING*/

View File

@ -43439,15 +43439,6 @@ device::parse (_dev_t dev)
parse (_major (dev), _minor (dev)); parse (_major (dev), _minor (dev));
} }
void
device::tty_to_real_device ()
{
if (!real_tty_attached (myself))
*this = myself->ctty < 0 ? dev_bad_storage : *console_dev;
else
parse (DEV_TTYS_MAJOR, myself->ctty);
}
void void
device::parsedisk (int drive, int part) device::parsedisk (int drive, int part)
{ {

View File

@ -268,7 +268,6 @@ struct device
return true; return true;
} }
static void init (); static void init ();
void tty_to_real_device ();
inline operator int () const {return devn;} inline operator int () const {return devn;}
inline void setfs (bool x) {dev_on_fs = x;} inline void setfs (bool x) {dev_on_fs = x;}
inline bool isfs () const {return dev_on_fs || devn == FH_FS;} inline bool isfs () const {return dev_on_fs || devn == FH_FS;}

View File

@ -146,15 +146,6 @@ device::parse (_dev_t dev)
parse (_major (dev), _minor (dev)); parse (_major (dev), _minor (dev));
} }
void
device::tty_to_real_device ()
{
if (!real_tty_attached (myself))
*this = myself->ctty < 0 ? dev_bad_storage : *console_dev;
else
parse (DEV_TTYS_MAJOR, myself->ctty);
}
void void
device::parsedisk (int drive, int part) device::parsedisk (int drive, int part)
{ {

View File

@ -245,10 +245,7 @@ dtable::release (int fd)
{ {
if (fds[fd]->need_fixup_before ()) if (fds[fd]->need_fixup_before ())
dec_need_fixup_before (); dec_need_fixup_before ();
fhandler_base *arch = fds[fd]->archetype;
delete fds[fd]; delete fds[fd];
if (arch && !arch->usecount)
cygheap->fdtab.delete_archetype (arch);
fds[fd] = NULL; fds[fd] = NULL;
} }
} }
@ -309,25 +306,20 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
else else
dev = *pipew_dev; dev = *pipew_dev;
} }
else if (GetConsoleScreenBufferInfo (handle, &buf)) else if (GetConsoleScreenBufferInfo (handle, &buf)
|| GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
{ {
/* Console output */ /* Console I/O */
if (ISSTATE (myself, PID_USETTY)) if (!ISSTATE (myself, PID_USETTY))
dev.parse (FH_TTY);
else
dev = *console_dev; dev = *console_dev;
} else if (myself->ctty >= 0)
else if (GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf)) dev.parse (DEV_TTYS_MAJOR, myself->ctty);
{
/* Console input */
if (ISSTATE (myself, PID_USETTY))
dev.parse (FH_TTY);
else else
dev = *console_dev; dev.parse (FH_TTY);
} }
else if (GetCommState (handle, &dcb)) else if (GetCommState (handle, &dcb))
/* serial */ /* FIXME: Not right - assumes ttyS0 */
dev.parse (DEV_TTYS_MAJOR, 0); dev.parse (DEV_SERIAL_MAJOR, 0);
else else
/* Try to figure it out from context - probably a disk file */ /* Try to figure it out from context - probably a disk file */
handle_to_fn (handle, name); handle_to_fn (handle, name);
@ -434,15 +426,15 @@ build_fh_dev (const device& dev, const char *unix_name)
} }
#define fh_unset ((fhandler_base *) 1) #define fh_unset ((fhandler_base *) 1)
fhandler_base * static fhandler_base *
build_fh_pc (path_conv& pc, bool set_name) fh_alloc (device dev)
{ {
fhandler_base *fh = fh_unset; fhandler_base *fh = fh_unset;
switch (pc.dev.major) switch (dev.major)
{ {
case DEV_TTYS_MAJOR: case DEV_TTYS_MAJOR:
fh = cnew (fhandler_tty_slave) (); fh = cnew (fhandler_tty_slave) (dev.minor);
break; break;
case DEV_TTYM_MAJOR: case DEV_TTYM_MAJOR:
fh = cnew (fhandler_tty_master) (); fh = cnew (fhandler_tty_master) ();
@ -469,7 +461,7 @@ build_fh_pc (path_conv& pc, bool set_name)
fh = cnew (fhandler_serial) (); fh = cnew (fhandler_serial) ();
break; break;
default: default:
switch (pc.dev) switch (dev)
{ {
case FH_CONSOLE: case FH_CONSOLE:
case FH_CONIN: case FH_CONIN:
@ -548,8 +540,8 @@ build_fh_pc (path_conv& pc, bool set_name)
{ {
if (myself->ctty == TTY_CONSOLE) if (myself->ctty == TTY_CONSOLE)
fh = cnew (fhandler_console) (); fh = cnew (fhandler_console) ();
else if (myself->ctty >= 0) else
fh = cnew (fhandler_tty_slave) (); fh = cnew (fhandler_tty_slave) (myself->ctty);
break; break;
} }
case FH_KMSG: case FH_KMSG:
@ -560,12 +552,34 @@ build_fh_pc (path_conv& pc, bool set_name)
if (fh == fh_unset) if (fh == fh_unset)
fh = cnew (fhandler_nodevice) (); fh = cnew (fhandler_nodevice) ();
return fh;
}
fhandler_base *
build_fh_pc (path_conv& pc, bool set_name)
{
fhandler_base *fh = fh_alloc (pc.dev);
if (!fh) if (!fh)
set_errno (EMFILE); set_errno (EMFILE);
else if (fh->dev () != FH_BAD)
fh->set_name (fh->dev ().name);
else if (set_name) else if (set_name)
fh->set_name (pc); fh->set_name (pc);
if (!fh->use_archetype ())
/* doesn't use archetypes */;
else if ((fh->archetype = cygheap->fdtab.find_archetype (fh->dev ())))
debug_printf ("found an archetype for %s(%d/%d)", fh->get_name (), fh->dev ().major, fh->dev ().minor);
else
{
debug_printf ("creating an archetype for %s(%d/%d)", fh->get_name (), fh->dev ().major, fh->dev ().minor);
fh->archetype = fh_alloc (fh->pc.dev);
*fh->archetype = *fh;
fh->archetype->archetype = NULL;
*cygheap->fdtab.add_archetype () = fh->archetype;
}
debug_printf ("fh %p", fh); debug_printf ("fh %p", fh);
return fh; return fh;
} }
@ -582,7 +596,8 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
else else
{ {
*newfh = *oldfh; *newfh = *oldfh;
newfh->set_io_handle (NULL); if (!oldfh->archetype)
newfh->set_io_handle (NULL);
newfh->pc.reset_conv_handle (); newfh->pc.reset_conv_handle ();
if (oldfh->dup (newfh)) if (oldfh->dup (newfh))
{ {
@ -592,11 +607,10 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
} }
else else
{ {
newfh->usecount = 0;
newfh->archetype_usecount (1);
/* The O_CLOEXEC flag enforces close-on-exec behaviour. */ /* The O_CLOEXEC flag enforces close-on-exec behaviour. */
if (flags & O_CLOEXEC) newfh->set_close_on_exec (!!(flags & O_CLOEXEC));
newfh->set_close_on_exec (true);
else
newfh->close_on_exec (false);
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 ());
} }
} }
@ -754,7 +768,7 @@ dtable::fixup_after_exec ()
if (fh->archetype) if (fh->archetype)
{ {
debug_printf ("closing fd %d since it is an archetype", i); debug_printf ("closing fd %d since it is an archetype", i);
fh->close (); fh->close_with_arch ();
} }
release (i); release (i);
} }
@ -786,102 +800,6 @@ dtable::fixup_after_fork (HANDLE parent)
} }
} }
#ifdef NEWVFORK
int
dtable::vfork_child_dup ()
{
fhandler_base **newtable;
lock ();
newtable = (fhandler_base **) ccalloc (HEAP_ARGV, size, sizeof (fds[0]));
int res = 1;
/* Remove impersonation */
cygheap->user.deimpersonate ();
if (cygheap->ctty)
{
cygheap->ctty->usecount++;
cygheap->console_count++;
report_tty_counts (cygheap->ctty, "vfork dup", "incremented ", "");
}
for (size_t i = 0; i < size; i++)
if (not_open (i))
continue;
else if ((newtable[i] = dup_worker (fds[i])) != NULL)
newtable[i]->set_close_on_exec (fds[i]->close_on_exec ());
else
{
res = 0;
goto out;
}
fds_on_hold = fds;
fds = newtable;
out:
/* Restore impersonation */
cygheap->user.reimpersonate ();
unlock ();
return 1;
}
void
dtable::vfork_parent_restore ()
{
lock ();
fhandler_tty_slave *ctty_on_hold = cygheap->ctty_on_hold;
close_all_files ();
fhandler_base **deleteme = fds;
fds = fds_on_hold;
fds_on_hold = NULL;
cfree (deleteme);
unlock ();
if (cygheap->ctty != ctty_on_hold)
{
cygheap->ctty = ctty_on_hold; // revert
cygheap->ctty->close (); // Undo previous bump of this archetype
}
cygheap->ctty_on_hold = NULL;
}
void
dtable::vfork_child_fixup ()
{
if (!fds_on_hold)
return;
debug_printf ("here");
fhandler_base **saveme = fds;
fds = fds_on_hold;
fhandler_base *fh;
for (int i = 0; i < (int) size; i++)
if ((fh = fds[i]) != NULL)
{
fh->clear_readahead ();
if (!fh->archetype && fh->close_on_exec ())
release (i);
else
{
fh->close ();
release (i);
}
}
fds = saveme;
cfree (fds_on_hold);
fds_on_hold = NULL;
if (cygheap->ctty_on_hold)
{
cygheap->ctty_on_hold->close ();
cygheap->ctty_on_hold = NULL;
}
}
#endif /*NEWVFORK*/
static void static void
decode_tty (char *buf, WCHAR *w32) decode_tty (char *buf, WCHAR *w32)
{ {

View File

@ -39,7 +39,7 @@ struct __cygwin_perfile *perfile_table;
inline fhandler_base& inline fhandler_base&
fhandler_base::operator =(fhandler_base& x) fhandler_base::operator =(fhandler_base& x)
{ {
memcpy (this, &x, sizeof *this); memcpy (this, &x, size ());
pc = x.pc; pc = x.pc;
rabuf = NULL; rabuf = NULL;
ralen = 0; ralen = 0;
@ -449,6 +449,40 @@ done:
return res; return res;
} }
int
fhandler_base::open_with_arch (int flags, mode_t mode)
{
int res;
close_on_exec (flags & O_CLOEXEC);
if (!(res = (archetype && archetype->io_handle)
|| open (flags, (mode & 07777) & ~cygheap->umask)))
{
if (archetype)
delete archetype;
}
else if (archetype)
{
if (!archetype->io_handle)
{
usecount = 0;
*archetype = *this;
archetype_usecount (1);
archetype->archetype = NULL;
}
else
{
fhandler_base *arch = archetype;
*this = *archetype;
archetype = arch;
archetype_usecount (1);
usecount = 0;
}
open_setup (flags);
}
return res;
}
/* Open system call handler function. */ /* Open system call handler function. */
int int
fhandler_base::open (int flags, mode_t mode) fhandler_base::open (int flags, mode_t mode)
@ -1029,6 +1063,48 @@ fhandler_base::pwrite (void *, size_t, _off64_t)
return -1; return -1;
} }
int
fhandler_base::close_with_arch ()
{
int res;
fhandler_base *fh;
if (usecount)
{
if (!--usecount)
debug_printf ("closing passed in archetype, usecount %d", usecount);
else
{
debug_printf ("not closing passed in archetype, usecount %d", usecount);
return 0;
}
fh = this;
}
else if (!archetype)
fh = this;
else
{
cleanup ();
if (archetype_usecount (-1) == 0)
{
debug_printf ("closing archetype");
fh = archetype;
}
else
{
debug_printf ("not closing archetype");
return 0;
}
}
res = fh->close ();
if (archetype)
{
cygheap->fdtab.delete_archetype (archetype);
archetype = NULL;
}
return res;
}
int int
fhandler_base::close () fhandler_base::close ()
{ {

View File

@ -178,8 +178,13 @@ class fhandler_base
path_conv pc; path_conv pc;
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) {pc.set_normalized_path (s);} virtual void set_name (const char *s)
{
pc.set_normalized_path (s);
pc.set_path (s);
}
int error () const {return pc.error;} int error () const {return pc.error;}
void set_error (int error) {pc.error = error;} void set_error (int error) {pc.error = error;}
bool exists () const {return pc.exists ();} bool exists () const {return pc.exists ();}
@ -290,9 +295,24 @@ class fhandler_base
bool fork_fixup (HANDLE, HANDLE &, const char *); bool fork_fixup (HANDLE, HANDLE &, const char *);
virtual bool need_fixup_before () const {return false;} virtual bool need_fixup_before () const {return false;}
virtual int open (int, mode_t = 0); int open_with_arch (int, mode_t = 0);
virtual int open (int, mode_t);
virtual void open_setup (int flags) { return; }
int open_fs (int, mode_t = 0); int open_fs (int, mode_t = 0);
virtual int close_with_arch ();
virtual int close (); virtual int close ();
virtual void cleanup () { return; }
int _archetype_usecount (const char *fn, int ln, int n)
{
if (!archetype)
return 0;
archetype->usecount += n;
if (strace.active ())
strace.prntf (_STRACE_ALL, fn, "line %d: %s<%p> usecount + %d = %d", ln, get_name (), archetype, n, archetype->usecount);
return archetype->usecount;
}
# define archetype_usecount(n) _archetype_usecount (__PRETTY_FUNCTION__, __LINE__, (n))
int close_fs () { return fhandler_base::close (); } int close_fs () { return fhandler_base::close (); }
virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2)));
@ -548,6 +568,7 @@ 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);}
}; };
class fhandler_base_overlapped: public fhandler_base class fhandler_base_overlapped: public fhandler_base
@ -612,6 +633,7 @@ 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);}
}; };
class fhandler_fifo: public fhandler_base_overlapped class fhandler_fifo: public fhandler_base_overlapped
@ -645,6 +667,7 @@ public:
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);}
}; };
class fhandler_mailslot : public fhandler_base_overlapped class fhandler_mailslot : public fhandler_base_overlapped
@ -657,6 +680,7 @@ 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);}
}; };
class fhandler_dev_raw: public fhandler_base class fhandler_dev_raw: public fhandler_base
@ -689,6 +713,7 @@ class fhandler_dev_raw: public fhandler_base
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);}
}; };
#define MAX_PARTITIONS 15 #define MAX_PARTITIONS 15
@ -732,6 +757,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw
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);}
}; };
class fhandler_dev_tape: public fhandler_dev_raw class fhandler_dev_tape: public fhandler_dev_raw
@ -749,7 +775,7 @@ class fhandler_dev_tape: public fhandler_dev_raw
public: public:
fhandler_dev_tape (); fhandler_dev_tape ();
virtual int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
virtual int close (); virtual int close ();
void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3))); void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
@ -763,6 +789,7 @@ class fhandler_dev_tape: public fhandler_dev_raw
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);}
}; };
/* Standard disk file */ /* Standard disk file */
@ -806,6 +833,7 @@ 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);}
}; };
class fhandler_cygdrive: public fhandler_disk_file class fhandler_cygdrive: public fhandler_disk_file
@ -827,6 +855,7 @@ 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);}
}; };
class fhandler_serial: public fhandler_base class fhandler_serial: public fhandler_base
@ -875,6 +904,7 @@ class fhandler_serial: public fhandler_base
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *); select_record *select_except (select_stuff *);
bool is_slow () {return true;} bool is_slow () {return true;}
size_t size () const { return sizeof (*this);}
}; };
#define acquire_output_mutex(ms) \ #define acquire_output_mutex(ms) \
@ -1048,7 +1078,10 @@ class fhandler_console: public fhandler_termios
fhandler_console* is_console () { return this; } fhandler_console* is_console () { return this; }
int open (int flags, mode_t mode = 0); bool use_archetype () const {return true;}
int open (int flags, mode_t mode);
void open_setup (int flags);
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);
@ -1059,9 +1092,6 @@ class fhandler_console: public fhandler_termios
int tcsetattr (int a, const struct termios *t); int tcsetattr (int a, const struct termios *t);
int tcgetattr (struct termios *t); int tcgetattr (struct termios *t);
/* Special dup as we must dup two handles */
int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
int init (HANDLE, DWORD, mode_t); int init (HANDLE, DWORD, mode_t);
bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event); bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event);
@ -1080,6 +1110,7 @@ class fhandler_console: public fhandler_termios
bool is_slow () {return true;} bool is_slow () {return true;}
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);}
}; };
class fhandler_tty_common: public fhandler_termios class fhandler_tty_common: public fhandler_termios
@ -1124,9 +1155,11 @@ class fhandler_tty_slave: public fhandler_tty_common
public: public:
/* Constructor */ /* Constructor */
fhandler_tty_slave (); fhandler_tty_slave (int);
bool use_archetype () const {return true;}
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 init (HANDLE, DWORD, mode_t); int init (HANDLE, DWORD, mode_t);
@ -1136,6 +1169,7 @@ class fhandler_tty_slave: public fhandler_tty_common
int tcflush (int); int tcflush (int);
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
int close (); int close ();
void cleanup ();
int dup (fhandler_base *child); int dup (fhandler_base *child);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
void fixup_after_exec (); void fixup_after_exec ();
@ -1146,6 +1180,7 @@ class fhandler_tty_slave: public fhandler_tty_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);}
}; };
class fhandler_pty_master: public fhandler_tty_common class fhandler_pty_master: public fhandler_tty_common
@ -1161,6 +1196,7 @@ public:
/* Constructor */ /* Constructor */
fhandler_pty_master (); fhandler_pty_master ();
virtual bool use_archetype () const {return true;}
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);
@ -1169,6 +1205,7 @@ public:
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 ();
void cleanup ();
int tcsetattr (int a, const struct termios *t); int tcsetattr (int a, const struct termios *t);
int tcgetattr (struct termios *t); int tcgetattr (struct termios *t);
@ -1184,6 +1221,8 @@ public:
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
void fixup_after_exec (); void fixup_after_exec ();
int tcgetpgrp (); int tcgetpgrp ();
virtual bool is_tty_master () const {return false;}
size_t size () const { return sizeof (*this);}
}; };
class fhandler_tty_master: public fhandler_pty_master class fhandler_tty_master: public fhandler_pty_master
@ -1191,11 +1230,14 @@ class fhandler_tty_master: public fhandler_pty_master
public: public:
/* Constructor */ /* Constructor */
fhandler_console *console; // device handler to perform real i/o. fhandler_console *console; // device handler to perform real i/o.
bool use_archetype () const {return false;}
fhandler_tty_master (); fhandler_tty_master ();
int init (); int init ();
int init_console (); int init_console ();
void set_winsize (bool); void set_winsize (bool);
bool is_tty_master () const {return true;}
size_t size () const { return sizeof (*this);}
}; };
class fhandler_dev_null: public fhandler_base class fhandler_dev_null: public fhandler_base
@ -1206,6 +1248,7 @@ 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);}
}; };
class fhandler_dev_zero: public fhandler_base class fhandler_dev_zero: public fhandler_base
@ -1224,6 +1267,7 @@ 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);}
}; };
class fhandler_dev_random: public fhandler_base class fhandler_dev_random: public fhandler_base
@ -1245,6 +1289,7 @@ class fhandler_dev_random: 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);
size_t size () const { return sizeof (*this);}
}; };
class fhandler_dev_mem: public fhandler_base class fhandler_dev_mem: public fhandler_base
@ -1269,7 +1314,8 @@ 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);}
};
class fhandler_dev_clipboard: public fhandler_base class fhandler_dev_clipboard: public fhandler_base
{ {
@ -1288,6 +1334,7 @@ class fhandler_dev_clipboard: public fhandler_base
int dup (fhandler_base *child); int dup (fhandler_base *child);
void fixup_after_exec (); void fixup_after_exec ();
size_t size () const { return sizeof (*this);}
}; };
class fhandler_windows: public fhandler_base class fhandler_windows: public fhandler_base
@ -1310,6 +1357,7 @@ 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);}
}; };
class fhandler_dev_dsp: public fhandler_base class fhandler_dev_dsp: public fhandler_base
@ -1334,12 +1382,13 @@ class fhandler_dev_dsp: public fhandler_base
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
_off64_t lseek (_off64_t, int); _off64_t lseek (_off64_t, int);
int close (); int close ();
int dup (fhandler_base *child);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
void fixup_after_exec (); void fixup_after_exec ();
private: private:
void close_audio_in (); void close_audio_in ();
void close_audio_out (bool immediately = false); void close_audio_out (bool immediately = false);
size_t size () const { return sizeof (*this);}
bool use_archetype () const {return true;}
}; };
class fhandler_virtual : public fhandler_base class fhandler_virtual : public fhandler_base
@ -1374,6 +1423,7 @@ 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);}
}; };
class fhandler_proc: public fhandler_virtual class fhandler_proc: public fhandler_virtual
@ -1387,6 +1437,7 @@ 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);}
}; };
class fhandler_procsys: public fhandler_virtual class fhandler_procsys: public fhandler_virtual
@ -1406,6 +1457,7 @@ 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);}
}; };
class fhandler_procsysvipc: public fhandler_proc class fhandler_procsysvipc: public fhandler_proc
@ -1418,6 +1470,7 @@ 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);}
}; };
class fhandler_netdrive: public fhandler_virtual class fhandler_netdrive: public fhandler_virtual
@ -1431,6 +1484,7 @@ 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);}
}; };
class fhandler_registry: public fhandler_proc class fhandler_registry: public fhandler_proc
@ -1454,6 +1508,7 @@ class fhandler_registry: public fhandler_proc
bool fill_filebuf (); bool fill_filebuf ();
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child);
size_t size () const { return sizeof (*this);}
}; };
class pinfo; class pinfo;
@ -1468,6 +1523,7 @@ 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);}
}; };
class fhandler_procnet: public fhandler_proc class fhandler_procnet: public fhandler_proc
@ -1480,6 +1536,7 @@ 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);}
}; };
struct fhandler_nodevice: public fhandler_base struct fhandler_nodevice: public fhandler_base
@ -1492,7 +1549,7 @@ struct fhandler_nodevice: public fhandler_base
#define report_tty_counts(fh, call, use_op) \ #define report_tty_counts(fh, call, use_op) \
termios_printf ("%s %s, %susecount %d",\ termios_printf ("%s %s, %susecount %d",\
fh->ttyname (), call,\ fh->ttyname (), call,\
use_op, ((fhandler_tty_slave *) fh)->archetype->usecount); use_op, ((fhandler_tty_slave *) (fh->archetype ?: fh))->usecount);
typedef union typedef union
{ {

View File

@ -94,8 +94,6 @@ fhandler_console::get_tty_stuff (int flags = 0)
if (!shared_console_info->tty_min_state.ntty) if (!shared_console_info->tty_min_state.ntty)
{ {
shared_console_info->tty_min_state.setntty (TTY_CONSOLE); shared_console_info->tty_min_state.setntty (TTY_CONSOLE);
shared_console_info->tty_min_state.setsid (myself->sid);
myself->set_ctty (&shared_console_info->tty_min_state, flags, this);
dev_state->scroll_region.Bottom = -1; dev_state->scroll_region.Bottom = -1;
dev_state->dwLastCursorPosition.X = -1; dev_state->dwLastCursorPosition.X = -1;
@ -700,8 +698,6 @@ fhandler_console::open (int flags, mode_t)
set_io_handle (NULL); set_io_handle (NULL);
set_output_handle (NULL); set_output_handle (NULL);
set_flags ((flags & ~O_TEXT) | O_BINARY);
/* Open the input handle as handle_ */ /* Open the input handle as handle_ */
h = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE, h = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, sec_none_cloexec (flags), FILE_SHARE_READ | FILE_SHARE_WRITE, sec_none_cloexec (flags),
@ -735,7 +731,6 @@ fhandler_console::open (int flags, mode_t)
tc->rstcons (false); tc->rstcons (false);
set_open_status (); set_open_status ();
cygheap->manage_console_count ("fhandler_console::open", 1);
DWORD cflags; DWORD cflags;
if (GetConsoleMode (get_io_handle (), &cflags)) if (GetConsoleMode (get_io_handle (), &cflags))
@ -748,6 +743,14 @@ fhandler_console::open (int flags, mode_t)
return 1; return 1;
} }
void
fhandler_console::open_setup (int flags)
{
cygheap->manage_console_count ("fhandler_console::open", 1);
set_flags ((flags & ~O_TEXT) | O_BINARY);
myself->set_ctty (&shared_console_info->tty_min_state, flags, this);
}
int int
fhandler_console::close () fhandler_console::close ()
{ {
@ -758,19 +761,6 @@ fhandler_console::close ()
return 0; return 0;
} }
/* Special console dup to duplicate input and output handles. */
int
fhandler_console::dup (fhandler_base *child)
{
fhandler_console *fhc = (fhandler_console *) child;
if (!fhc->open (get_flags () & ~O_NOCTTY, 0))
system_printf ("error opening console, %E");
return 0;
}
int int
fhandler_console::ioctl (unsigned int cmd, void *buf) fhandler_console::ioctl (unsigned int cmd, void *buf)
{ {
@ -855,6 +845,8 @@ fhandler_console::output_tcsetattr (int, struct termios const *t)
DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1; int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1;
if (!res)
__seterrno_from_win_error (GetLastError ());
syscall_printf ("%d = tcsetattr (,%x) (ENABLE FLAGS %x) (lflag %x oflag %x)", syscall_printf ("%d = tcsetattr (,%x) (ENABLE FLAGS %x) (lflag %x oflag %x)",
res, t, flags, t->c_lflag, t->c_oflag); res, t, flags, t->c_lflag, t->c_oflag);
return res; return res;
@ -980,6 +972,7 @@ fhandler_console::tcgetattr (struct termios *t)
fhandler_console::fhandler_console () : fhandler_console::fhandler_console () :
fhandler_termios () fhandler_termios ()
{ {
dev ().parse (FH_CONSOLE);
trunc_buf.len = 0; trunc_buf.len = 0;
} }
@ -2094,7 +2087,7 @@ fhandler_console::init (HANDLE h, DWORD a, mode_t bin)
flags = O_WRONLY; flags = O_WRONLY;
if (a == (GENERIC_READ | GENERIC_WRITE)) if (a == (GENERIC_READ | GENERIC_WRITE))
flags = O_RDWR; flags = O_RDWR;
open (flags | O_BINARY | (h ? 0 : O_NOCTTY)); open_with_arch (flags | O_BINARY | (h ? 0 : O_NOCTTY));
if (h && h != INVALID_HANDLE_VALUE) if (h && h != INVALID_HANDLE_VALUE)
CloseHandle (h); /* Reopened by open */ CloseHandle (h); /* Reopened by open */
@ -2127,24 +2120,7 @@ set_console_title (char *title)
void void
fhandler_console::fixup_after_fork_exec (bool execing) fhandler_console::fixup_after_fork_exec (bool execing)
{ {
HANDLE h = get_handle (); get_tty_stuff ();
HANDLE oh = get_output_handle ();
if ((execing && close_on_exec ()) || open (O_NOCTTY | get_flags (), 0))
cygheap->manage_console_count ("fhandler_console::fixup_after_fork_exec", -1);
else
{
if (!get_io_handle ())
system_printf ("error opening input console handle for %s after fork/exec, errno %d, %E", get_name (), get_errno ());
if (!get_output_handle ())
system_printf ("error opening output console handle for %s after fork/exec, errno %d, %E", get_name (), get_errno ());
}
if (!close_on_exec ())
{
CloseHandle (h);
CloseHandle (oh);
}
} }
bool NO_COPY fhandler_console::invisible_console; bool NO_COPY fhandler_console::invisible_console;

View File

@ -1006,11 +1006,6 @@ fhandler_dev_dsp::fhandler_dev_dsp ():
int int
fhandler_dev_dsp::open (int flags, mode_t mode) fhandler_dev_dsp::open (int flags, mode_t mode)
{ {
if (cygheap->fdtab.find_archetype (dev ()))
{
set_errno (EBUSY);
return 0;
}
int err = 0; int err = 0;
UINT num_in = 0, num_out = 0; UINT num_in = 0, num_out = 0;
set_flags ((flags & ~O_TEXT) | O_BINARY); set_flags ((flags & ~O_TEXT) | O_BINARY);
@ -1042,13 +1037,6 @@ fhandler_dev_dsp::open (int flags, mode_t mode)
set_open_status (); set_open_status ();
need_fork_fixup (true); need_fork_fixup (true);
nohandle (true); nohandle (true);
// FIXME: Do this better someday
fhandler_dev_dsp *arch = (fhandler_dev_dsp *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
archetype = arch;
*((fhandler_dev_dsp **) cygheap->fdtab.add_archetype ()) = arch;
*arch = *this;
archetype->usecount = 1;
} }
else else
set_errno (err); set_errno (err);
@ -1065,9 +1053,6 @@ ssize_t __stdcall
fhandler_dev_dsp::write (const void *ptr, size_t len) fhandler_dev_dsp::write (const void *ptr, size_t len)
{ {
debug_printf ("ptr=%08x len=%d", ptr, len); debug_printf ("ptr=%08x len=%d", ptr, len);
if ((fhandler_dev_dsp *) archetype != this)
return ((fhandler_dev_dsp *)archetype)->write(ptr, len);
int len_s = len; int len_s = len;
const char *ptr_s = static_cast <const char *> (ptr); const char *ptr_s = static_cast <const char *> (ptr);
@ -1114,8 +1099,6 @@ void __stdcall
fhandler_dev_dsp::read (void *ptr, size_t& len) fhandler_dev_dsp::read (void *ptr, size_t& len)
{ {
debug_printf ("ptr=%08x len=%d", ptr, len); debug_printf ("ptr=%08x len=%d", ptr, len);
if ((fhandler_dev_dsp *) archetype != this)
return ((fhandler_dev_dsp *)archetype)->read(ptr, len);
if (audio_in_) if (audio_in_)
/* nothing to do */; /* nothing to do */;
@ -1181,27 +1164,8 @@ fhandler_dev_dsp::close ()
{ {
debug_printf ("audio_in=%08x audio_out=%08x", debug_printf ("audio_in=%08x audio_out=%08x",
(int)audio_in_, (int)audio_out_); (int)audio_in_, (int)audio_out_);
if (!hExeced) close_audio_in ();
{ close_audio_out (exit_state != ES_NOT_EXITING);
if ((fhandler_dev_dsp *) archetype != this)
return ((fhandler_dev_dsp *) archetype)->close ();
if (--usecount == 0)
{
close_audio_in ();
close_audio_out (exit_state != ES_NOT_EXITING);
}
}
return 0;
}
int
fhandler_dev_dsp::dup (fhandler_base * child)
{
debug_printf ("");
child->archetype = archetype;
child->set_flags (get_flags ());
archetype->usecount++;
return 0; return 0;
} }
@ -1210,9 +1174,6 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
{ {
debug_printf ("audio_in=%08x audio_out=%08x", debug_printf ("audio_in=%08x audio_out=%08x",
(int)audio_in_, (int)audio_out_); (int)audio_in_, (int)audio_out_);
if ((fhandler_dev_dsp *) archetype != this)
return ((fhandler_dev_dsp *)archetype)->ioctl(cmd, ptr);
int *intptr = (int *) ptr; int *intptr = (int *) ptr;
switch (cmd) switch (cmd)
{ {
@ -1419,11 +1380,9 @@ fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
{ // called from new child process { // called from new child process
debug_printf ("audio_in=%08x audio_out=%08x", debug_printf ("audio_in=%08x audio_out=%08x",
(int)audio_in_, (int)audio_out_); (int)audio_in_, (int)audio_out_);
if (archetype != this)
return ((fhandler_dev_dsp *)archetype)->fixup_after_fork (parent);
if (audio_in_) if (audio_in_)
audio_in_ ->fork_fixup (parent); audio_in_->fork_fixup (parent);
if (audio_out_) if (audio_out_)
audio_out_->fork_fixup (parent); audio_out_->fork_fixup (parent);
} }
@ -1435,9 +1394,6 @@ fhandler_dev_dsp::fixup_after_exec ()
(int) audio_in_, (int) audio_out_, close_on_exec ()); (int) audio_in_, (int) audio_out_, close_on_exec ());
if (!close_on_exec ()) if (!close_on_exec ())
{ {
if (archetype != this)
return ((fhandler_dev_dsp *) archetype)->fixup_after_exec ();
audio_in_ = NULL; audio_in_ = NULL;
audio_out_ = NULL; audio_out_ = NULL;
} }

View File

@ -113,7 +113,7 @@ fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
DWORD ms) DWORD ms)
{ {
if (strace.active ()) if (strace.active ())
strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex: waiting %d ms", ln, ms); strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex (%p): waiting %d ms", ln, output_mutex, ms);
DWORD res = WaitForSingleObject (output_mutex, ms); DWORD res = WaitForSingleObject (output_mutex, ms);
if (res == WAIT_OBJECT_0) if (res == WAIT_OBJECT_0)
{ {
@ -138,11 +138,11 @@ fhandler_tty_common::__release_output_mutex (const char *fn, int ln)
{ {
#ifndef DEBUGGING #ifndef DEBUGGING
if (strace.active ()) if (strace.active ())
strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex released", ln); strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex(%p) released", ln, output_mutex);
#else #else
if (osi > 0) if (osi > 0)
osi--; osi--;
termios_printf ("released at %s:%d, osi %d", fn, ln, osi); termios_printf ("released(%p) at %s:%d, osi %d", output_mutex, fn, ln, osi);
termios_printf (" for %s:%d (%s)", ostack[osi].fn, ostack[osi].ln, ostack[osi].tname); termios_printf (" for %s:%d (%s)", ostack[osi].fn, ostack[osi].ln, ostack[osi].tname);
ostack[osi].ln = -ln; ostack[osi].ln = -ln;
#endif #endif
@ -299,7 +299,10 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
while (1) while (1)
{ {
if (!PeekNamedPipe (handle, NULL, 0, NULL, &n, NULL)) if (!PeekNamedPipe (handle, NULL, 0, NULL, &n, NULL))
goto err; {
termios_printf ("PeekNamedPipe failed, %E");
goto err;
}
if (n > 0) if (n > 0)
break; break;
if (hit_eof ()) if (hit_eof ())
@ -307,6 +310,10 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
/* DISCARD (FLUSHO) and tcflush can finish here. */ /* DISCARD (FLUSHO) and tcflush can finish here. */
if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf)) if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
goto out; goto out;
if (is_tty_master ())
continue;
if (is_nonblocking ()) if (is_nonblocking ())
{ {
set_errno (EAGAIN); set_errno (EAGAIN);
@ -321,17 +328,19 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
rc = -1; rc = -1;
goto out; goto out;
} }
} }
if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE) if (!ReadFile (handle, outbuf, rlen, &n, NULL))
goto err; {
termios_printf ("ReadFile failed, %E");
goto err;
}
} }
termios_printf ("bytes read %u", n); termios_printf ("bytes read %u", n);
get_ttyp ()->write_error = 0; get_ttyp ()->write_error = 0;
if (output_done_event != NULL) if (output_done_event != NULL)
SetEvent (output_done_event); SetEvent (output_done_event);
if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf) if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
continue; continue;
@ -420,14 +429,17 @@ process_output (void *)
for (;;) for (;;)
{ {
int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0); int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0);
if (n <= 0) if (n > 0)
{
n = tty_master->console->write ((void *) buf, (size_t) n);
tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
}
else
{ {
if (n < 0) if (n < 0)
termios_printf ("ReadFile %E"); termios_printf ("ReadFile %E");
ExitThread (0); ExitThread (0);
} }
n = tty_master->console->write ((void *) buf, (size_t) n);
tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
} }
} }
@ -454,9 +466,12 @@ process_ioctl (void *)
/**********************************************************************/ /**********************************************************************/
/* Tty slave stuff */ /* Tty slave stuff */
fhandler_tty_slave::fhandler_tty_slave () fhandler_tty_slave::fhandler_tty_slave (int ntty)
: fhandler_tty_common (), inuse (NULL) : fhandler_tty_common (), inuse (NULL)
{} {
if (ntty >= 0)
dev ().parse (DEV_TTYS_MAJOR, ntty);
}
/* FIXME: This function needs to close handles when it has /* FIXME: This function needs to close handles when it has
a failing condition. */ a failing condition. */
@ -472,28 +487,13 @@ fhandler_tty_slave::open (int flags, mode_t)
NULL NULL
}; };
const char *errmsg = NULL;
for (HANDLE **h = handles; *h; h++) for (HANDLE **h = handles; *h; h++)
**h = NULL; **h = NULL;
if (get_device () == FH_TTY)
dev().tty_to_real_device ();
fhandler_tty_slave *arch = (fhandler_tty_slave *) cygheap->fdtab.find_archetype (pc.dev);
if (arch)
{
*this = *(fhandler_tty_slave *) arch;
termios_printf ("copied fhandler_tty_slave archetype");
set_flags ((flags & ~O_TEXT) | O_BINARY);
cygheap->manage_console_count ("fhandler_tty_slave::open<arch>", 1);
goto out;
}
tcinit (cygwin_shared->tty[get_unit ()], false); tcinit (cygwin_shared->tty[get_unit ()], false);
cygwin_shared->tty.attach (get_unit ()); cygwin_shared->tty.attach (get_unit ());
set_flags ((flags & ~O_TEXT) | O_BINARY);
/* Create synchronisation events */ /* Create synchronisation events */
char buf[MAX_PATH]; char buf[MAX_PATH];
@ -505,6 +505,8 @@ fhandler_tty_slave::open (int flags, mode_t)
shared_name (buf, OUTPUT_DONE_EVENT, get_unit ()); shared_name (buf, OUTPUT_DONE_EVENT, get_unit ());
output_done_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf); output_done_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf);
const char *errmsg = NULL;
if (!(output_mutex = get_ttyp ()->open_output_mutex (MAXIMUM_ALLOWED))) if (!(output_mutex = get_ttyp ()->open_output_mutex (MAXIMUM_ALLOWED)))
{ {
errmsg = "open output mutex failed, %E"; errmsg = "open output mutex failed, %E";
@ -646,19 +648,6 @@ fhandler_tty_slave::open (int flags, mode_t)
if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1 if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1
&& !output_done_event) && !output_done_event)
fhandler_console::need_invisible (); fhandler_console::need_invisible ();
// FIXME: Do this better someday
arch = (fhandler_tty_slave *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
*((fhandler_tty_slave **) cygheap->fdtab.add_archetype ()) = arch;
archetype = arch;
*arch = *this;
out:
usecount = 0;
arch->usecount++;
report_tty_counts (this, "opened", "");
myself->set_ctty (get_ttyp (), flags, arch);
return 1; return 1;
err: err:
@ -672,8 +661,17 @@ err_no_msg:
return 0; return 0;
} }
int void
fhandler_tty_slave::close () fhandler_tty_slave::open_setup (int flags)
{
set_flags ((flags & ~O_TEXT) | O_BINARY);
myself->set_ctty (get_ttyp (), flags, this);
cygheap->manage_console_count ("fhandler_tty_slave::setup", 1);
report_tty_counts (this, "opened", "");
}
void
fhandler_tty_slave::cleanup ()
{ {
/* This used to always call fhandler_tty_common::close when hExeced but that /* This used to always call fhandler_tty_common::close when hExeced but that
caused multiple closes of the handles associated with this tty. Since caused multiple closes of the handles associated with this tty. Since
@ -681,20 +679,12 @@ fhandler_tty_slave::close ()
or before a non-cygwin process has exited, it should be safe to just or before a non-cygwin process has exited, it should be safe to just
close this normally. cgf 2006-05-20 */ close this normally. cgf 2006-05-20 */
cygheap->manage_console_count ("fhandler_tty_slave::close", -1); cygheap->manage_console_count ("fhandler_tty_slave::close", -1);
archetype->usecount--;
report_tty_counts (this, "closed", ""); report_tty_counts (this, "closed", "");
}
if (archetype->usecount) int
{ fhandler_tty_slave::close ()
#ifdef DEBUGGING {
if (archetype->usecount < 0)
system_printf ("error: usecount %d", archetype->usecount);
#endif
termios_printf ("just returning because archetype usecount is != 0");
return 0;
}
termios_printf ("closing last open %s handle", ttyname ()); termios_printf ("closing last open %s handle", ttyname ());
if (inuse && !CloseHandle (inuse)) if (inuse && !CloseHandle (inuse))
termios_printf ("CloseHandle (inuse), %E"); termios_printf ("CloseHandle (inuse), %E");
@ -702,7 +692,7 @@ fhandler_tty_slave::close ()
} }
int int
fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t) fhandler_tty_slave::init (HANDLE h, DWORD a, mode_t)
{ {
int flags = 0; int flags = 0;
@ -714,7 +704,7 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
if (a == (GENERIC_READ | GENERIC_WRITE)) if (a == (GENERIC_READ | GENERIC_WRITE))
flags = O_RDWR; flags = O_RDWR;
int ret = open (flags); int ret = open_with_arch (flags);
if (ret && !cygwin_finished_initializing && !being_debugged ()) if (ret && !cygwin_finished_initializing && !being_debugged ())
{ {
@ -735,8 +725,8 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
} }
} }
if (f != INVALID_HANDLE_VALUE) if (h != INVALID_HANDLE_VALUE)
CloseHandle (f); /* Reopened by open */ CloseHandle (h); /* Reopened by open */
return ret; return ret;
} }
@ -1037,38 +1027,14 @@ out:
int int
fhandler_tty_slave::dup (fhandler_base *child) fhandler_tty_slave::dup (fhandler_base *child)
{ {
fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype;
/* In dtable::dup_worker, the path_conv member has already been assigned
from "this" to "child". Part of this assigment (path_conv::operator=)
is to allocate memory for the strings "path" and "normalized_path from
cygheap. The below `child = *arch' statement will overwrite child's
path_conv again, this time from "*arch". By doing that, it will allocate
new strings from cygheap, overwriting the old pointer values. Thus, the
old allocated strings are lost, and we're leaking memory for each tty dup,
unless we free the strings here.
FIXME: We can't redefine path_conv::operator= so that it frees the old
strings. Probably it would be most helpful to copy only the required
members from *arch, rather than copying everything. */
child->pc.free_strings ();
*(fhandler_tty_slave *) child = *arch;
child->set_flags (get_flags ());
child->usecount = 0;
arch->usecount++;
cygheap->manage_console_count ("fhandler_tty_slave::dup", 1); cygheap->manage_console_count ("fhandler_tty_slave::dup", 1);
report_tty_counts (child, "duped", ""); 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)
{ {
fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
/* See comment in fhandler_tty_slave::dup. */
child->pc.free_strings ();
*(fhandler_tty_master *) child = *arch;
child->set_flags (get_flags ());
child->usecount = 0;
arch->usecount++;
report_tty_counts (child, "duped master", ""); report_tty_counts (child, "duped master", "");
return 0; return 0;
} }
@ -1435,15 +1401,8 @@ fhandler_pty_master::open (int flags, mode_t)
set_flags ((flags & ~O_TEXT) | O_BINARY); set_flags ((flags & ~O_TEXT) | O_BINARY);
set_open_status (); set_open_status ();
/* FIXME: Do this better someday */ dwProcessId = GetCurrentProcessId ();
fhandler_pty_master *arch = (fhandler_tty_master *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
*((fhandler_pty_master **) cygheap->fdtab.add_archetype ()) = arch;
archetype = arch;
*arch = *this;
arch->dwProcessId = GetCurrentProcessId ();
usecount = 0;
arch->usecount++;
char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")]; char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")];
__small_sprintf (buf, "opened pty master for tty%d", get_unit ()); __small_sprintf (buf, "opened pty master for tty%d", get_unit ());
report_tty_counts (this, buf, ""); report_tty_counts (this, buf, "");
@ -1482,6 +1441,12 @@ fhandler_tty_common::close ()
return 0; return 0;
} }
void
fhandler_pty_master::cleanup ()
{
report_tty_counts (this, "closing master", "");
}
int int
fhandler_pty_master::close () fhandler_pty_master::close ()
{ {
@ -1489,25 +1454,12 @@ fhandler_pty_master::close ()
while (accept_input () > 0) while (accept_input () > 0)
continue; continue;
#endif #endif
archetype->usecount--;
report_tty_counts (this, "closing master", "");
if (archetype->usecount)
{
#ifdef DEBUGGING
if (archetype->usecount < 0)
system_printf ("error: usecount %d", archetype->usecount);
#endif
termios_printf ("just returning because archetype usecount is != 0");
return 0;
}
fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%d)", termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%d)",
arch->from_master, arch->to_master, arch->dwProcessId); from_master, to_master, dwProcessId);
if (cygwin_finished_initializing) if (cygwin_finished_initializing)
{ {
if (arch->master_ctl && get_ttyp ()->master_pid == myself->pid) if (master_ctl && get_ttyp ()->master_pid == myself->pid)
{ {
char buf[MAX_PATH]; char buf[MAX_PATH];
pipe_request req = { (DWORD) -1 }; pipe_request req = { (DWORD) -1 };
@ -1517,13 +1469,13 @@ fhandler_pty_master::close ()
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl", __small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl",
&installation_key, get_unit ()); &installation_key, get_unit ());
CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500); CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
CloseHandle (arch->master_ctl); CloseHandle (master_ctl);
arch->master_thread->detach (); master_thread->detach ();
} }
if (!ForceCloseHandle (arch->from_master)) if (!ForceCloseHandle (from_master))
termios_printf ("error closing from_master %p, %E", arch->from_master); termios_printf ("error closing from_master %p, %E", from_master);
if (!ForceCloseHandle (arch->to_master)) if (!ForceCloseHandle (to_master))
termios_printf ("error closing from_master %p, %E", arch->to_master); termios_printf ("error closing from_master %p, %E", to_master);
} }
fhandler_tty_common::close (); fhandler_tty_common::close ();
@ -1674,7 +1626,7 @@ fhandler_tty_slave::fixup_after_exec ()
int int
fhandler_tty_master::init_console () fhandler_tty_master::init_console ()
{ {
console = (fhandler_console *) build_fh_dev (*console_dev, "/dev/ttym"); console = (fhandler_console *) build_fh_dev (*console_dev, "/dev/ttym_console");
if (console == NULL) if (console == NULL)
return -1; return -1;
@ -1824,10 +1776,10 @@ reply:
} }
static DWORD WINAPI static DWORD WINAPI
pty_master_thread (VOID *arg) pty_master_thread (VOID *arg)
{ {
return ((fhandler_pty_master *) arg)->pty_master_thread (); return ((fhandler_pty_master *) arg)->pty_master_thread ();
} }
bool bool
fhandler_pty_master::setup (bool ispty) fhandler_pty_master::setup (bool ispty)

View File

@ -371,12 +371,33 @@ _pinfo::_ctty (char *buf)
} }
void void
_pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *arch) _pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *fh)
{ {
debug_printf ("old %s", __ctty ()); debug_printf ("old %s, ctty %d, tc->ntty %d flags & O_NOCTTY %p", __ctty (), ctty, tc->ntty, flags & O_NOCTTY);
if ((ctty < 0 || ctty == tc->ntty) && !(flags & O_NOCTTY)) if ((ctty < 0 || ctty == tc->ntty) && !(flags & O_NOCTTY))
{ {
ctty = tc->ntty; ctty = tc->ntty;
if (cygheap->ctty != fh->archetype)
{
debug_printf ("/dev/tty%d cygheap->ctty %p, archetype %p", ctty, cygheap->ctty, fh->archetype);
if (!cygheap->ctty)
syscall_printf ("ctty was NULL");
else
{
syscall_printf ("ctty %p, usecount %d", cygheap->ctty,
cygheap->ctty->archetype_usecount (0));
cygheap->ctty->close ();
}
cygheap->ctty = (fhandler_termios *) fh->archetype;
if (cygheap->ctty)
{
fh->archetype_usecount (1);
/* guard ctty fh */
cygheap->manage_console_count ("_pinfo::set_ctty", 1);
report_tty_counts (cygheap->ctty, "ctty", "");
}
}
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 ());
@ -399,28 +420,8 @@ _pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *arch)
sid = tc->getsid (); sid = tc->getsid ();
if (tc->getpgid () == 0) if (tc->getpgid () == 0)
tc->setpgid (pgid); tc->setpgid (pgid);
if (cygheap->ctty != arch)
{
debug_printf ("cygheap->ctty %p, arch %p", cygheap->ctty, arch);
if (!cygheap->ctty)
syscall_printf ("ctty NULL");
else
{
syscall_printf ("ctty %p, usecount %d", cygheap->ctty,
cygheap->ctty->usecount);
cygheap->ctty->close ();
}
cygheap->ctty = arch;
if (arch)
{
arch->usecount++;
/* guard ctty arch */
cygheap->manage_console_count ("_pinfo::set_ctty", 1);
report_tty_counts (cygheap->ctty, "ctty", "");
}
}
} }
debug_printf ("cygheap->ctty now %p, arch %p", cygheap->ctty, arch); debug_printf ("cygheap->ctty now %p, archetype %p", cygheap->ctty, fh->archetype);
} }
/* 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

@ -101,7 +101,7 @@ close_all_files (bool norelease)
DuplicateHandle (GetCurrentProcess (), fh->get_output_handle (), DuplicateHandle (GetCurrentProcess (), fh->get_output_handle (),
GetCurrentProcess (), &h, GetCurrentProcess (), &h,
0, false, DUPLICATE_SAME_ACCESS); 0, false, DUPLICATE_SAME_ACCESS);
fh->close (); fh->close_with_arch ();
if (!norelease) if (!norelease)
cygheap->fdtab.release (i); cygheap->fdtab.release (i);
} }
@ -601,7 +601,7 @@ unlink_nt (path_conv &pc)
NFS implements its own mechanism to remove in-use files which NFS implements its own mechanism to remove in-use files which
looks quite similar to what we do in try_to_bin for remote files. looks quite similar to what we do in try_to_bin for remote files.
That's why we don't call try_to_bin on NFS. That's why we don't call try_to_bin on NFS.
Netapp filesystems don't understand the "move and delete" method Netapp filesystems don't understand the "move and delete" method
at all and have all kinds of weird effects. Just setting the delete at all and have all kinds of weird effects. Just setting the delete
dispositon usually works fine, though. */ dispositon usually works fine, though. */
@ -721,7 +721,7 @@ unlink_nt (path_conv &pc)
http://msdn.microsoft.com/en-us/library/ff545765%28VS.85%29.aspx http://msdn.microsoft.com/en-us/library/ff545765%28VS.85%29.aspx
"Subsequently, the only legal operation by such a caller is "Subsequently, the only legal operation by such a caller is
to close the open file handle." to close the open file handle."
FIXME? On Vista and later, we could use FILE_HARD_LINK_INFORMATION FIXME? On Vista and later, we could use FILE_HARD_LINK_INFORMATION
to find all hardlinks and use one of them to restore the R/O bit, to find all hardlinks and use one of them to restore the R/O bit,
after the NtClose, but before we stop the transaction. This after the NtClose, but before we stop the transaction. This
@ -1107,25 +1107,18 @@ open (const char *unix_path, int flags, ...)
res = -1; res = -1;
set_errno (EEXIST); set_errno (EEXIST);
} }
else if (fh->is_fs_special () && fh->device_access_denied (flags)) else if ((fh->is_fs_special () && fh->device_access_denied (flags))
|| !fh->open_with_arch (flags, (mode & 07777) & ~cygheap->umask))
{ {
delete fh; delete fh;
res = -1; res = -1;
} }
else else
{ {
fh->close_on_exec (flags & O_CLOEXEC); fd = fh;
if (!fh->open (flags, (mode & 07777) & ~cygheap->umask)) if (fd <= 2)
{ set_std_handle (fd);
delete fh; res = fd;
res = -1;
}
else
{
cygheap->fdtab[fd] = fh;
if ((res = fd) <= 2)
set_std_handle (res);
}
} }
} }
} }
@ -1185,7 +1178,7 @@ close (int fd)
res = -1; res = -1;
else else
{ {
res = cfd->close (); res = cfd->close_with_arch ();
cfd.release (); cfd.release ();
} }
@ -1974,7 +1967,7 @@ rename (const char *oldpath, const char *newpath)
filename has one of the blessed executable suffixes. */ filename has one of the blessed executable suffixes. */
if (!old_explicit_suffix && oldpc.known_suffix if (!old_explicit_suffix && oldpc.known_suffix
&& !newpc.is_binary () && !newpc.is_binary ()
&& !nt_path_has_executable_suffix (newpc.get_nt_native_path ())) && !nt_path_has_executable_suffix (newpc.get_nt_native_path ()))
{ {
rename_append_suffix (new2pc, newpath, nlen, ".exe"); rename_append_suffix (new2pc, newpath, nlen, ".exe");
removepc = &newpc; removepc = &newpc;
@ -2040,7 +2033,7 @@ retry:
a temporary filename and then rename the temp filename to the a temporary filename and then rename the temp filename to the
target filename. This renaming fails due to the jealous virus target filename. This renaming fails due to the jealous virus
scanner and the application fails to create the target file. scanner and the application fails to create the target file.
This kludge tries to work around that by yielding until the This kludge tries to work around that by yielding until the
sharing violation goes away, or a signal arrived, or after sharing violation goes away, or a signal arrived, or after
about a second, give or take. */ about a second, give or take. */