* dcrt0.cc (jit_debug): New global.

(initial_env): Set jit_debug when we are automatically starting a gdb process.
* dtable.cc (dtable::get_debugger_info): Don't tty tricks when we are being
debugged by our own captive gdb, as determined by jit_debug == true.
(dtable::init_std_file_from_handle): Detect errors when initializing a tty
early rather than at random points later.
* fhandler.h (fhandler_*::init): Return int to indicate success/failure.
* fhandler.cc (fhandler_base::init): Reflect change in return value.
* pipe.cc (fhandler_pipe::init): Ditto.
(fhandler_pipe::create_selectable): Don't say we're retrying when we aren't.
* fhandler_console.cc (fhandler_console::init): Ditto.  Return success/failure.
* fhandler_serial.cc (fhandler_serial::init): Ditto.
* fhandler_tty.cc (fhandler_tty_slave::init): Ditto.
(fhandler_tty_slave::open): Make debugging output more detailed.
* tty.cc (tty_list::terminate): Don't close I/O handles before all slaves have
checked in.
(tty::slave_alive): Make a non-inlined function.  Check if tty pipe handles can
be created as an additional exists check.
* tty.h (tty::slave_alive): Just define here.
This commit is contained in:
Christopher Faylor 2009-07-03 18:05:51 +00:00
parent 3e62013829
commit 3c4f2024a1
11 changed files with 85 additions and 38 deletions

View File

@ -1,3 +1,30 @@
2009-07-03 Christopher Faylor <me+cygwin@cgf.cx>
* dcrt0.cc (jit_debug): New global.
(initial_env): Set jit_debug when we are automatically starting a gdb
process.
* dtable.cc (dtable::get_debugger_info): Don't tty tricks when we are
being debugged by our own captive gdb, as determined by jit_debug ==
true.
(dtable::init_std_file_from_handle): Detect errors when initializing a
tty early rather than at random points later.
* fhandler.h (fhandler_*::init): Return int to indicate
success/failure.
* fhandler.cc (fhandler_base::init): Reflect change in return value.
* pipe.cc (fhandler_pipe::init): Ditto.
(fhandler_pipe::create_selectable): Don't say we're retrying when we
aren't.
* fhandler_console.cc (fhandler_console::init): Ditto. Return
success/failure.
* fhandler_serial.cc (fhandler_serial::init): Ditto.
* fhandler_tty.cc (fhandler_tty_slave::init): Ditto.
(fhandler_tty_slave::open): Make debugging output more detailed.
* tty.cc (tty_list::terminate): Don't close I/O handles before all
slaves have checked in.
(tty::slave_alive): Make a non-inlined function. Check if tty pipe
handles can be created as an additional exists check.
* tty.h (tty::slave_alive): Just define here.
2009-07-03 Corinna Vinschen <corinna@vinschen.de> 2009-07-03 Corinna Vinschen <corinna@vinschen.de>
* posix.sgml: Add fpurge and mkstemps to BSD list. * posix.sgml: Add fpurge and mkstemps to BSD list.

View File

