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."),