Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog93
-rw-r--r--winsup/cygwin/cygheap.cc6
-rw-r--r--winsup/cygwin/debug.cc5
-rw-r--r--winsup/cygwin/devices.cc9
-rw-r--r--winsup/cygwin/devices.h1
-rw-r--r--winsup/cygwin/devices.in9
-rw-r--r--winsup/cygwin/dtable.cc170
-rw-r--r--winsup/cygwin/fhandler.cc78
-rw-r--r--winsup/cygwin/fhandler.h79
-rw-r--r--winsup/cygwin/fhandler_console.cc50
-rw-r--r--winsup/cygwin/fhandler_dsp.cc50
-rw-r--r--winsup/cygwin/fhandler_tty.cc186
-rw-r--r--winsup/cygwin/pinfo.cc47
-rw-r--r--winsup/cygwin/syscalls.cc31
14 files changed, 408 insertions, 406 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index df65b3bf5..7ef8f0101 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 8dde3dfe9..8a2a1f4dc 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -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;
}
diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc
index bea256cae..3e2aa1145 100644
--- a/winsup/cygwin/debug.cc
+++ b/winsup/cygwin/debug.cc
@@ -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*/
diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc
index 569d239e1..0bcaae0bc 100644
--- a/winsup/cygwin/devices.cc
+++ b/winsup/cygwin/devices.cc
@@ -43440,15 +43440,6 @@ device::parse (_dev_t 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)
{
int base;
diff --git a/winsup/cygwin/devices.h b/winsup/cygwin/devices.h
index b4927f1ba..5c9909a5f 100644
--- a/winsup/cygwin/devices.h
+++ b/winsup/cygwin/devices.h
@@ -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;}
diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in
index 7ce8994bb..1b59d9493 100644
--- a/winsup/cygwin/devices.in
+++ b/winsup/cygwin/devices.in
@@ -147,15 +147,6 @@ device::parse (_dev_t 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)
{
int base;
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 5fbe0f4b9..654526065 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -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)
{
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 9fad7ce4d..304feed63 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -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)
@@ -1030,6 +1064,48 @@ fhandler_base::pwrite (void *, size_t, _off64_t)
}
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 ()
{
int res = -1;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 14922b8b9..6ceaff33a 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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
{
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index b33b14dee..8fe4414cc 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -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;
diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc
index f784ca358..488cd864e 100644
--- a/winsup/cygwin/fhandler_dsp.cc
+++ b/winsup/cygwin/fhandler_dsp.cc
@@ -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;
}
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index f55eab21e..42e539191 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -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)
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 2096475a9..820559e0f 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -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.
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 5585b332a..d122c8dc2 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -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. */