* 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>
* pinfo.h (class push_process_state): New class to push a process state

View File

@ -107,11 +107,7 @@ void
init_cygheap::close_ctty ()
{
debug_printf ("closing cygheap->ctty %p", cygheap->ctty);
/* FIXME: Support for console-as-ctty is limited due to the fact that
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->close_with_arch ();
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);
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;
}
#endif /*DEBUGGING*/

View File

@ -43439,15 +43439,6 @@ device::parse (_dev_t 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
device::parsedisk (int drive, int part)
{

View File

@ -268,7 +268,6 @@ struct device
return true;
}
static void init ();
void tty_to_real_device ();
inline operator int () const {return devn;}
inline void setfs (bool x) {dev_on_fs = x;}
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));
}
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
device::parsedisk (int drive, int part)
{

View File

@ -245,10 +245,7 @@ dtable::release (int fd)
{
if (fds[fd]->need_fixup_before ())
dec_need_fixup_before ();
fhandler_base *arch = fds[fd]->archetype;
delete fds[fd];
if (arch && !arch->usecount)
cygheap->fdtab.delete_archetype (arch);
fds[fd] = NULL;
}
}
@ -309,25 +306,20 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
else
dev = *pipew_dev;
}
else if (GetConsoleScreenBufferInfo (handle, &buf))
else if (GetConsoleScreenBufferInfo (handle, &buf)
|| GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
{
/* Console output */
if (ISSTATE (myself, PID_USETTY))
dev.parse (FH_TTY);
else
/* Console I/O */
if (!ISSTATE (myself, PID_USETTY))
dev = *console_dev;
}
else if (GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
{
/* Console input */
if (ISSTATE (myself, PID_USETTY))
dev.parse (FH_TTY);
else if (myself->ctty >= 0)
dev.parse (DEV_TTYS_MAJOR, myself->ctty);
else
dev = *console_dev;
dev.parse (FH_TTY);
}
else if (GetCommState (handle, &dcb))
/* serial */
dev.parse (DEV_TTYS_MAJOR, 0);
/* FIXME: Not right - assumes ttyS0 */
dev.parse (DEV_SERIAL_MAJOR, 0);
else
/* Try to figure it out from context - probably a disk file */
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)
fhandler_base *
build_fh_pc (path_conv& pc, bool set_name)
static fhandler_base *
fh_alloc (device dev)
{
fhandler_base *fh = fh_unset;
switch (pc.dev.major)
switch (dev.major)
{
case DEV_TTYS_MAJOR:
fh = cnew (fhandler_tty_slave) ();
fh = cnew (fhandler_tty_slave) (dev.minor);
break;
case DEV_TTYM_MAJOR:
fh = cnew (fhandler_tty_master) ();
@ -469,7 +461,7 @@ build_fh_pc (path_conv& pc, bool set_name)
fh = cnew (fhandler_serial) ();
break;
default:
switch (pc.dev)
switch (dev)
{
case FH_CONSOLE:
case FH_CONIN:
@ -548,8 +540,8 @@ build_fh_pc (path_conv& pc, bool set_name)
{
if (myself->ctty == TTY_CONSOLE)
fh = cnew (fhandler_console) ();
else if (myself->ctty >= 0)
fh = cnew (fhandler_tty_slave) ();
else
fh = cnew (fhandler_tty_slave) (myself->ctty);
break;
}
case FH_KMSG:
@ -560,12 +552,34 @@ build_fh_pc (path_conv& pc, bool set_name)
if (fh == fh_unset)
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)
set_errno (EMFILE);
else if (fh->dev () != FH_BAD)
fh->set_name (fh->dev ().name);
else if (set_name)
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);
return fh;
}
@ -582,7 +596,8 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
else
{
*newfh = *oldfh;
newfh->set_io_handle (NULL);
if (!oldfh->archetype)
newfh->set_io_handle (NULL);
newfh->pc.reset_conv_handle ();
if (oldfh->dup (newfh))
{
@ -592,11 +607,10 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
}
else
{
newfh->usecount = 0;
newfh->archetype_usecount (1);
/* The O_CLOEXEC flag enforces close-on-exec behaviour. */
if (flags & O_CLOEXEC)
newfh->set_close_on_exec (true);
else
newfh->close_on_exec (false);
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 ());
}
}
@ -754,7 +768,7 @@ dtable::fixup_after_exec ()
if (fh->archetype)
{
debug_printf ("closing fd %d since it is an archetype", i);
fh->close ();
fh->close_with_arch ();
}
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
decode_tty (char *buf, WCHAR *w32)
{

View File

@ -39,7 +39,7 @@ struct __cygwin_perfile *perfile_table;
inline fhandler_base&
fhandler_base::operator =(fhandler_base& x)
{
memcpy (this, &x, sizeof *this);
memcpy (this, &x, size ());
pc = x.pc;
rabuf = NULL;
ralen = 0;
@ -449,6 +449,40 @@ done:
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. */
int
fhandler_base::open (int flags, mode_t mode)
@ -1029,6 +1063,48 @@ fhandler_base::pwrite (void *, size_t, _off64_t)
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
fhandler_base::close ()
{

View File

@ -178,8 +178,13 @@ class fhandler_base
path_conv pc;
virtual bool use_archetype () const {return false;}
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;}
void set_error (int error) {pc.error = error;}
bool exists () const {return pc.exists ();}
@ -290,9 +295,24 @@ class fhandler_base
bool fork_fixup (HANDLE, HANDLE &, const char *);
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);
virtual int close_with_arch ();
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 (); }
virtual int __stdcall fstat (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 facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
int __stdcall link (const char *) __attribute__ ((regparm (2)));
size_t size () const { return sizeof (*this);}
};
class fhandler_base_overlapped: public fhandler_base
@ -612,6 +633,7 @@ public:
static int create (fhandler_pipe *[2], unsigned, int);
static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL);
friend class fhandler_fifo;
size_t size () const { return sizeof (*this);}
};
class fhandler_fifo: public fhandler_base_overlapped
@ -645,6 +667,7 @@ public:
select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *);
size_t size () const { return sizeof (*this);}
};
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)));
int ioctl (unsigned int cmd, void *);
select_record *select_read (select_stuff *);
size_t size () const { return sizeof (*this);}
};
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_exec ();
size_t size () const { return sizeof (*this);}
};
#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)));
_off64_t lseek (_off64_t offset, int whence);
int ioctl (unsigned int cmd, void *buf);
size_t size () const { return sizeof (*this);}
};
class fhandler_dev_tape: public fhandler_dev_raw
@ -749,7 +775,7 @@ class fhandler_dev_tape: public fhandler_dev_raw
public:
fhandler_dev_tape ();
virtual int open (int flags, mode_t mode = 0);
int open (int flags, mode_t mode = 0);
virtual int close ();
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 set_close_on_exec (bool val);
virtual int ioctl (unsigned int cmd, void *buf);
size_t size () const { return sizeof (*this);}
};
/* 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 pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
size_t size () const { return sizeof (*this);}
};
class fhandler_cygdrive: public fhandler_disk_file
@ -827,6 +855,7 @@ class fhandler_cygdrive: public fhandler_disk_file
void rewinddir (DIR *);
int closedir (DIR *);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
size_t size () const { return sizeof (*this);}
};
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_except (select_stuff *);
bool is_slow () {return true;}
size_t size () const { return sizeof (*this);}
};
#define acquire_output_mutex(ms) \
@ -1048,7 +1078,10 @@ class fhandler_console: public fhandler_termios
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)));
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 tcgetattr (struct termios *t);
/* Special dup as we must dup two handles */
int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *);
int init (HANDLE, DWORD, mode_t);
bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event);
@ -1080,6 +1110,7 @@ class fhandler_console: public fhandler_termios
bool is_slow () {return true;}
static bool need_invisible ();
static bool has_a () {return !invisible_console;}
size_t size () const { return sizeof (*this);}
};
class fhandler_tty_common: public fhandler_termios
@ -1124,9 +1155,11 @@ class fhandler_tty_slave: public fhandler_tty_common
public:
/* Constructor */
fhandler_tty_slave ();
fhandler_tty_slave (int);
bool use_archetype () const {return true;}
int open (int flags, mode_t mode = 0);
void open_setup (int flags);
ssize_t __stdcall write (const void *ptr, size_t len);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
int init (HANDLE, DWORD, mode_t);
@ -1136,6 +1169,7 @@ class fhandler_tty_slave: public fhandler_tty_common
int tcflush (int);
int ioctl (unsigned int cmd, void *);
int close ();
void cleanup ();
int dup (fhandler_base *child);
void fixup_after_fork (HANDLE parent);
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 fchmod (mode_t mode) __attribute__ ((regparm (1)));
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
size_t size () const { return sizeof (*this);}
};
class fhandler_pty_master: public fhandler_tty_common
@ -1161,6 +1196,7 @@ public:
/* Constructor */
fhandler_pty_master ();
virtual bool use_archetype () const {return true;}
DWORD pty_master_thread ();
int process_slave_output (char *buf, size_t len, int pktmode_on);
void doecho (const void *str, DWORD len);
@ -1169,6 +1205,7 @@ public:
ssize_t __stdcall write (const void *ptr, size_t len);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
int close ();
void cleanup ();
int tcsetattr (int a, const struct termios *t);
int tcgetattr (struct termios *t);
@ -1184,6 +1221,8 @@ public:
void fixup_after_fork (HANDLE parent);
void fixup_after_exec ();
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
@ -1191,11 +1230,14 @@ class fhandler_tty_master: public fhandler_pty_master
public:
/* Constructor */
fhandler_console *console; // device handler to perform real i/o.
bool use_archetype () const {return false;}
fhandler_tty_master ();
int init ();
int init_console ();
void set_winsize (bool);
bool is_tty_master () const {return true;}
size_t size () const { return sizeof (*this);}
};
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_write (select_stuff *);
select_record *select_except (select_stuff *);
size_t size () const { return sizeof (*this);}
};
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,
_off64_t offset, DWORD size,
void *address);
size_t size () const { return sizeof (*this);}
};
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);
int close ();
int dup (fhandler_base *child);
size_t size () const { return sizeof (*this);}
};
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);
bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
_off64_t offset, DWORD size, void *address);
} ;
size_t size () const { return sizeof (*this);}
};
class fhandler_dev_clipboard: public fhandler_base
{
@ -1288,6 +1334,7 @@ class fhandler_dev_clipboard: public fhandler_base
int dup (fhandler_base *child);
void fixup_after_exec ();
size_t size () const { return sizeof (*this);}
};
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_write (select_stuff *);
select_record *select_except (select_stuff *);
size_t size () const { return sizeof (*this);}
};
class fhandler_dev_dsp: public fhandler_base
@ -1334,12 +1382,13 @@ class fhandler_dev_dsp: public fhandler_base
int ioctl (unsigned int cmd, void *);
_off64_t lseek (_off64_t, int);
int close ();
int dup (fhandler_base *child);
void fixup_after_fork (HANDLE parent);
void fixup_after_exec ();
private:
void close_audio_in ();
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
@ -1374,6 +1423,7 @@ class fhandler_virtual : public fhandler_base
virtual bool fill_filebuf ();
char *get_filebuf () { return filebuf; }
void fixup_after_exec ();
virtual size_t size () const { return sizeof (*this);}
};
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 __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf ();
virtual size_t size () const { return sizeof (*this);}
};
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);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf ();
size_t size () const { return sizeof (*this);}
};
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 __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf ();
size_t size () const { return sizeof (*this);}
};
class fhandler_netdrive: public fhandler_virtual
@ -1431,6 +1484,7 @@ class fhandler_netdrive: public fhandler_virtual
int closedir (DIR *);
int open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
size_t size () const { return sizeof (*this);}
};
class fhandler_registry: public fhandler_proc
@ -1454,6 +1508,7 @@ class fhandler_registry: public fhandler_proc
bool fill_filebuf ();
int close ();
int dup (fhandler_base *child);
size_t size () const { return sizeof (*this);}
};
class pinfo;
@ -1468,6 +1523,7 @@ class fhandler_process: public fhandler_proc
int open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf ();
size_t size () const { return sizeof (*this);}
};
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 __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
bool fill_filebuf ();
size_t size () const { return sizeof (*this);}
};
struct fhandler_nodevice: public fhandler_base
@ -1492,7 +1549,7 @@ struct fhandler_nodevice: public fhandler_base
#define report_tty_counts(fh, call, use_op) \
termios_printf ("%s %s, %susecount %d",\
fh->ttyname (), call,\
use_op, ((fhandler_tty_slave *) fh)->archetype->usecount);
use_op, ((fhandler_tty_slave *) (fh->archetype ?: fh))->usecount);
typedef union
{

View File

@ -94,8 +94,6 @@ fhandler_console::get_tty_stuff (int flags = 0)
if (!shared_console_info->tty_min_state.ntty)
{
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->dwLastCursorPosition.X = -1;
@ -700,8 +698,6 @@ fhandler_console::open (int flags, mode_t)
set_io_handle (NULL);
set_output_handle (NULL);
set_flags ((flags & ~O_TEXT) | O_BINARY);
/* Open the input handle as handle_ */
h = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, sec_none_cloexec (flags),
@ -735,7 +731,6 @@ fhandler_console::open (int flags, mode_t)
tc->rstcons (false);
set_open_status ();
cygheap->manage_console_count ("fhandler_console::open", 1);
DWORD cflags;
if (GetConsoleMode (get_io_handle (), &cflags))
@ -748,6 +743,14 @@ fhandler_console::open (int flags, mode_t)
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
fhandler_console::close ()
{
@ -758,19 +761,6 @@ fhandler_console::close ()
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
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;
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)",
res, t, flags, t->c_lflag, t->c_oflag);
return res;
@ -980,6 +972,7 @@ fhandler_console::tcgetattr (struct termios *t)
fhandler_console::fhandler_console () :
fhandler_termios ()
{
dev ().parse (FH_CONSOLE);
trunc_buf.len = 0;
}
@ -2094,7 +2087,7 @@ fhandler_console::init (HANDLE h, DWORD a, mode_t bin)
flags = O_WRONLY;
if (a == (GENERIC_READ | GENERIC_WRITE))
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)
CloseHandle (h); /* Reopened by open */
@ -2127,24 +2120,7 @@ set_console_title (char *title)
void
fhandler_console::fixup_after_fork_exec (bool execing)
{
HANDLE h = get_handle ();
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);
}
get_tty_stuff ();
}
bool NO_COPY fhandler_console::invisible_console;