@ -48,6 +48,8 @@ static char NO_COPY **envp;
static char title_buf[TITLESIZE + 1]; static char title_buf[TITLESIZE + 1];
bool NO_COPY jit_debug;
static void static void
do_global_dtors () do_global_dtors ()
{ {
@ -499,6 +501,7 @@ initial_env ()
if (strstr (buf1, buf)) if (strstr (buf1, buf))
{ {
error_start_init (p); error_start_init (p);
jit_debug = true;
try_to_debug (); try_to_debug ();
console_printf ("*** Sending Break. gdb may issue spurious SIGTRAP message.\n"); console_printf ("*** Sending Break. gdb may issue spurious SIGTRAP message.\n");
break_here (); break_here ();

View File

@ -109,7 +109,8 @@ dtable::extend (int howmuch)
void void
dtable::get_debugger_info () dtable::get_debugger_info ()
{ {
if (being_debugged ()) extern bool jit_debug;
if (!jit_debug && being_debugged ())
{ {
char std[3][sizeof ("/dev/ttyNNNN")]; char std[3][sizeof ("/dev/ttyNNNN")];
std[0][0] = std[1][0] = std [2][0] = '\0'; std[0][0] = std[1][0] = std [2][0] = '\0';
@ -383,9 +384,11 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
This needs further investigation but the workaround not to close This needs further investigation but the workaround not to close
the handles will have a marginal hit of three extra handles per the handles will have a marginal hit of three extra handles per
process at most. */ process at most. */
fh->init (dev == FH_CONSOLE && wincap.has_console_handle_problem () if (fh->init (dev == FH_CONSOLE && wincap.has_console_handle_problem ()
? INVALID_HANDLE_VALUE : handle, access, bin); ? INVALID_HANDLE_VALUE : handle, access, bin))
set_std_handle (fd); set_std_handle (fd);
else
api_fatal ("couldn't initialize fd %d for %s", fd, fh->get_name ());
paranoid_printf ("fd %d, handle %p", fd, handle); paranoid_printf ("fd %d, handle %p", fd, handle);
} }
} }

View File

@ -1123,7 +1123,7 @@ fhandler_base::fstatvfs (struct statvfs *sfs)
return fh.fstatvfs (sfs); return fh.fstatvfs (sfs);
} }
void int
fhandler_base::init (HANDLE f, DWORD a, mode_t bin) fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
{ {
set_io_handle (f); set_io_handle (f);
@ -1139,6 +1139,7 @@ fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
set_flags (flags | bin); set_flags (flags | bin);
set_open_status (); set_open_status ();
debug_printf ("created new fhandler_base for handle %p, bin %d", f, rbinary ()); debug_printf ("created new fhandler_base for handle %p, bin %d", f, rbinary ());
return 1;
} }
int int

View File

@ -325,7 +325,7 @@ class fhandler_base
void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;}
virtual void init (HANDLE, DWORD, mode_t); virtual int init (HANDLE, DWORD, mode_t);
virtual int tcflush (int); virtual int tcflush (int);
virtual int tcsendbreak (int); virtual int tcsendbreak (int);
@ -566,7 +566,7 @@ public:
int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3))); int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3))); int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
int ready_for_read (int fd, DWORD howlong); int ready_for_read (int fd, DWORD howlong);
void init (HANDLE, DWORD, mode_t); int init (HANDLE, DWORD, mode_t);
static int create (fhandler_pipe *[2], unsigned, int); static int create (fhandler_pipe *[2], unsigned, int);
static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL); static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL);
friend class fhandler_fifo; friend class fhandler_fifo;
@ -771,7 +771,7 @@ class fhandler_serial: public fhandler_base
int open (int flags, mode_t mode); int open (int flags, mode_t mode);
int close (); int close ();
void init (HANDLE h, DWORD a, mode_t flags); int init (HANDLE h, DWORD a, mode_t flags);
void overlapped_setup (); void overlapped_setup ();
int dup (fhandler_base *child); int dup (fhandler_base *child);
void raw_read (void *ptr, size_t& ulen); void raw_read (void *ptr, size_t& ulen);
@ -971,7 +971,7 @@ class fhandler_console: public fhandler_termios
int dup (fhandler_base *child); int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
void init (HANDLE, DWORD, mode_t); int init (HANDLE, DWORD, mode_t);
bool mouse_aware () {return dev_state->use_mouse;} bool mouse_aware () {return dev_state->use_mouse;}
select_record *select_read (select_stuff *); select_record *select_read (select_stuff *);
@ -1032,7 +1032,7 @@ class fhandler_tty_slave: public fhandler_tty_common
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); int write (const void *ptr, size_t len);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
void init (HANDLE, DWORD, mode_t); int init (HANDLE, DWORD, mode_t);
int tcsetattr (int a, const struct termios *t); int tcsetattr (int a, const struct termios *t);
int tcgetattr (struct termios *t); int tcgetattr (struct termios *t);

