X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote-fileio.c;h=82a4fe920d7ff3687d9259bb6cbc972ab64f9fbc;hb=790c20f3f358afee041c54335081e4d877924ce3;hp=eb7ae3829636c390ebcc9becbc18fd00d4136ebe;hpb=9c7deb13f0e8432ea757903fa43400cbd43ba84a;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c
index eb7ae38296..82a4fe920d 100644
--- a/gdb/remote-fileio.c
+++ b/gdb/remote-fileio.c
@@ -1,12 +1,13 @@
/* Remote File-I/O communications
- Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -15,9 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see . */
/* See the GDB User Guide for details of the GDB remote protocol. */
@@ -30,11 +29,21 @@
#include "gdb_stat.h"
#include "exceptions.h"
#include "remote-fileio.h"
+#include "event-loop.h"
#include
#include
#ifdef __CYGWIN__
#include /* For cygwin_conv_to_full_posix_path. */
+#include
+#if CYGWIN_VERSION_DLL_MAKE_COMBINED(CYGWIN_VERSION_API_MAJOR,CYGWIN_VERSION_API_MINOR) < 181
+# define CCP_POSIX_TO_WIN_A 0
+# define CCP_WIN_A_TO_POSIX 2
+# define cygwin_conv_path(op, from, to, size) \
+ (op == CCP_WIN_A_TO_POSIX) ? \
+ cygwin_conv_to_full_posix_path (from, to) : \
+ cygwin_conv_to_win32_path (from, to)
+#endif
#endif
#include
@@ -49,6 +58,8 @@ static struct {
static int remote_fio_system_call_allowed = 0;
+static struct async_signal_handler *sigint_fileio_token;
+
static int
remote_fileio_init_fd_map (void)
{
@@ -70,12 +81,16 @@ remote_fileio_init_fd_map (void)
static int
remote_fileio_resize_fd_map (void)
{
+ int i = remote_fio_data.fd_map_size;
+
if (!remote_fio_data.fd_map)
return remote_fileio_init_fd_map ();
remote_fio_data.fd_map_size += 10;
remote_fio_data.fd_map =
(int *) xrealloc (remote_fio_data.fd_map,
remote_fio_data.fd_map_size * sizeof (int));
+ for (; i < remote_fio_data.fd_map_size; i++)
+ remote_fio_data.fd_map[i] = FIO_FD_INVALID;
return remote_fio_data.fd_map_size - 10;
}
@@ -94,6 +109,7 @@ static int
remote_fileio_fd_to_targetfd (int fd)
{
int target_fd = remote_fileio_next_free_fd ();
+
remote_fio_data.fd_map[target_fd] = fd;
return target_fd;
}
@@ -501,13 +517,19 @@ remote_fileio_sig_exit (void)
#endif
}
+static void
+async_remote_fileio_interrupt (gdb_client_data arg)
+{
+ deprecated_throw_reason (RETURN_QUIT);
+}
+
static void
remote_fileio_ctrl_c_signal_handler (int signo)
{
remote_fileio_sig_set (SIG_IGN);
remote_fio_ctrl_c_flag = 1;
if (!remote_fio_no_longjmp)
- deprecated_throw_reason (RETURN_QUIT);
+ gdb_call_async_signal_handler (sigint_fileio_token, 1);
remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
}
@@ -729,7 +751,7 @@ remote_fileio_func_read (char *buf)
static char *remaining_buf = NULL;
static int remaining_length = 0;
- buffer = (gdb_byte *) xmalloc (32768);
+ buffer = (gdb_byte *) xmalloc (16384);
if (remaining_buf)
{
remote_fio_no_longjmp = 1;
@@ -751,7 +773,18 @@ remote_fileio_func_read (char *buf)
}
else
{
- ret = ui_file_read (gdb_stdtargin, (char *) buffer, 32767);
+ /* Windows (at least XP and Server 2003) has difficulty
+ with large reads from consoles. If a handle is
+ backed by a real console device, overly large reads
+ from the handle will fail and set errno == ENOMEM.
+ On a Windows Server 2003 system where I tested,
+ reading 26608 bytes from the console was OK, but
+ anything above 26609 bytes would fail. The limit has
+ been observed to vary on different systems. So, we
+ limit this read to something smaller than that - by a
+ safe margin, in case the limit depends on system
+ resources or version. */
+ ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
remote_fio_no_longjmp = 1;
if (ret > 0 && (size_t)ret > length)
{
@@ -850,6 +883,7 @@ remote_fileio_func_write (char *buf)
{
case FIO_FD_CONSOLE_IN:
remote_fileio_badfd ();
+ xfree (buffer);
return;
case FIO_FD_CONSOLE_OUT:
ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
@@ -997,12 +1031,14 @@ remote_fileio_func_rename (char *buf)
errno = EISDIR;
else
{
- char oldfullpath[PATH_MAX + 1];
- char newfullpath[PATH_MAX + 1];
+ char oldfullpath[PATH_MAX];
+ char newfullpath[PATH_MAX];
int len;
- cygwin_conv_to_full_posix_path (oldpath, oldfullpath);
- cygwin_conv_to_full_posix_path (newpath, newfullpath);
+ cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
+ PATH_MAX);
+ cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
+ PATH_MAX);
len = strlen (oldfullpath);
if (newfullpath[len] == '/'
&& !strncmp (oldfullpath, newfullpath, len))
@@ -1332,19 +1368,19 @@ static struct {
char *name;
void (*func)(char *);
} remote_fio_func_map[] = {
- "open", remote_fileio_func_open,
- "close", remote_fileio_func_close,
- "read", remote_fileio_func_read,
- "write", remote_fileio_func_write,
- "lseek", remote_fileio_func_lseek,
- "rename", remote_fileio_func_rename,
- "unlink", remote_fileio_func_unlink,
- "stat", remote_fileio_func_stat,
- "fstat", remote_fileio_func_fstat,
- "gettimeofday", remote_fileio_func_gettimeofday,
- "isatty", remote_fileio_func_isatty,
- "system", remote_fileio_func_system,
- NULL, NULL
+ { "open", remote_fileio_func_open },
+ { "close", remote_fileio_func_close },
+ { "read", remote_fileio_func_read },
+ { "write", remote_fileio_func_write },
+ { "lseek", remote_fileio_func_lseek },
+ { "rename", remote_fileio_func_rename },
+ { "unlink", remote_fileio_func_unlink },
+ { "stat", remote_fileio_func_stat },
+ { "fstat", remote_fileio_func_fstat },
+ { "gettimeofday", remote_fileio_func_gettimeofday },
+ { "isatty", remote_fileio_func_isatty },
+ { "system", remote_fileio_func_system },
+ { NULL, NULL }
};
static int
@@ -1386,34 +1422,50 @@ remote_fileio_reset (void)
}
if (remote_fio_data.fd_map)
{
- free (remote_fio_data.fd_map);
+ xfree (remote_fio_data.fd_map);
remote_fio_data.fd_map = NULL;
remote_fio_data.fd_map_size = 0;
}
}
+/* Handle a file I/O request. BUF points to the packet containing the
+ request. CTRLC_PENDING_P should be nonzero if the target has not
+ acknowledged the Ctrl-C sent asynchronously earlier. */
+
void
-remote_fileio_request (char *buf)
+remote_fileio_request (char *buf, int ctrlc_pending_p)
{
int ex;
remote_fileio_sig_init ();
- remote_fio_ctrl_c_flag = 0;
- remote_fio_no_longjmp = 0;
-
- ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
- RETURN_MASK_ALL);
- switch (ex)
+ if (ctrlc_pending_p)
{
- case RETURN_ERROR:
- remote_fileio_reply (-1, FILEIO_ENOSYS);
- break;
- case RETURN_QUIT:
- remote_fileio_reply (-1, FILEIO_EINTR);
- break;
- default:
- break;
+ /* If the target hasn't responded to the Ctrl-C sent
+ asynchronously earlier, take this opportunity to send the
+ Ctrl-C synchronously. */
+ remote_fio_ctrl_c_flag = 1;
+ remote_fio_no_longjmp = 0;
+ remote_fileio_reply (-1, FILEIO_EINTR);
+ }
+ else
+ {
+ remote_fio_ctrl_c_flag = 0;
+ remote_fio_no_longjmp = 0;
+
+ ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
+ RETURN_MASK_ALL);
+ switch (ex)
+ {
+ case RETURN_ERROR:
+ remote_fileio_reply (-1, FILEIO_ENOSYS);
+ break;
+ case RETURN_QUIT:
+ remote_fileio_reply (-1, FILEIO_EINTR);
+ break;
+ default:
+ break;
+ }
}
remote_fileio_sig_exit ();
@@ -1426,6 +1478,7 @@ set_system_call_allowed (char *args, int from_tty)
{
char *arg_end;
int val = strtoul (args, &arg_end, 10);
+
if (*args && *arg_end == '\0')
{
remote_fio_system_call_allowed = !!val;
@@ -1448,6 +1501,9 @@ void
initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
struct cmd_list_element *remote_show_cmdlist)
{
+ sigint_fileio_token =
+ create_async_signal_handler (async_remote_fileio_interrupt, NULL);
+
add_cmd ("system-call-allowed", no_class,
set_system_call_allowed,
_("Set if the host system(3) call is allowed for the target."),