View File

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

View File

@ -113,7 +113,7 @@ fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
DWORD ms)
{
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);
if (res == WAIT_OBJECT_0)
{
@ -138,11 +138,11 @@ fhandler_tty_common::__release_output_mutex (const char *fn, int ln)
{
#ifndef DEBUGGING
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
if (osi > 0)
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);
ostack[osi].ln = -ln;
#endif
@ -299,7 +299,10 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
while (1)
{
if (!PeekNamedPipe (handle, NULL, 0, NULL, &n, NULL))
goto err;
{
termios_printf ("PeekNamedPipe failed, %E");
goto err;
}
if (n > 0)
break;
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. */
if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
goto out;
if (is_tty_master ())
continue;
if (is_nonblocking ())
{
set_errno (EAGAIN);
@ -321,17 +328,19 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
rc = -1;
goto out;
}
}
if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE)
goto err;
if (!ReadFile (handle, outbuf, rlen, &n, NULL))
{
termios_printf ("ReadFile failed, %E");
goto err;
}
}
termios_printf ("bytes read %u", n);
get_ttyp ()->write_error = 0;
if (output_done_event != NULL)
SetEvent (output_done_event);
SetEvent (output_done_event);
if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
continue;
@ -420,14 +429,17 @@ process_output (void *)
for (;;)
{
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)
termios_printf ("ReadFile %E");
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 */
fhandler_tty_slave::fhandler_tty_slave ()
fhandler_tty_slave::fhandler_tty_slave (int ntty)
: fhandler_tty_common (), inuse (NULL)
{}
{
if (ntty >= 0)
dev ().parse (DEV_TTYS_MAJOR, ntty);
}
/* FIXME: This function needs to close handles when it has
a failing condition. */
@ -472,28 +487,13 @@ fhandler_tty_slave::open (int flags, mode_t)
NULL
};
const char *errmsg = NULL;
for (HANDLE **h = handles; *h; h++)
**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);
cygwin_shared->tty.attach (get_unit ());
set_flags ((flags & ~O_TEXT) | O_BINARY);
/* Create synchronisation events */
char buf[MAX_PATH];
@ -505,6 +505,8 @@ fhandler_tty_slave::open (int flags, mode_t)
shared_name (buf, OUTPUT_DONE_EVENT, get_unit ());
output_done_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf);
const char *errmsg = NULL;
if (!(output_mutex = get_ttyp ()->open_output_mutex (MAXIMUM_ALLOWED)))
{
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
&& !output_done_event)
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;
err:
@ -672,8 +661,17 @@ err_no_msg:
return 0;
}
int
fhandler_tty_slave::close ()
void
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
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
close this normally. cgf 2006-05-20 */
cygheap->manage_console_count ("fhandler_tty_slave::close", -1);
archetype->usecount--;
report_tty_counts (this, "closed", "");
}
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;
}
int
fhandler_tty_slave::close ()
{
termios_printf ("closing last open %s handle", ttyname ());
if (inuse && !CloseHandle (inuse))
termios_printf ("CloseHandle (inuse), %E");
@ -702,7 +692,7 @@ fhandler_tty_slave::close ()
}
int
fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
fhandler_tty_slave::init (HANDLE h, DWORD a, mode_t)
{
int flags = 0;
@ -714,7 +704,7 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
if (a == (GENERIC_READ | GENERIC_WRITE))
flags = O_RDWR;
int ret = open (flags);
int ret = open_with_arch (flags);
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)
CloseHandle (f); /* Reopened by open */
if (h != INVALID_HANDLE_VALUE)
CloseHandle (h); /* Reopened by open */
return ret;
}
@ -1037,38 +1027,14 @@ out:
int
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);
report_tty_counts (child, "duped", "");
report_tty_counts (child, "duped slave", "");
return 0;
}
int
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", "");
return 0;
}
@ -1435,15 +1401,8 @@ fhandler_pty_master::open (int flags, mode_t)
set_flags ((flags & ~O_TEXT) | O_BINARY);
set_open_status ();
/* FIXME: Do this better someday */
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 ();
dwProcessId = GetCurrentProcessId ();
usecount = 0;
arch->usecount++;
char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")];
__small_sprintf (buf, "opened pty master for tty%d", get_unit ());
report_tty_counts (this, buf, "");
@ -1482,6 +1441,12 @@ fhandler_tty_common::close ()
return 0;
}
void
fhandler_pty_master::cleanup ()
{
report_tty_counts (this, "closing master", "");
}
int
fhandler_pty_master::close ()
{
@ -1489,25 +1454,12 @@ fhandler_pty_master::close ()
while (accept_input () > 0)
continue;
#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)",
arch->from_master, arch->to_master, arch->dwProcessId);
from_master, to_master, dwProcessId);
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];
pipe_request req = { (DWORD) -1 };
@ -1517,13 +1469,13 @@ fhandler_pty_master::close ()
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl",
&installation_key, get_unit ());
CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
CloseHandle (arch->master_ctl);
arch->master_thread->detach ();
CloseHandle (master_ctl);
master_thread->detach ();
}
if (!ForceCloseHandle (arch->from_master))
termios_printf ("error closing from_master %p, %E", arch->from_master);
if (!ForceCloseHandle (arch->to_master))
termios_printf ("error closing from_master %p, %E", arch->to_master);
if (!ForceCloseHandle (from_master))
termios_printf ("error closing from_master %p, %E", from_master);
if (!ForceCloseHandle (to_master))
termios_printf ("error closing from_master %p, %E", to_master);
}
fhandler_tty_common::close ();
@ -1674,7 +1626,7 @@ fhandler_tty_slave::fixup_after_exec ()
int
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)
return -1;
@ -1824,10 +1776,10 @@ reply:
}
static DWORD WINAPI
pty_master_thread (VOID *arg)
{
pty_master_thread (VOID *arg)
{
return ((fhandler_pty_master *) arg)->pty_master_thread ();
}
}
bool
fhandler_pty_master::setup (bool ispty)