View File

@ -1855,7 +1855,7 @@ get_nonascii_key (INPUT_RECORD& input_rec, char *tmp)
return NULL; return NULL;
} }
void int
fhandler_console::init (HANDLE f, DWORD a, mode_t bin) fhandler_console::init (HANDLE f, DWORD a, mode_t bin)
{ {
// this->fhandler_termios::init (f, mode, bin); // this->fhandler_termios::init (f, mode, bin);
@ -1873,7 +1873,7 @@ fhandler_console::init (HANDLE f, DWORD a, mode_t bin)
if (f != INVALID_HANDLE_VALUE) if (f != INVALID_HANDLE_VALUE)
CloseHandle (f); /* Reopened by open */ CloseHandle (f); /* Reopened by open */
tcsetattr (0, &tc->ti); return !tcsetattr (0, &tc->ti);
} }
int int

View File

@ -190,10 +190,10 @@ err:
return -1; return -1;
} }
void int
fhandler_serial::init (HANDLE f, DWORD flags, mode_t bin) fhandler_serial::init (HANDLE f, DWORD flags, mode_t bin)
{ {
open (flags, bin & (O_BINARY | O_TEXT)); return open (flags, bin & (O_BINARY | O_TEXT));
} }
int int

View File

@ -559,7 +559,8 @@ fhandler_tty_slave::open (int flags, mode_t)
hMainProc, &from_master_local, 0, TRUE, hMainProc, &from_master_local, 0, TRUE,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
termios_printf ("can't duplicate input, %E"); termios_printf ("can't duplicate input from %u/%p, %E",
get_ttyp ()->master_pid, get_ttyp ()->from_master);
__seterrno (); __seterrno ();
return 0; return 0;
} }
@ -654,7 +655,7 @@ fhandler_tty_slave::cygserver_attach_tty (LPHANDLE from_master_ptr,
return 1; return 1;
} }
void int
fhandler_tty_slave::init (HANDLE, DWORD a, mode_t) fhandler_tty_slave::init (HANDLE, DWORD a, mode_t)
{ {
int flags = 0; int flags = 0;
@ -667,7 +668,7 @@ fhandler_tty_slave::init (HANDLE, DWORD a, mode_t)
if (a == (GENERIC_READ | GENERIC_WRITE)) if (a == (GENERIC_READ | GENERIC_WRITE))
flags = O_RDWR; flags = O_RDWR;
open (flags); return open (flags);
} }
int int

View File

