* dtable.cc (dtable::init_std_file_from_handle): Avoid adding fh to fdtab until
we know that it is good. * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Handle error conditions more consistently. Avoid handle leakage on error.
This commit is contained in:
parent
ed32dd8946
commit
1ae0a7c5a6
@ -1,3 +1,10 @@
|
|||||||
|
2010-04-02 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
|
* dtable.cc (dtable::init_std_file_from_handle): Avoid adding fh to
|
||||||
|
fdtab until we know that it is good.
|
||||||
|
* fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Handle
|
||||||
|
error conditions more consistently. Avoid handle leakage on error.
|
||||||
|
|
||||||
2010-04-02 Corinna Vinschen <corinna@vinschen.de>
|
2010-04-02 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_tty.cc (fhandler_tty_slave::close): Avoid potential crash
|
* fhandler_tty.cc (fhandler_tty_slave::close): Avoid potential crash
|
||||||
|
@ -350,9 +350,6 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||||||
else
|
else
|
||||||
fh = build_fh_name (name);
|
fh = build_fh_name (name);
|
||||||
|
|
||||||
if (fh)
|
|
||||||
cygheap->fdtab[fd] = fh;
|
|
||||||
|
|
||||||
if (name[0])
|
if (name[0])
|
||||||
{
|
{
|
||||||
bin = fh->pc_binmode ();
|
bin = fh->pc_binmode ();
|
||||||
@ -389,11 +386,12 @@ 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. */
|
||||||
if (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);
|
|
||||||
else
|
|
||||||
api_fatal ("couldn't initialize fd %d for %s", fd, fh->get_name ());
|
api_fatal ("couldn't initialize fd %d for %s", fd, fh->get_name ());
|
||||||
|
|
||||||
|
cygheap->fdtab[fd] = fh;
|
||||||
|
set_std_handle (fd);
|
||||||
paranoid_printf ("fd %d, handle %p", fd, handle);
|
paranoid_printf ("fd %d, handle %p", fd, handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,6 +450,20 @@ fhandler_tty_slave::fhandler_tty_slave ()
|
|||||||
int
|
int
|
||||||
fhandler_tty_slave::open (int flags, mode_t)
|
fhandler_tty_slave::open (int flags, mode_t)
|
||||||
{
|
{
|
||||||
|
HANDLE tty_owner, from_master_local, to_master_local;
|
||||||
|
HANDLE *handles[] =
|
||||||
|
{
|
||||||
|
&from_master_local, &input_available_event, &input_mutex, &inuse,
|
||||||
|
&ioctl_done_event, &ioctl_request_event, &output_done_event,
|
||||||
|
&output_mutex, &to_master_local, &tty_owner,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *errmsg = NULL;
|
||||||
|
|
||||||
|
for (HANDLE **h = handles; *h; h++)
|
||||||
|
**h = NULL;
|
||||||
|
|
||||||
if (get_device () == FH_TTY)
|
if (get_device () == FH_TTY)
|
||||||
dev().tty_to_real_device ();
|
dev().tty_to_real_device ();
|
||||||
fhandler_tty_slave *arch = (fhandler_tty_slave *) cygheap->fdtab.find_archetype (pc.dev);
|
fhandler_tty_slave *arch = (fhandler_tty_slave *) cygheap->fdtab.find_archetype (pc.dev);
|
||||||
@ -480,22 +494,19 @@ fhandler_tty_slave::open (int flags, mode_t)
|
|||||||
|
|
||||||
if (!(output_mutex = get_ttyp ()->open_output_mutex ()))
|
if (!(output_mutex = get_ttyp ()->open_output_mutex ()))
|
||||||
{
|
{
|
||||||
termios_printf ("open output mutex failed, %E");
|
errmsg = "open output mutex failed, %E";
|
||||||
__seterrno ();
|
goto err;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (!(input_mutex = get_ttyp ()->open_input_mutex ()))
|
if (!(input_mutex = get_ttyp ()->open_input_mutex ()))
|
||||||
{
|
{
|
||||||
termios_printf ("open input mutex failed, %E");
|
errmsg = "open input mutex failed, %E";
|
||||||
__seterrno ();
|
goto err;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
shared_name (buf, INPUT_AVAILABLE_EVENT, get_unit ());
|
shared_name (buf, INPUT_AVAILABLE_EVENT, get_unit ());
|
||||||
if (!(input_available_event = OpenEvent (EVENT_ALL_ACCESS, TRUE, buf)))
|
if (!(input_available_event = OpenEvent (EVENT_ALL_ACCESS, TRUE, buf)))
|
||||||
{
|
{
|
||||||
termios_printf ("open input event failed, %E");
|
errmsg = "open input event failed, %E";
|
||||||
__seterrno ();
|
goto err;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The ioctl events may or may not exist. See output_done_event,
|
/* The ioctl events may or may not exist. See output_done_event,
|
||||||
@ -515,30 +526,26 @@ fhandler_tty_slave::open (int flags, mode_t)
|
|||||||
|
|
||||||
if (!get_ttyp ()->from_master || !get_ttyp ()->to_master)
|
if (!get_ttyp ()->from_master || !get_ttyp ()->to_master)
|
||||||
{
|
{
|
||||||
termios_printf ("tty handles have been closed");
|
errmsg = "tty handles have been closed";
|
||||||
set_errno (EACCES);
|
set_errno (EACCES);
|
||||||
return 0;
|
goto err_no_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE from_master_local;
|
|
||||||
HANDLE to_master_local;
|
|
||||||
from_master_local = to_master_local = NULL;
|
|
||||||
|
|
||||||
if (cygserver_running == CYGSERVER_UNAVAIL
|
if (cygserver_running == CYGSERVER_UNAVAIL
|
||||||
|| !cygserver_attach_tty (&from_master_local, &to_master_local))
|
|| !cygserver_attach_tty (&from_master_local, &to_master_local))
|
||||||
{
|
{
|
||||||
if (get_ttyp ()->master_pid < 0)
|
if (get_ttyp ()->master_pid < 0)
|
||||||
{
|
{
|
||||||
|
errmsg = "*** master is closed";
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
termios_printf ("*** master is closed");
|
goto err_no_errno;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
pinfo p (get_ttyp ()->master_pid);
|
pinfo p (get_ttyp ()->master_pid);
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
|
errmsg = "*** couldn't find tty master";
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
termios_printf ("*** couldn't find tty master");
|
goto err_no_errno;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
termios_printf ("cannot dup handles via server. using old method.");
|
termios_printf ("cannot dup handles via server. using old method.");
|
||||||
HANDLE tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
|
HANDLE tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
|
||||||
@ -548,7 +555,7 @@ fhandler_tty_slave::open (int flags, mode_t)
|
|||||||
termios_printf ("can't open tty (%d) handle process %d",
|
termios_printf ("can't open tty (%d) handle process %d",
|
||||||
get_unit (), get_ttyp ()->master_pid);
|
get_unit (), get_ttyp ()->master_pid);
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return 0;
|
goto err_no_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master,
|
if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master,
|
||||||
@ -558,7 +565,7 @@ fhandler_tty_slave::open (int flags, mode_t)
|
|||||||
termios_printf ("can't duplicate input from %u/%p, %E",
|
termios_printf ("can't duplicate input from %u/%p, %E",
|
||||||
get_ttyp ()->master_pid, get_ttyp ()->from_master);
|
get_ttyp ()->master_pid, get_ttyp ()->from_master);
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return 0;
|
goto err_no_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyHandle (from_master_local);
|
VerifyHandle (from_master_local);
|
||||||
@ -566,9 +573,8 @@ fhandler_tty_slave::open (int flags, mode_t)
|
|||||||
GetCurrentProcess (), &to_master_local, 0, TRUE,
|
GetCurrentProcess (), &to_master_local, 0, TRUE,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
termios_printf ("can't duplicate output, %E");
|
errmsg = "can't duplicate output, %E";
|
||||||
__seterrno ();
|
goto err;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
VerifyHandle (to_master_local);
|
VerifyHandle (to_master_local);
|
||||||
CloseHandle (tty_owner);
|
CloseHandle (tty_owner);
|
||||||
@ -601,6 +607,16 @@ out:
|
|||||||
myself->set_ctty (get_ttyp (), flags, arch);
|
myself->set_ctty (get_ttyp (), flags, arch);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
__seterrno ();
|
||||||
|
err_no_errno:
|
||||||
|
termios_printf (errmsg);
|
||||||
|
err_no_msg:
|
||||||
|
for (HANDLE **h = handles; *h; h++)
|
||||||
|
if (**h && **h != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle (**h);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user