View File

@ -371,12 +371,33 @@ _pinfo::_ctty (char *buf)
}
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))
{
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;
syscall_printf ("attaching %s sid %d, pid %d, pgid %d, tty->pgid %d, tty->sid %d",
__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 ();
if (tc->getpgid () == 0)
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.

View File

@ -101,7 +101,7 @@ close_all_files (bool norelease)
DuplicateHandle (GetCurrentProcess (), fh->get_output_handle (),
GetCurrentProcess (), &h,
0, false, DUPLICATE_SAME_ACCESS);
fh->close ();
fh->close_with_arch ();
if (!norelease)
cygheap->fdtab.release (i);
}
@ -601,7 +601,7 @@ unlink_nt (path_conv &pc)
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.
That's why we don't call try_to_bin on NFS.
Netapp filesystems don't understand the "move and delete" method
at all and have all kinds of weird effects. Just setting the delete
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
"Subsequently, the only legal operation by such a caller is
to close the open file handle."
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,
after the NtClose, but before we stop the transaction. This
@ -1107,25 +1107,18 @@ open (const char *unix_path, int flags, ...)
res = -1;
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;
res = -1;
}
else
{
fh->close_on_exec (flags & O_CLOEXEC);
if (!fh->open (flags, (mode & 07777) & ~cygheap->umask))
{
delete fh;
res = -1;
}
else
{
cygheap->fdtab[fd] = fh;
if ((res = fd) <= 2)
set_std_handle (res);
}
fd = fh;
if (fd <= 2)
set_std_handle (fd);
res = fd;
}
}
}
@ -1185,7 +1178,7 @@ close (int fd)
res = -1;
else
{
res = cfd->close ();
res = cfd->close_with_arch ();
cfd.release ();
}
@ -1974,7 +1967,7 @@ rename (const char *oldpath, const char *newpath)
filename has one of the blessed executable suffixes. */
if (!old_explicit_suffix && oldpc.known_suffix
&& !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");
removepc = &newpc;
@ -2040,7 +2033,7 @@ retry:
a temporary filename and then rename the temp filename to the
target filename. This renaming fails due to the jealous virus
scanner and the application fails to create the target file.
This kludge tries to work around that by yielding until the
sharing violation goes away, or a signal arrived, or after
about a second, give or take. */