(dll_crt0_1): Reflect renaming from tty_init to tty::init_session.
(do_exit): Reflect moving of tty_terminate into tty_list.
* exceptions.cc (events_init): Move tty_mutex stuff elsewhere.
* fhandler_console.cc (set_console_title): Use lock_ttys class.
* fhandler_termios.cc (fhandler_termios::bg_check): Make debug output more
accurate.
* fhandler_tty.cc (fhandler_tty_slave::open): Reflect move of attach_tty into
tty_list class. Don't attempt to grab master end of pty if master doesn't
exist.
(fhandler_pty_master::open): Reflect move of allocate_tty into tty_list class.
Use lock_ttys::release to release mutex. Improve debugging output.
(fhandler_pty_master::setup): Remove if 0'ed block. Fix argument to
SetNamedPipeHandleState.
* pinfo.cc (_pinfo::set_ctty): Lock ttys before setting sid/pgid. Improve
debugging. Add temporary debugging.
* tty.cc (tty_list::init_session): New function.
(tty::init_session): Rename from tty_init. Reflect move of attach_tty to
tty_list class.
(tty::create_master): Rename from create_tty_master.
(tty_list::attach): Rename from attach_tty. Reflect renaming of connect_tty to
connect. Ditto for allocate_tty.
(tty_terminate): Delete.
(tty_list::terminate): Subsume tty_terminate. Use lock_ttys rather than
manipulating mutex directly.
(tty_list::allocate): Rename from allocate_tty. Use lock_ttys rather than
manipulating mutex directly. Don't set sid here since linux apparently doesn't
do this. Reflect move of create_tty_master into tty.
(lock_ttys::lock_ttys): Define new constructor.
(lock_ttys::release): New function.
* tty.h (tty::exists): Return false immediately if !master_pid.
(tty::set_master_closed): Define new function.
(tty::create_master): Ditto.
(tty::init_session): Ditto.
(tty_list::mutex): New field.
(tty_list::allocate): Define new function.
(tty_list::connect): Ditto.
(tty_list::attach): Ditto.
(tty_list::init_session): Ditto.
(lock_ttys): New class.
(tty_init): Delete declaration.
(tty_terminate): Ditto.
(attach_tty): Ditto.
(create_tty_master): Ditto.
2006-06-03 Christopher Faylor <cgf@timesys.com>
+ * dcrt0.cc (dll_crt0_0): Call tty_list::init_session here.
+ (dll_crt0_1): Reflect renaming from tty_init to tty::init_session.
+ (do_exit): Reflect moving of tty_terminate into tty_list.
+ * exceptions.cc (events_init): Move tty_mutex stuff elsewhere.
+ * fhandler_console.cc (set_console_title): Use lock_ttys class.
+ * fhandler_termios.cc (fhandler_termios::bg_check): Make debug output
+ more accurate.
+ * fhandler_tty.cc (fhandler_tty_slave::open): Reflect move of
+ attach_tty into tty_list class. Don't attempt to grab master end of
+ pty if master doesn't exist.
+ (fhandler_pty_master::open): Reflect move of allocate_tty into tty_list
+ class. Use lock_ttys::release to release mutex. Improve debugging
+ output.
+ (fhandler_pty_master::setup): Remove if 0'ed block. Fix argument to
+ SetNamedPipeHandleState.
+ * pinfo.cc (_pinfo::set_ctty): Lock ttys before setting sid/pgid.
+ Improve debugging. Add temporary debugging.
+ * tty.cc (tty_list::init_session): New function.
+ (tty::init_session): Rename from tty_init. Reflect move of attach_tty
+ to tty_list class.
+ (tty::create_master): Rename from create_tty_master.
+ (tty_list::attach): Rename from attach_tty. Reflect renaming of
+ connect_tty to connect. Ditto for allocate_tty.
+ (tty_terminate): Delete.
+ (tty_list::terminate): Subsume tty_terminate. Use lock_ttys rather
+ than manipulating mutex directly.
+ (tty_list::allocate): Rename from allocate_tty. Use lock_ttys rather
+ than manipulating mutex directly. Don't set sid here since linux
+ apparently doesn't do this. Reflect move of create_tty_master into
+ tty.
+ (lock_ttys::lock_ttys): Define new constructor.
+ (lock_ttys::release): New function.
+ * tty.h (tty::exists): Return false immediately if !master_pid.
+ (tty::set_master_closed): Define new function.
+ (tty::create_master): Ditto.
+ (tty::init_session): Ditto.
+ (tty_list::mutex): New field.
+ (tty_list::allocate): Define new function.
+ (tty_list::connect): Ditto.
+ (tty_list::attach): Ditto.
+ (tty_list::init_session): Ditto.
+ (lock_ttys): New class.
+ (tty_init): Delete declaration.
+ (tty_terminate): Ditto.
+ (attach_tty): Ditto.
+ (create_tty_master): Ditto.
+
+2006-06-03 Christopher Faylor <cgf@timesys.com>
+
* Makefile.in (libdl.a): New library.
2006-06-03 Christopher Faylor <cgf@timesys.com>
/* Initialize events */
events_init ();
+ tty_list::init_session ();
cygheap->cwd.init ();
if (!threadfunc_ix)
system_printf ("internal error: couldn't determine location of thread function on stack. Expect signal problems.");
-
/* Connect to tty. */
- tty_init ();
+ tty::init_session ();
if (!__argc)
{
if (exit_state < ES_TTY_TERMINATE)
{
exit_state = ES_TTY_TERMINATE;
- tty_terminate ();
+ cygwin_shared->tty.terminate ();
}
myself.exit (n);
/* if any of these mutexes is owned, we will fail to start any cygwin app
until trapped app exits */
- ReleaseMutex (tty_mutex);
+ lock_ttys::release ();
/* prevent recursive exception handling */
char* rawenv = GetEnvironmentStrings () ;
do_exit (rc);
}
-HANDLE NO_COPY tty_mutex = NULL;
-
void
events_init ()
{
- char *name;
- char mutex_name[CYG_MAX_PATH];
- /* tty_mutex is on while searching for a tty slot. It's necessary
- while finding console window handle */
-
- if (!(tty_mutex = CreateMutex (&sec_all_nih, FALSE,
- name = shared_name (mutex_name,
- "tty_mutex", 0))))
- api_fatal ("can't create title mutex '%s', %E", name);
-
- ProtectHandle (tty_mutex);
mask_sync.init ("mask_sync");
windows_system_directory[0] = '\0';
GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
void
_cygtls::signal_debugger (int sig)
{
- if (being_debugged ())
+ if (isinitialized () && being_debugged ())
{
char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
__small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context);
void __stdcall
set_console_title (char *title)
{
- int rc;
char buf[257];
strncpy (buf, title, sizeof (buf) - 1);
buf[sizeof (buf) - 1] = '\0';
- if ((rc = WaitForSingleObject (tty_mutex, 15000)) != WAIT_OBJECT_0)
- sigproc_printf ("wait for title mutex failed rc %d, %E", rc);
+ lock_ttys here (15000);
SetConsoleTitle (buf);
- ReleaseMutex (tty_mutex);
debug_printf ("title '%s'", buf);
}
if (sig < 0)
sig = -sig;
- termios_printf ("bg I/O pgid %d, tpgid %d, %s", myself->pgid, tc->getpgid (),
- myctty ());
+ termios_printf ("bg I/O pgid %d, tpgid %d, %s, ntty tty%d", myself->pgid, tc->getpgid (),
+ myctty (), tc->ntty);
if (tc->getsid () == 0)
{
tcinit (cygwin_shared->tty[get_unit ()]);
- attach_tty (get_unit ());
+ cygwin_shared->tty.attach (get_unit ());
set_flags ((flags & ~O_TEXT) | O_BINARY);
/* Create synchronisation events */
|| !cygserver_attach_tty (&from_master_local, &to_master_local))
#endif
{
+ if (get_ttyp ()->master_pid < 0)
+ {
+ set_errno (EAGAIN);
+ termios_printf ("*** master is closed");
+ return 0;
+ }
pinfo p (get_ttyp ()->master_pid);
if (!p)
{
goto out;
}
- int ntty = cygwin_shared->tty.allocate_tty (false);
+ int ntty;
+ ntty = cygwin_shared->tty.allocate (false);
if (ntty < 0)
return 0;
slave.setunit (ntty);
if (!setup (*cygwin_shared->tty[ntty]))
{
- ReleaseMutex (tty_mutex); // lock was set in allocate_tty
+ lock_ttys::release ();
return 0;
}
- ReleaseMutex (tty_mutex); // lock was set in allocate_tty
+ lock_ttys::release ();
set_flags ((flags & ~O_TEXT) | O_BINARY);
set_open_status ();
//
out:
usecount = 0;
arch->usecount++;
- report_tty_counts (this, "opened master", "");
- termios_printf ("opened pty master tty%d", get_unit ());
+ char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")];
+ __small_sprintf (buf, "opened pty master for tty%d", get_unit ());
+ report_tty_counts (this, buf, "");
return 1;
}
}
fhandler_tty_common::close ();
- if (!hExeced && get_ttyp ()->master_pid == myself->pid)
- get_ttyp ()->init ();
+ if (hExeced || get_ttyp ()->master_pid != myself->pid)
+ termios_printf ("not clearing: %d, master_pid %d", hExeced, get_ttyp ()->master_pid);
+ else
+ get_ttyp ()->set_master_closed ();
return 0;
}
/* Create communication pipes */
-#if 0 // CGF: don't think this is needed since it is handled by the constructor
- input_handle = io_handle = output_done_event = ioctl_done_event =
- ioctl_request_event = input_available_event = output_mutex = input_mutex NULL;
-#endif
-
/* FIXME: should this be sec_none_nih? */
if (!CreatePipe (&from_master, &get_output_handle (), &sec_all, 128 * 1024))
{
goto err;
}
- if (!SetNamedPipeHandleState (&get_output_handle (), &pipe_mode, NULL, NULL))
+ if (!SetNamedPipeHandleState (get_output_handle (), &pipe_mode, NULL, NULL))
termios_printf ("can't set output_handle(%p) to non-blocking mode",
get_output_handle ());
if ((ctty < 0 || ctty == tc->ntty) && !(flags & O_NOCTTY))
{
ctty = tc->ntty;
- syscall_printf ("attached %s sid %d, pid %d, tty->pgid %d, tty->sid %d",
- __ctty (), sid, pid, pgid, tc->getsid ());
+ 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 ());
pinfo p (tc->getsid ());
if (sid == pid && (!p || p->pid == pid || !p->exists ()))
{
+#ifdef DEBUGGING
+ debug_printf ("resetting %s sid. Was %d, now %d. pgid was %d, now %d.",
+ __ctty (), tc->getsid (), sid, tc->getpgid (), pgid);
+#else
paranoid_printf ("resetting %s sid. Was %d, now %d. pgid was %d, now %d.",
__ctty (), tc->getsid (), sid, tc->getpgid (), pgid);
+#endif
/* We are the session leader */
tc->setsid (sid);
tc->setpgid (pgid);
else
sid = tc->getsid ();
if (tc->getpgid () == 0)
- tc->setpgid (pgid);
+{debug_printf ("setting pgid to %d", pgid);
+ tc->setpgid (pgid);
+}
if (cygheap->ctty != arch)
{
debug_printf ("cygheap->ctty %p, arch %p", cygheap->ctty, arch);
return myself->ctty;
}
+HANDLE NO_COPY tty_list::mutex = NULL;
+
void __stdcall
-tty_init ()
+tty_list::init_session ()
+{
+ char mutex_name[CYG_MAX_PATH];
+ /* tty_list::mutex is used while searching for a tty slot. It's necessary
+ while finding console window handle */
+
+ char *name = shared_name (mutex_name, "tty_list::mutex", 0);
+ if (!(mutex = CreateMutex (&sec_all_nih, FALSE, name)))
+ api_fatal ("can't create tty_list::mutex '%s', %E", name);
+ ProtectHandle (mutex);
+}
+
+void __stdcall
+tty::init_session ()
{
if (!myself->cygstarted && NOTSTATE (myself, PID_CYGPARENT))
cygheap->fdtab.get_debugger_info ();
return;
if (myself->ctty == -1)
if (NOTSTATE (myself, PID_CYGPARENT))
- myself->ctty = attach_tty (myself->ctty);
+ myself->ctty = cygwin_shared->tty.attach (myself->ctty);
else
return;
if (myself->ctty == -1)
/* Create session's master tty */
void __stdcall
-create_tty_master (int ttynum)
+tty::create_master (int ttynum)
{
device ttym = *ttym_dev;
ttym.setunit (ttynum); /* CGF FIXME device */
}
}
-void __stdcall
-tty_terminate ()
-{
- if (NOTSTATE (myself, PID_USETTY))
- return;
- cygwin_shared->tty.terminate ();
-}
-
int __stdcall
-attach_tty (int num)
+tty_list::attach (int num)
{
if (num != -1)
{
- return cygwin_shared->tty.connect_tty (num);
+ return connect (num);
}
if (NOTSTATE (myself, PID_USETTY))
return -1;
- return cygwin_shared->tty.allocate_tty (true);
+ return allocate (true);
}
void
tty_list::terminate ()
{
+ if (NOTSTATE (myself, PID_USETTY))
+ return;
int ttynum = myself->ctty;
/* Keep master running till there are connected clients */
low_priority_sleep (200);
}
- if (WaitForSingleObject (tty_mutex, INFINITE) == WAIT_FAILED)
- termios_printf ("WFSO for tty_mutex %p failed, %E", tty_mutex);
+ lock_ttys here ();
termios_printf ("tty %d master about to finish", ttynum);
CloseHandle (tty_master->get_io_handle ());
char buf[20];
__small_sprintf (buf, "tty%d", ttynum);
logout (buf);
-
- ReleaseMutex (tty_mutex);
}
}
int
-tty_list::connect_tty (int ttynum)
+tty_list::connect (int ttynum)
{
if (ttynum < 0 || ttynum >= NTTYS)
{
If flag == 0, just find a free tty.
*/
int
-tty_list::allocate_tty (bool with_console)
+tty_list::allocate (bool with_console)
{
HWND console;
int freetty = -1;
/* FIXME: This whole function needs a protective mutex. */
- if (WaitForSingleObject (tty_mutex, INFINITE) == WAIT_FAILED)
- termios_printf ("WFSO for tty_mutex %p failed, %E", tty_mutex);
+ lock_ttys here;
if (!with_console)
console = NULL;
t = ttys + freetty;
t->init ();
t->setsid (-1);
- t->setpgid (myself->pgid);
t->sethwnd (console);
out:
if (freetty < 0)
- {
- ReleaseMutex (tty_mutex);
- system_printf ("No tty allocated");
- }
+ system_printf ("No tty allocated");
else if (!with_console)
{
termios_printf ("tty%d allocated", freetty);
- /* exit with tty_mutex still held -- caller has more work to do */
+ here.dont_release (); /* exit with mutex still held -- caller has more work to do */
}
else
{
termios_printf ("console %p associated with tty%d", console, freetty);
if (!hmaster)
- create_tty_master (freetty);
- ReleaseMutex (tty_mutex);
+ tty::create_master (freetty);
}
return freetty;
}
termios_printf ("created event %s", buf);
return hev;
}
+
+lock_ttys::lock_ttys (DWORD howlong): release_me (true)
+{
+ if (WaitForSingleObject (tty_list::mutex, howlong) == WAIT_FAILED)
+ {
+ termios_printf ("WFSO for mutex %p failed, %E", tty_list::mutex);
+ release_me = false;
+ }
+}
+
+void
+lock_ttys::release ()
+{
+ ReleaseMutex (tty_list::mutex);
+}
HANDLE open_input_mutex ();
bool exists ()
{
+ if (!master_pid)
+ return false;
HANDLE h = open_output_mutex ();
if (h)
{
}
return slave_alive ();
}
+ void set_master_closed () {master_pid = -1;}
+ static void __stdcall create_master (int);
+ static void __stdcall init_session ();
friend class fhandler_pty_master;
};
class tty_list
{
tty ttys[NTTYS];
+ static HANDLE mutex;
public:
tty * operator [](int n) {return ttys + n;}
- int allocate_tty (bool); /* true if allocate a tty, pty otherwise */
- int connect_tty (int);
+ int allocate (bool); /* true if allocate a tty, pty otherwise */
+ int connect (int);
void terminate ();
void init ();
tty_min *get_tty (int n);
+ int __stdcall attach (int);
+ static void __stdcall init_session ();
+ friend class lock_ttys;
+};
+
+class lock_ttys
+{
+ bool release_me;
+public:
+ lock_ttys (DWORD = INFINITE);
+ static void release ();
+ void dont_release () {release_me = false;}
+ ~lock_ttys ()
+ {
+ if (release_me)
+ release ();
+ }
};
-void __stdcall tty_init ();
-void __stdcall tty_terminate ();
-int __stdcall attach_tty (int);
-void __stdcall create_tty_master (int);
extern "C" int ttyslot (void);