diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index b79d488e2..34a44682b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2004-05-17 Christopher Faylor + + Change the name "title_mutex" to "tty_mutex" throughout. + * tty.h (tty_list::allocate_tty): Turn argument into a boolean. + * tty.cc (tty_list::init): Protect entire allocation operation with + tty_mutex (formerly title_mutex) to protect against allocation races. + 2004-05-16 Corinna Vinschen * fhandler_socket.cc (fhandler_socket::recvfrom): Use original flags diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 3b7be7042..44f37cbbe 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -330,7 +330,7 @@ try_to_debug (bool waitloop) /* if any of these mutexes is owned, we will fail to start any cygwin app until trapped app exits */ - ReleaseMutex (title_mutex); + ReleaseMutex (tty_mutex); /* prevent recursive exception handling */ char* rawenv = GetEnvironmentStrings () ; @@ -1117,22 +1117,22 @@ signal_exit (int rc) do_exit (rc); } -HANDLE NO_COPY title_mutex = NULL; +HANDLE NO_COPY tty_mutex = NULL; void events_init (void) { char *name; char mutex_name[CYG_MAX_PATH]; - /* title_mutex protects modification of console title. It's necessary + /* tty_mutex is on while searching for a tty slot. It's necessary while finding console window handle */ - if (!(title_mutex = CreateMutex (&sec_all_nih, FALSE, + if (!(tty_mutex = CreateMutex (&sec_all_nih, FALSE, name = shared_name (mutex_name, - "title_mutex", 0)))) + "tty_mutex", 0)))) api_fatal ("can't create title mutex '%s', %E", name); - ProtectHandle (title_mutex); + ProtectHandle (tty_mutex); new_muto (mask_sync); windows_system_directory[0] = '\0'; (void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2); diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 616090dfd..242182ec3 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -1776,10 +1776,10 @@ set_console_title (char *title) char buf[257]; strncpy (buf, title, sizeof (buf) - 1); buf[sizeof (buf) - 1] = '\0'; - if ((rc = WaitForSingleObject (title_mutex, 15000)) != WAIT_OBJECT_0) + if ((rc = WaitForSingleObject (tty_mutex, 15000)) != WAIT_OBJECT_0) sigproc_printf ("wait for title mutex failed rc %d, %E", rc); SetConsoleTitle (buf); - ReleaseMutex (title_mutex); + ReleaseMutex (tty_mutex); debug_printf ("title '%s'", buf); } diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 6233971cb..8b98c2dba 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -1157,7 +1157,7 @@ fhandler_pty_master::fhandler_pty_master () int fhandler_pty_master::open (int flags, mode_t) { - int ntty = cygwin_shared->tty.allocate_tty (0); + int ntty = cygwin_shared->tty.allocate_tty (false); if (ntty < 0) return 0; diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 000de2e6e..6ced84bb0 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -121,7 +121,7 @@ attach_tty (int num) } if (NOTSTATE (myself, PID_USETTY)) return -1; - return cygwin_shared->tty.allocate_tty (1); + return cygwin_shared->tty.allocate_tty (true); } void @@ -196,32 +196,28 @@ tty_list::init (void) If flag == 0, just find a free tty. */ int -tty_list::allocate_tty (int with_console) +tty_list::allocate_tty (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); + if (!with_console) console = NULL; else if (!(console = GetConsoleWindow ())) { - char *oldtitle = new char [TITLESIZE]; + char oldtitle[TITLESIZE]; - if (!oldtitle) - { - termios_printf ("Can't *allocate console title buffer"); - return -1; - } if (!GetConsoleTitle (oldtitle, TITLESIZE)) { termios_printf ("Can't read console title"); - return -1; + goto out; } - if (WaitForSingleObject (title_mutex, INFINITE) == WAIT_FAILED) - termios_printf ("WFSO for title_mutext %p failed, %E", title_mutex); - char buf[40]; __small_sprintf (buf, "cygwin.find.console.%d", myself->pid); @@ -234,16 +230,15 @@ tty_list::allocate_tty (int with_console) } SetConsoleTitle (oldtitle); Sleep (40); - ReleaseMutex (title_mutex); if (console == NULL) { termios_printf ("Can't find console window"); - return -1; + goto out; } } - /* Is a tty allocated for console? */ - int freetty = -1; + HANDLE hmaster = NULL; + /* Is a tty allocated for console? */ for (int i = 0; i < NTTYS; i++) { if (!ttys[i].exists ()) @@ -254,17 +249,19 @@ tty_list::allocate_tty (int with_console) break; /* No. We've got one. */ } + /* FIXME: Is this right? We can potentially query a "nonexistent" + tty slot after falling through from the above? */ if (with_console && ttys[i].gethwnd () == console) { termios_printf ("console %x already associated with tty%d", console, i); /* Is the master alive? */ - HANDLE hMaster; - hMaster = OpenProcess (PROCESS_DUP_HANDLE, FALSE, ttys[i].master_pid); - if (hMaster) + hmaster = OpenProcess (PROCESS_DUP_HANDLE, FALSE, ttys[i].master_pid); + if (hmaster) { - CloseHandle (hMaster); - return i; + CloseHandle (hmaster); + freetty = i; + goto out; } /* Master is dead */ freetty = i; @@ -274,23 +271,27 @@ tty_list::allocate_tty (int with_console) /* There is no tty allocated to console, allocate the first free found */ if (freetty == -1) - { - system_printf ("No free ttys available"); - return -1; - } - tty *t = ttys + freetty; + goto out; + + tty *t; + t = ttys + freetty; t->init (); t->setsid (-1); t->setpgid (myself->pgid); t->sethwnd (console); - if (with_console) - { - termios_printf ("console %x associated with tty%d", console, freetty); - create_tty_master (freetty); - } - else +out: + if (freetty < 0) + system_printf ("No tty allocated"); + else if (!with_console) termios_printf ("tty%d allocated", freetty); + else + { + termios_printf ("console %p associated with tty%d", console, freetty); + if (!hmaster) + create_tty_master (freetty); + } + ReleaseMutex (tty_mutex); return freetty; } diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index d29b2e903..5602a0530 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -125,7 +125,7 @@ class tty_list public: tty * operator [](int n) {return ttys + n;} - int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */ + int allocate_tty (bool); /* true if allocate a tty, pty otherwise */ int connect_tty (int); void terminate (); void init (); diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index cd698ba56..49a880ea9 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -134,7 +134,7 @@ extern int cygserver_running; #include "debug.h" /* Events/mutexes */ -extern HANDLE title_mutex; +extern HANDLE tty_mutex; /**************************** Convenience ******************************/