@ -29,7 +29,7 @@ fhandler_pipe::fhandler_pipe ()
uninterruptible_io (true); uninterruptible_io (true);
} }
void int
fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode) fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode)
{ {
// FIXME: Have to clean this up someday // FIXME: Have to clean this up someday
@ -53,6 +53,7 @@ fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode)
if (mode & O_NOINHERIT) if (mode & O_NOINHERIT)
close_on_exec (true); close_on_exec (true);
setup_overlapped (opened_properly); setup_overlapped (opened_properly);
return 1;
} }
extern "C" int sscanf (const char *, const char *, ...); extern "C" int sscanf (const char *, const char *, ...);
@ -259,12 +260,12 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r,
case ERROR_PIPE_BUSY: case ERROR_PIPE_BUSY:
/* The pipe is already open with compatible parameters. /* The pipe is already open with compatible parameters.
Pick a new name and retry. */ Pick a new name and retry. */
debug_printf ("pipe busy, retrying"); debug_printf ("pipe busy", name ? ", retrying" : "");
break; break;
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
/* The pipe is already open with incompatible parameters. /* The pipe is already open with incompatible parameters.
Pick a new name and retry. */ Pick a new name and retry. */
debug_printf ("pipe access denied, retrying"); debug_printf ("pipe access denied%s", name ? ", retrying" : "");
break; break;
default: default:
{ {

View File

@ -147,8 +147,6 @@ tty_list::terminate ()
if (ttynum != -1 && tty_master && ttys[ttynum].master_pid == myself->pid) if (ttynum != -1 && tty_master && ttys[ttynum].master_pid == myself->pid)
{ {
tty *t = ttys + ttynum; tty *t = ttys + ttynum;
CloseHandle (tty_master->from_master);
CloseHandle (tty_master->to_master);
/* Wait for children which rely on tty handling in this process to /* Wait for children which rely on tty handling in this process to
go away */ go away */
for (int i = 0; ; i++) for (int i = 0; ; i++)
@ -166,6 +164,8 @@ tty_list::terminate ()
} }
lock_ttys here (); lock_ttys here ();
CloseHandle (tty_master->from_master);
CloseHandle (tty_master->to_master);
termios_printf ("tty %d master about to finish", ttynum); termios_printf ("tty %d master about to finish", ttynum);
CloseHandle (tty_master->get_io_handle ()); CloseHandle (tty_master->get_io_handle ());
@ -209,7 +209,7 @@ tty_list::init ()
/* Search for tty class for our console. Allocate new tty if our process is /* Search for tty class for our console. Allocate new tty if our process is
the only cygwin process in the current console. the only cygwin process in the current console.
Return tty number or -1 if error. Return tty number or -1 if error.
If flag == 0, just find a free tty. If with_console == 0, just find a free tty.
*/ */
int int
tty_list::allocate (bool with_console) tty_list::allocate (bool with_console)
@ -218,8 +218,6 @@ tty_list::allocate (bool with_console)
int freetty = -1; int freetty = -1;
HANDLE hmaster = NULL; HANDLE hmaster = NULL;
/* FIXME: This whole function needs a protective mutex. */
lock_ttys here; lock_ttys here;
if (!with_console) if (!with_console)
@ -261,7 +259,7 @@ tty_list::allocate (bool with_console)
} }
} }
/* There is no tty allocated to console, allocate the first free found */ /* There is no tty allocated to console; allocate the first free found */
if (freetty == -1) if (freetty == -1)
goto out; goto out;
@ -294,6 +292,30 @@ tty::slave_alive ()
return alive (TTY_SLAVE_ALIVE); return alive (TTY_SLAVE_ALIVE);
} }
bool
tty::exists ()
{
/* Attempt to open the from-master side of the tty. If it is accessible
then it exists although it may have been privileges to actually use it. */
char pipename[sizeof("ttyNNNN-from-master")];
__small_sprintf (pipename, "tty%d-from-master", ntty);
HANDLE r, w;
int res = fhandler_pipe::create_selectable (&sec_none_nih, r, w, 0, pipename);
if (res)
return true;
CloseHandle (r);
CloseHandle (w);
HANDLE h = open_output_mutex ();
if (h)
{
CloseHandle (h);
return true;
}
return slave_alive ();
}
bool bool
tty::alive (const char *fmt) tty::alive (const char *fmt)
{ {

View File

@ -102,18 +102,7 @@ public:
HANDLE open_mutex (const char *mutex); HANDLE open_mutex (const char *mutex);
HANDLE open_output_mutex (); HANDLE open_output_mutex ();
HANDLE open_input_mutex (); HANDLE open_input_mutex ();
bool exists () bool exists ();
{
if (!master_pid)
return false;
HANDLE h = open_output_mutex ();
if (h)
{
CloseHandle (h);
return 1;
}
return slave_alive ();
}
void set_master_closed () {master_pid = -1;} void set_master_closed () {master_pid = -1;}
static void __stdcall create_master (int); static void __stdcall create_master (int);
static void __stdcall init_session (); static void __stdcall init_session ();