gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / remote-fileio.c
index fd57617acd5e37ca8ec6b7be31397066032d66e0..7450e84860287946dd1a10f4f66695013e1f416a 100644 (file)
@@ -1,12 +1,12 @@
 /* Remote File-I/O communications
 
 /* Remote File-I/O communications
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003-2020 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
 
    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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-/* See the GDB User Guide for details of the GDB remote protocol. */
+/* See the GDB User Guide for details of the GDB remote protocol.  */
 
 #include "defs.h"
 
 #include "defs.h"
-#include "gdb_string.h"
 #include "gdbcmd.h"
 #include "remote.h"
 #include "gdbcmd.h"
 #include "remote.h"
-#include "gdb/fileio.h"
-#include "gdb_wait.h"
-#include "gdb_stat.h"
+#include "gdbsupport/gdb_wait.h"
+#include <sys/stat.h>
 #include "remote-fileio.h"
 #include "remote-fileio.h"
+#include "gdbsupport/event-loop.h"
+#include "target.h"
+#include "filenames.h"
+#include "gdbsupport/filestuff.h"
 
 #include <fcntl.h>
 
 #include <fcntl.h>
-#include <sys/time.h>
+#include "gdbsupport/gdb_sys_time.h"
 #ifdef __CYGWIN__
 #ifdef __CYGWIN__
-#include <sys/cygwin.h>                /* For cygwin_conv_to_full_posix_path.  */
+#include <sys/cygwin.h>                /* For cygwin_conv_path.  */
 #endif
 #include <signal.h>
 
 #endif
 #include <signal.h>
 
@@ -55,7 +55,7 @@ remote_fileio_init_fd_map (void)
 
   if (!remote_fio_data.fd_map)
     {
 
   if (!remote_fio_data.fd_map)
     {
-      remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int));
+      remote_fio_data.fd_map = XNEWVEC (int, 10);
       remote_fio_data.fd_map_size = 10;
       remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
       remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
       remote_fio_data.fd_map_size = 10;
       remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
       remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
@@ -69,12 +69,16 @@ remote_fileio_init_fd_map (void)
 static int
 remote_fileio_resize_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));
   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;
 }
 
   return remote_fio_data.fd_map_size - 10;
 }
 
@@ -93,6 +97,7 @@ static int
 remote_fileio_fd_to_targetfd (int fd)
 {
   int target_fd = remote_fileio_next_free_fd ();
 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;
 }
   remote_fio_data.fd_map[target_fd] = fd;
   return target_fd;
 }
@@ -134,7 +139,7 @@ remote_fileio_oflags_to_host (long flags)
   if (flags & FILEIO_O_RDWR)
     hflags |= O_RDWR;
 /* On systems supporting binary and text mode, always open files in
   if (flags & FILEIO_O_RDWR)
     hflags |= O_RDWR;
 /* On systems supporting binary and text mode, always open files in
-   binary mode. */
+   binary mode.  */
 #ifdef O_BINARY
   hflags |= O_BINARY;
 #endif
 #ifdef O_BINARY
   hflags |= O_BINARY;
 #endif
@@ -161,104 +166,31 @@ remote_fileio_mode_to_host (long mode, int open_call)
     hmode |= S_IWUSR;
   if (mode & FILEIO_S_IXUSR)
     hmode |= S_IXUSR;
     hmode |= S_IWUSR;
   if (mode & FILEIO_S_IXUSR)
     hmode |= S_IXUSR;
+#ifdef S_IRGRP
   if (mode & FILEIO_S_IRGRP)
     hmode |= S_IRGRP;
   if (mode & FILEIO_S_IRGRP)
     hmode |= S_IRGRP;
+#endif
+#ifdef S_IWGRP
   if (mode & FILEIO_S_IWGRP)
     hmode |= S_IWGRP;
   if (mode & FILEIO_S_IWGRP)
     hmode |= S_IWGRP;
+#endif
+#ifdef S_IXGRP
   if (mode & FILEIO_S_IXGRP)
     hmode |= S_IXGRP;
   if (mode & FILEIO_S_IXGRP)
     hmode |= S_IXGRP;
+#endif
   if (mode & FILEIO_S_IROTH)
     hmode |= S_IROTH;
   if (mode & FILEIO_S_IROTH)
     hmode |= S_IROTH;
+#ifdef S_IWOTH
   if (mode & FILEIO_S_IWOTH)
     hmode |= S_IWOTH;
   if (mode & FILEIO_S_IWOTH)
     hmode |= S_IWOTH;
+#endif
+#ifdef S_IXOTH
   if (mode & FILEIO_S_IXOTH)
     hmode |= S_IXOTH;
   if (mode & FILEIO_S_IXOTH)
     hmode |= S_IXOTH;
+#endif
   return hmode;
 }
 
   return hmode;
 }
 
-static LONGEST
-remote_fileio_mode_to_target (mode_t mode)
-{
-  mode_t tmode = 0;
-
-  if (mode & S_IFREG)
-    tmode |= FILEIO_S_IFREG;
-  if (mode & S_IFDIR)
-    tmode |= FILEIO_S_IFDIR;
-  if (mode & S_IFCHR)
-    tmode |= FILEIO_S_IFCHR;
-  if (mode & S_IRUSR)
-    tmode |= FILEIO_S_IRUSR;
-  if (mode & S_IWUSR)
-    tmode |= FILEIO_S_IWUSR;
-  if (mode & S_IXUSR)
-    tmode |= FILEIO_S_IXUSR;
-  if (mode & S_IRGRP)
-    tmode |= FILEIO_S_IRGRP;
-  if (mode & S_IWGRP)
-    tmode |= FILEIO_S_IWGRP;
-  if (mode & S_IXGRP)
-    tmode |= FILEIO_S_IXGRP;
-  if (mode & S_IROTH)
-    tmode |= FILEIO_S_IROTH;
-  if (mode & S_IWOTH)
-    tmode |= FILEIO_S_IWOTH;
-  if (mode & S_IXOTH)
-    tmode |= FILEIO_S_IXOTH;
-  return tmode;
-}
-
-static int
-remote_fileio_errno_to_target (int error)
-{
-  switch (error)
-    {
-      case EPERM:
-        return FILEIO_EPERM;
-      case ENOENT:
-        return FILEIO_ENOENT;
-      case EINTR:
-        return FILEIO_EINTR;
-      case EIO:
-        return FILEIO_EIO;
-      case EBADF:
-        return FILEIO_EBADF;
-      case EACCES:
-        return FILEIO_EACCES;
-      case EFAULT:
-        return FILEIO_EFAULT;
-      case EBUSY:
-        return FILEIO_EBUSY;
-      case EEXIST:
-        return FILEIO_EEXIST;
-      case ENODEV:
-        return FILEIO_ENODEV;
-      case ENOTDIR:
-        return FILEIO_ENOTDIR;
-      case EISDIR:
-        return FILEIO_EISDIR;
-      case EINVAL:
-        return FILEIO_EINVAL;
-      case ENFILE:
-        return FILEIO_ENFILE;
-      case EMFILE:
-        return FILEIO_EMFILE;
-      case EFBIG:
-        return FILEIO_EFBIG;
-      case ENOSPC:
-        return FILEIO_ENOSPC;
-      case ESPIPE:
-        return FILEIO_ESPIPE;
-      case EROFS:
-        return FILEIO_EROFS;
-      case ENOSYS:
-        return FILEIO_ENOSYS;
-      case ENAMETOOLONG:
-        return FILEIO_ENAMETOOLONG;
-    }
-  return FILEIO_EUNKNOWN;
-}
-
 static int
 remote_fileio_seek_flag_to_host (long num, int *flag)
 {
 static int
 remote_fileio_seek_flag_to_host (long num, int *flag)
 {
@@ -353,139 +285,39 @@ remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
   return 0;
 }
 
   return 0;
 }
 
-/* Convert to big endian */
-static void
-remote_fileio_to_be (LONGEST num, char *buf, int bytes)
-{
-  int i;
-
-  for (i = 0; i < bytes; ++i)
-    buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
-}
-
-static void
-remote_fileio_to_fio_int (long num, fio_int_t fnum)
-{
-  remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
-}
-
-static void
-remote_fileio_to_fio_uint (long num, fio_uint_t fnum)
-{
-  remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
-}
-
-static void
-remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum)
-{
-  remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4);
-}
-
-static void
-remote_fileio_to_fio_time (time_t num, fio_time_t fnum)
-{
-  remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
-}
-
 static void
 remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
 {
 static void
 remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
 {
-  remote_fileio_to_be (num, (char *) fnum, 8);
-}
-
-static void
-remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum)
-{
-  remote_fileio_to_be (num, (char *) fnum, 8);
-}
-
-static void
-remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
-{
-  /* `st_dev' is set in the calling function */
-  remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino);
-  remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode);
-  remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink);
-  remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid);
-  remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid);
-  remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev);
-  remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size);
-  remote_fileio_to_fio_ulong ((LONGEST) st->st_blksize, fst->fst_blksize);
-  remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
-  remote_fileio_to_fio_time (st->st_atime, fst->fst_atime);
-  remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime);
-  remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime);
+  host_to_bigendian (num, (char *) fnum, 8);
 }
 
 static void
 remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
 {
 }
 
 static void
 remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
 {
-  remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec);
+  host_to_fileio_time (tv->tv_sec, ftv->ftv_sec);
   remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
 }
 
   remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
 }
 
-static int remote_fio_ctrl_c_flag = 0;
-static int remote_fio_no_longjmp = 0;
+/* The quit handler originally installed.  */
+static quit_handler_ftype *remote_fileio_o_quit_handler;
 
 
-#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
-static struct sigaction remote_fio_sa;
-static struct sigaction remote_fio_osa;
-#else
-static void (*remote_fio_ofunc)(int);
-#endif
+/* What to do on a QUIT call while handling a file I/O request.  We
+   throw a quit exception, which is caught by remote_fileio_request
+   and translated to an EINTR reply back to the target.  */
 
 static void
 
 static void
-remote_fileio_sig_init (void)
+remote_fileio_quit_handler (void)
 {
 {
-#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
-  remote_fio_sa.sa_handler = SIG_IGN;
-  sigemptyset (&remote_fio_sa.sa_mask);
-  remote_fio_sa.sa_flags = 0;
-  sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
-#else
-  remote_fio_ofunc = signal (SIGINT, SIG_IGN);
-#endif
+  if (check_quit_flag ())
+    quit ();
 }
 
 static void
 }
 
 static void
-remote_fileio_sig_set (void (*sigint_func)(int))
-{
-#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
-  remote_fio_sa.sa_handler = sigint_func;
-  sigemptyset (&remote_fio_sa.sa_mask);
-  remote_fio_sa.sa_flags = 0;
-  sigaction (SIGINT, &remote_fio_sa, NULL);
-#else
-  signal (SIGINT, sigint_func);
-#endif
-}
-
-static void
-remote_fileio_sig_exit (void)
-{
-#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
-  sigaction (SIGINT, &remote_fio_osa, NULL);
-#else
-  signal (SIGINT, remote_fio_ofunc);
-#endif
-}
-
-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)
-    throw_exception (RETURN_QUIT);
-  remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
-}
-
-static void
-remote_fileio_reply (int retcode, int error)
+remote_fileio_reply (remote_target *remote, int retcode, int error)
 {
   char buf[32];
 {
   char buf[32];
+  int ctrl_c = check_quit_flag ();
 
 
-  remote_fileio_sig_set (SIG_IGN);
   strcpy (buf, "F");
   if (retcode < 0)
     {
   strcpy (buf, "F");
   if (retcode < 0)
     {
@@ -493,9 +325,9 @@ remote_fileio_reply (int retcode, int error)
       retcode = -retcode;
     }
   sprintf (buf + strlen (buf), "%x", retcode);
       retcode = -retcode;
     }
   sprintf (buf + strlen (buf), "%x", retcode);
-  if (error || remote_fio_ctrl_c_flag)
+  if (error || ctrl_c)
     {
     {
-      if (error && remote_fio_ctrl_c_flag)
+      if (error && ctrl_c)
         error = FILEIO_EINTR;
       if (error < 0)
         {
         error = FILEIO_EINTR;
       if (error < 0)
         {
@@ -503,129 +335,109 @@ remote_fileio_reply (int retcode, int error)
          error = -error;
        }
       sprintf (buf + strlen (buf), ",%x", error);
          error = -error;
        }
       sprintf (buf + strlen (buf), ",%x", error);
-      if (remote_fio_ctrl_c_flag)
+      if (ctrl_c)
         strcat (buf, ",C");
     }
         strcat (buf, ",C");
     }
-  remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
-  putpkt (buf);
+  quit_handler = remote_fileio_o_quit_handler;
+  putpkt (remote, buf);
 }
 
 static void
 }
 
 static void
-remote_fileio_ioerror (void)
+remote_fileio_ioerror (remote_target *remote)
 {
 {
-  remote_fileio_reply (-1, FILEIO_EIO);
+  remote_fileio_reply (remote, -1, FILEIO_EIO);
 }
 
 static void
 }
 
 static void
-remote_fileio_badfd (void)
+remote_fileio_badfd (remote_target *remote)
 {
 {
-  remote_fileio_reply (-1, FILEIO_EBADF);
+  remote_fileio_reply (remote, -1, FILEIO_EBADF);
 }
 
 static void
 }
 
 static void
-remote_fileio_return_errno (int retcode)
+remote_fileio_return_errno (remote_target *remote, int retcode)
 {
 {
-  remote_fileio_reply (retcode,
-                      retcode < 0 ? remote_fileio_errno_to_target (errno) : 0);
+  remote_fileio_reply (remote, retcode, retcode < 0
+                      ? host_to_fileio_error (errno) : 0);
 }
 
 static void
 }
 
 static void
-remote_fileio_return_success (int retcode)
+remote_fileio_return_success (remote_target *remote, int retcode)
 {
 {
-  remote_fileio_reply (retcode, 0);
-}
-
-/* Wrapper function for remote_write_bytes() which has the disadvantage to
-   write only one packet, regardless of the requested number of bytes to
-   transfer.  This wrapper calls remote_write_bytes() as often as needed. */
-static int
-remote_fileio_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
-{
-  int ret = 0, written;
-
-  while (len > 0 && (written = remote_write_bytes (memaddr, myaddr, len)) > 0)
-    {
-      len -= written;
-      memaddr += written;
-      myaddr += written;
-      ret += written;
-    }
-  return ret;
+  remote_fileio_reply (remote, retcode, 0);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_open (char *buf)
+remote_fileio_func_open (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
 {
   CORE_ADDR ptrval;
-  int length, retlength;
+  int length;
   long num;
   int flags, fd;
   mode_t mode;
   char *pathname;
   struct stat st;
 
   long num;
   int flags, fd;
   mode_t mode;
   char *pathname;
   struct stat st;
 
-  /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
+  /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   /* 2. Parameter: open flags */
   if (remote_fileio_extract_int (&buf, &num))
     {
       return;
     }
   /* 2. Parameter: open flags */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   flags = remote_fileio_oflags_to_host (num);
   /* 3. Parameter: open mode */
   if (remote_fileio_extract_int (&buf, &num))
     {
       return;
     }
   flags = remote_fileio_oflags_to_host (num);
   /* 3. Parameter: open mode */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   mode = remote_fileio_mode_to_host (num, 1);
 
       return;
     }
   mode = remote_fileio_mode_to_host (num, 1);
 
-  /* Request pathname using 'm' packet */
-  pathname = alloca (length);
-  retlength = remote_read_bytes (ptrval, pathname, length);
-  if (retlength != length)
+  /* Request pathname.  */
+  pathname = (char *) alloca (length);
+  if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
     {
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
   /* Check if pathname exists and is not a regular file or directory.  If so,
      return an appropriate error code.  Same for trying to open directories
       return;
     }
 
   /* Check if pathname exists and is not a regular file or directory.  If so,
      return an appropriate error code.  Same for trying to open directories
-     for writing. */
+     for writing.  */
   if (!stat (pathname, &st))
     {
       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
        {
   if (!stat (pathname, &st))
     {
       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
        {
-         remote_fileio_reply (-1, FILEIO_ENODEV);
+         remote_fileio_reply (remote, -1, FILEIO_ENODEV);
          return;
        }
       if (S_ISDIR (st.st_mode)
          && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
        {
          return;
        }
       if (S_ISDIR (st.st_mode)
          && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
        {
-         remote_fileio_reply (-1, FILEIO_EISDIR);
+         remote_fileio_reply (remote, -1, FILEIO_EISDIR);
          return;
        }
     }
 
          return;
        }
     }
 
-  remote_fio_no_longjmp = 1;
-  fd = open (pathname, flags, mode);
+  fd = gdb_open_cloexec (pathname, flags, mode);
   if (fd < 0)
     {
   if (fd < 0)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
 
   fd = remote_fileio_fd_to_targetfd (fd);
       return;
     }
 
   fd = remote_fileio_fd_to_targetfd (fd);
-  remote_fileio_return_success (fd);
+  remote_fileio_return_success (remote, fd);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_close (char *buf)
+remote_fileio_func_close (remote_target *remote, char *buf)
 {
   long num;
   int fd;
 {
   long num;
   int fd;
@@ -633,57 +445,56 @@ remote_fileio_func_close (char *buf)
   /* Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &num))
     {
   /* Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) num);
   if (fd == FIO_FD_INVALID)
     {
       return;
     }
   fd = remote_fileio_map_fd ((int) num);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
 
       return;
     }
 
-  remote_fio_no_longjmp = 1;
   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   remote_fileio_close_target_fd ((int) num);
   remote_fileio_close_target_fd ((int) num);
-  remote_fileio_return_success (0);
+  remote_fileio_return_success (remote, 0);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_read (char *buf)
+remote_fileio_func_read (remote_target *remote, char *buf)
 {
   long target_fd, num;
   LONGEST lnum;
   CORE_ADDR ptrval;
 {
   long target_fd, num;
   LONGEST lnum;
   CORE_ADDR ptrval;
-  int fd, ret, retlength;
-  char *buffer;
+  int fd, ret;
+  gdb_byte *buffer;
   size_t length;
   off_t old_offset, new_offset;
 
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
   size_t length;
   off_t old_offset, new_offset;
 
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   /* 2. Parameter: buffer pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
       return;
     }
   /* 2. Parameter: buffer pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
   /* 3. Parameter: buffer length */
   if (remote_fileio_extract_int (&buf, &num))
     {
       return;
     }
   ptrval = (CORE_ADDR) lnum;
   /* 3. Parameter: buffer length */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   length = (size_t) num;
       return;
     }
   length = (size_t) num;
@@ -691,17 +502,16 @@ remote_fileio_func_read (char *buf)
   switch (fd)
     {
       case FIO_FD_CONSOLE_OUT:
   switch (fd)
     {
       case FIO_FD_CONSOLE_OUT:
-       remote_fileio_badfd ();
+       remote_fileio_badfd (remote);
        return;
       case FIO_FD_CONSOLE_IN:
        {
          static char *remaining_buf = NULL;
          static int remaining_length = 0;
 
        return;
       case FIO_FD_CONSOLE_IN:
        {
          static char *remaining_buf = NULL;
          static int remaining_length = 0;
 
-         buffer = (char *) xmalloc (32768);
+         buffer = (gdb_byte *) xmalloc (16384);
          if (remaining_buf)
            {
          if (remaining_buf)
            {
-             remote_fio_no_longjmp = 1;
              if (remaining_length > length)
                {
                  memcpy (buffer, remaining_buf, length);
              if (remaining_length > length)
                {
                  memcpy (buffer, remaining_buf, length);
@@ -720,8 +530,18 @@ remote_fileio_func_read (char *buf)
            }
          else
            {
            }
          else
            {
-             ret = ui_file_read (gdb_stdtargin, buffer, 32767);
-             remote_fio_no_longjmp = 1;
+             /* 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 = gdb_stdtargin->read ((char *) buffer, 16383);
              if (ret > 0 && (size_t)ret > length)
                {
                  remaining_buf = (char *) xmalloc (ret - length);
              if (ret > 0 && (size_t)ret > length)
                {
                  remaining_buf = (char *) xmalloc (ret - length);
@@ -733,20 +553,19 @@ remote_fileio_func_read (char *buf)
        }
        break;
       default:
        }
        break;
       default:
-       buffer = (char *) xmalloc (length);
+       buffer = (gdb_byte *) xmalloc (length);
        /* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
           for read() to return -1 even if "some" bytes have been read.  It
           has been corrected in SUSv2 but that doesn't help us much...
           Therefore a complete solution must check how many bytes have been
           read on EINTR to return a more reliable value to the target */
        old_offset = lseek (fd, 0, SEEK_CUR);
        /* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
           for read() to return -1 even if "some" bytes have been read.  It
           has been corrected in SUSv2 but that doesn't help us much...
           Therefore a complete solution must check how many bytes have been
           read on EINTR to return a more reliable value to the target */
        old_offset = lseek (fd, 0, SEEK_CUR);
-       remote_fio_no_longjmp = 1;
        ret = read (fd, buffer, length);
        if (ret < 0 && errno == EINTR)
          {
            new_offset = lseek (fd, 0, SEEK_CUR);
            /* If some data has been read, return the number of bytes read.
        ret = read (fd, buffer, length);
        if (ret < 0 && errno == EINTR)
          {
            new_offset = lseek (fd, 0, SEEK_CUR);
            /* If some data has been read, return the number of bytes read.
-              The Ctrl-C flag is set in remote_fileio_reply() anyway */
+              The Ctrl-C flag is set in remote_fileio_reply() anyway */
            if (old_offset != new_offset)
              ret = new_offset - old_offset;
          }
            if (old_offset != new_offset)
              ret = new_offset - old_offset;
          }
@@ -755,94 +574,96 @@ remote_fileio_func_read (char *buf)
 
   if (ret > 0)
     {
 
   if (ret > 0)
     {
-      retlength = remote_fileio_write_bytes (ptrval, buffer, ret);
-      if (retlength != ret)
-       ret = -1; /* errno has been set to EIO in remote_fileio_write_bytes() */
+      errno = target_write_memory (ptrval, buffer, ret);
+      if (errno != 0)
+       ret = -1;
     }
 
   if (ret < 0)
     }
 
   if (ret < 0)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 
   xfree (buffer);
 }
 
 static void
 
   xfree (buffer);
 }
 
 static void
-remote_fileio_func_write (char *buf)
+remote_fileio_func_write (remote_target *remote, char *buf)
 {
   long target_fd, num;
   LONGEST lnum;
   CORE_ADDR ptrval;
 {
   long target_fd, num;
   LONGEST lnum;
   CORE_ADDR ptrval;
-  int fd, ret, retlength;
-  char *buffer;
+  int fd, ret;
+  gdb_byte *buffer;
   size_t length;
 
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
   size_t length;
 
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   /* 2. Parameter: buffer pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
       return;
     }
   /* 2. Parameter: buffer pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
   /* 3. Parameter: buffer length */
   if (remote_fileio_extract_int (&buf, &num))
     {
       return;
     }
   ptrval = (CORE_ADDR) lnum;
   /* 3. Parameter: buffer length */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   length = (size_t) num;
     
       return;
     }
   length = (size_t) num;
     
-  buffer = (char *) xmalloc (length);
-  retlength = remote_read_bytes (ptrval, buffer, length);
-  if (retlength != length)
+  buffer = (gdb_byte *) xmalloc (length);
+  if (target_read_memory (ptrval, buffer, length) != 0)
     {
       xfree (buffer);
     {
       xfree (buffer);
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
       return;
     }
 
-  remote_fio_no_longjmp = 1;
   switch (fd)
     {
       case FIO_FD_CONSOLE_IN:
   switch (fd)
     {
       case FIO_FD_CONSOLE_IN:
-       remote_fileio_badfd ();
+       remote_fileio_badfd (remote);
+       xfree (buffer);
        return;
       case FIO_FD_CONSOLE_OUT:
        return;
       case FIO_FD_CONSOLE_OUT:
-       ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr, buffer,
-                      length);
-       gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
-       ret = length;
+       {
+         ui_file *file = target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr;
+         file->write ((char *) buffer, length);
+         file->flush ();
+         ret = length;
+       }
        break;
       default:
        ret = write (fd, buffer, length);
        if (ret < 0 && errno == EACCES)
        break;
       default:
        ret = write (fd, buffer, length);
        if (ret < 0 && errno == EACCES)
-         errno = EBADF; /* Cygwin returns EACCESS when writing to a R/O file.*/
+         errno = EBADF; /* Cygwin returns EACCESS when writing to a
+                           R/O file.  */
        break;
     }
 
   if (ret < 0)
        break;
     }
 
   if (ret < 0)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 
   xfree (buffer);
 }
 
 static void
 
   xfree (buffer);
 }
 
 static void
-remote_fileio_func_lseek (char *buf)
+remote_fileio_func_lseek (remote_target *remote, char *buf)
 {
   long num;
   LONGEST lnum;
 {
   long num;
   LONGEST lnum;
@@ -852,109 +673,108 @@ remote_fileio_func_lseek (char *buf)
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &num))
     {
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) num);
   if (fd == FIO_FD_INVALID)
     {
       return;
     }
   fd = remote_fileio_map_fd ((int) num);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
     {
       return;
     }
   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
     {
-      remote_fileio_reply (-1, FILEIO_ESPIPE);
+      remote_fileio_reply (remote, -1, FILEIO_ESPIPE);
       return;
     }
 
   /* 2. Parameter: offset */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
       return;
     }
 
   /* 2. Parameter: offset */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   offset = (off_t) lnum;
   /* 3. Parameter: flag */
   if (remote_fileio_extract_int (&buf, &num))
     {
       return;
     }
   offset = (off_t) lnum;
   /* 3. Parameter: flag */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   if (remote_fileio_seek_flag_to_host (num, &flag))
     {
       return;
     }
   if (remote_fileio_seek_flag_to_host (num, &flag))
     {
-      remote_fileio_reply (-1, FILEIO_EINVAL);
+      remote_fileio_reply (remote, -1, FILEIO_EINVAL);
       return;
     }
   
       return;
     }
   
-  remote_fio_no_longjmp = 1;
   ret = lseek (fd, offset, flag);
 
   if (ret == (off_t) -1)
   ret = lseek (fd, offset, flag);
 
   if (ret == (off_t) -1)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_rename (char *buf)
+remote_fileio_func_rename (remote_target *remote, char *buf)
 {
 {
-  CORE_ADDR ptrval;
-  int length, retlength;
+  CORE_ADDR old_ptr, new_ptr;
+  int old_len, new_len;
   char *oldpath, *newpath;
   int ret, of, nf;
   struct stat ost, nst;
 
   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
   char *oldpath, *newpath;
   int ret, of, nf;
   struct stat ost, nst;
 
   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
-  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
+  if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
     {
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
       return;
     }
-  /* Request oldpath using 'm' packet */
-  oldpath = alloca (length);
-  retlength = remote_read_bytes (ptrval, oldpath, length);
-  if (retlength != length)
+  
+  /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
+  if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
     {
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
       return;
     }
-  /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
-  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
+  
+  /* Request oldpath using 'm' packet */
+  oldpath = (char *) alloca (old_len);
+  if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
     {
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
       return;
     }
+  
   /* Request newpath using 'm' packet */
   /* Request newpath using 'm' packet */
-  newpath = alloca (length);
-  retlength = remote_read_bytes (ptrval, newpath, length);
-  if (retlength != length)
+  newpath = (char *) alloca (new_len);
+  if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
     {
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   
       return;
     }
   
-  /* Only operate on regular files and directories */
+  /* Only operate on regular files and directories */
   of = stat (oldpath, &ost);
   nf = stat (newpath, &nst);
   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
     {
   of = stat (oldpath, &ost);
   nf = stat (newpath, &nst);
   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
     {
-      remote_fileio_reply (-1, FILEIO_EACCES);
+      remote_fileio_reply (remote, -1, FILEIO_EACCES);
       return;
     }
 
       return;
     }
 
-  remote_fio_no_longjmp = 1;
   ret = rename (oldpath, newpath);
 
   if (ret == -1)
     {
       /* Special case: newpath is a non-empty directory.  Some systems
          return ENOTEMPTY, some return EEXIST.  We coerce that to be
   ret = rename (oldpath, newpath);
 
   if (ret == -1)
     {
       /* Special case: newpath is a non-empty directory.  Some systems
          return ENOTEMPTY, some return EEXIST.  We coerce that to be
-        always EEXIST. */
+        always EEXIST.  */
       if (errno == ENOTEMPTY)
         errno = EEXIST;
 #ifdef __CYGWIN__
       if (errno == ENOTEMPTY)
         errno = EEXIST;
 #ifdef __CYGWIN__
-      /* Workaround some Cygwin problems with correct errnos. */
+      /* Workaround some Cygwin problems with correct errnos.  */
       if (errno == EACCES)
         {
          if (!of && !nf && S_ISDIR (nst.st_mode))
       if (errno == EACCES)
         {
          if (!of && !nf && S_ISDIR (nst.st_mode))
@@ -963,15 +783,17 @@ remote_fileio_func_rename (char *buf)
                errno = EISDIR;
              else
                {
                errno = EISDIR;
              else
                {
-                 char oldfullpath[PATH_MAX + 1];
-                 char newfullpath[PATH_MAX + 1];
+                 char oldfullpath[PATH_MAX];
+                 char newfullpath[PATH_MAX];
                  int len;
 
                  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);
                  len = strlen (oldfullpath);
-                 if (newfullpath[len] == '/'
-                     && !strncmp (oldfullpath, newfullpath, len))
+                 if (IS_DIR_SEPARATOR (newfullpath[len])
+                     && !filename_ncmp (oldfullpath, newfullpath, len))
                    errno = EINVAL;
                  else
                    errno = EEXIST;
                    errno = EINVAL;
                  else
                    errno = EEXIST;
@@ -980,17 +802,17 @@ remote_fileio_func_rename (char *buf)
        }
 #endif
 
        }
 #endif
 
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
     }
   else
     }
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_unlink (char *buf)
+remote_fileio_func_unlink (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
 {
   CORE_ADDR ptrval;
-  int length, retlength;
+  int length;
   char *pathname;
   int ret;
   struct stat st;
   char *pathname;
   int ret;
   struct stat st;
@@ -998,102 +820,99 @@ remote_fileio_func_unlink (char *buf)
   /* Parameter: Ptr to pathname / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
   /* Parameter: Ptr to pathname / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   /* Request pathname using 'm' packet */
       return;
     }
   /* Request pathname using 'm' packet */
-  pathname = alloca (length);
-  retlength = remote_read_bytes (ptrval, pathname, length);
-  if (retlength != length)
+  pathname = (char *) alloca (length);
+  if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
     {
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
   /* Only operate on regular files (and directories, which allows to return
       return;
     }
 
   /* Only operate on regular files (and directories, which allows to return
-     the correct return code) */
+     the correct return code) */
   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
     {
   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
     {
-      remote_fileio_reply (-1, FILEIO_ENODEV);
+      remote_fileio_reply (remote, -1, FILEIO_ENODEV);
       return;
     }
 
       return;
     }
 
-  remote_fio_no_longjmp = 1;
   ret = unlink (pathname);
 
   if (ret == -1)
   ret = unlink (pathname);
 
   if (ret == -1)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_stat (char *buf)
+remote_fileio_func_stat (remote_target *remote, char *buf)
 {
 {
-  CORE_ADDR ptrval;
-  int ret, length, retlength;
+  CORE_ADDR statptr, nameptr;
+  int ret, namelength;
   char *pathname;
   LONGEST lnum;
   struct stat st;
   struct fio_stat fst;
 
   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
   char *pathname;
   LONGEST lnum;
   struct stat st;
   struct fio_stat fst;
 
   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
-  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
-    {
-      remote_fileio_ioerror ();
-      return;
-    }
-  /* Request pathname using 'm' packet */
-  pathname = alloca (length);
-  retlength = remote_read_bytes (ptrval, pathname, length);
-  if (retlength != length)
+  if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
     {
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
   /* 2. Parameter: Ptr to struct stat */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
       return;
     }
 
   /* 2. Parameter: Ptr to struct stat */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
+      return;
+    }
+  statptr = (CORE_ADDR) lnum;
+  
+  /* Request pathname using 'm' packet */
+  pathname = (char *) alloca (namelength);
+  if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
+    {
+      remote_fileio_ioerror (remote);
       return;
     }
       return;
     }
-  ptrval = (CORE_ADDR) lnum;
 
 
-  remote_fio_no_longjmp = 1;
   ret = stat (pathname, &st);
 
   if (ret == -1)
     {
   ret = stat (pathname, &st);
 
   if (ret == -1)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
       return;
     }
-  /* Only operate on regular files and directories */
+  /* Only operate on regular files and directories */
   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
     {
   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
     {
-      remote_fileio_reply (-1, FILEIO_EACCES);
+      remote_fileio_reply (remote, -1, FILEIO_EACCES);
       return;
     }
       return;
     }
-  if (ptrval)
+  if (statptr)
     {
     {
-      remote_fileio_to_fio_stat (&st, &fst);
-      remote_fileio_to_fio_uint (0, fst.fst_dev);
-      
-      retlength = remote_fileio_write_bytes (ptrval, (char *) &fst, sizeof fst);
-      if (retlength != sizeof fst)
+      host_to_fileio_stat (&st, &fst);
+      host_to_fileio_uint (0, fst.fst_dev);
+
+      errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
+      if (errno != 0)
        {
        {
-         remote_fileio_return_errno (-1);
+         remote_fileio_return_errno (remote, -1);
          return;
        }
     }
          return;
        }
     }
-  remote_fileio_return_success (ret);
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_fstat (char *buf)
+remote_fileio_func_fstat (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
 {
   CORE_ADDR ptrval;
-  int fd, ret, retlength;
+  int fd, ret;
   long target_fd;
   LONGEST lnum;
   struct stat st;
   long target_fd;
   LONGEST lnum;
   struct stat st;
@@ -1103,35 +922,41 @@ remote_fileio_func_fstat (char *buf)
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   /* 2. Parameter: Ptr to struct stat */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
       return;
     }
   /* 2. Parameter: Ptr to struct stat */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
 
       return;
     }
   ptrval = (CORE_ADDR) lnum;
 
-  remote_fio_no_longjmp = 1;
   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
     {
   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
     {
-      remote_fileio_to_fio_uint (1, fst.fst_dev);
+      host_to_fileio_uint (1, fst.fst_dev);
+      memset (&st, 0, sizeof (st));
       st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
       st.st_nlink = 1;
       st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
       st.st_nlink = 1;
+#ifdef HAVE_GETUID
       st.st_uid = getuid ();
       st.st_uid = getuid ();
+#endif
+#ifdef HAVE_GETGID
       st.st_gid = getgid ();
       st.st_gid = getgid ();
-      st.st_rdev = 0;
-      st.st_size = 0;
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
       st.st_blksize = 512;
       st.st_blksize = 512;
+#endif
+#if HAVE_STRUCT_STAT_ST_BLOCKS
       st.st_blocks = 0;
       st.st_blocks = 0;
+#endif
       if (!gettimeofday (&tv, NULL))
        st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
       else
       if (!gettimeofday (&tv, NULL))
        st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
       else
@@ -1143,58 +968,57 @@ remote_fileio_func_fstat (char *buf)
 
   if (ret == -1)
     {
 
   if (ret == -1)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
   if (ptrval)
     {
       return;
     }
   if (ptrval)
     {
-      remote_fileio_to_fio_stat (&st, &fst);
+      host_to_fileio_stat (&st, &fst);
 
 
-      retlength = remote_fileio_write_bytes (ptrval, (char *) &fst, sizeof fst);
-      if (retlength != sizeof fst)
+      errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
+      if (errno != 0)
        {
        {
-         remote_fileio_return_errno (-1);
+         remote_fileio_return_errno (remote, -1);
          return;
        }
     }
          return;
        }
     }
-  remote_fileio_return_success (ret);
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_gettimeofday (char *buf)
+remote_fileio_func_gettimeofday (remote_target *remote, char *buf)
 {
   LONGEST lnum;
   CORE_ADDR ptrval;
 {
   LONGEST lnum;
   CORE_ADDR ptrval;
-  int ret, retlength;
+  int ret;
   struct timeval tv;
   struct fio_timeval ftv;
 
   /* 1. Parameter: struct timeval pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
   struct timeval tv;
   struct fio_timeval ftv;
 
   /* 1. Parameter: struct timeval pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
       return;
     }
   ptrval = (CORE_ADDR) lnum;
-  /* 2. Parameter: some pointer value... */
+  /* 2. Parameter: some pointer value...  */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
       return;
     }
-  /* ...which has to be NULL */
+  /* ...which has to be NULL */
   if (lnum)
     {
   if (lnum)
     {
-      remote_fileio_reply (-1, FILEIO_EINVAL);
+      remote_fileio_reply (remote, -1, FILEIO_EINVAL);
       return;
     }
 
       return;
     }
 
-  remote_fio_no_longjmp = 1;
   ret = gettimeofday (&tv, NULL);
 
   if (ret == -1)
     {
   ret = gettimeofday (&tv, NULL);
 
   if (ret == -1)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
 
       return;
     }
 
@@ -1202,18 +1026,18 @@ remote_fileio_func_gettimeofday (char *buf)
     {
       remote_fileio_to_fio_timeval (&tv, &ftv);
 
     {
       remote_fileio_to_fio_timeval (&tv, &ftv);
 
-      retlength = remote_fileio_write_bytes (ptrval, (char *) &ftv, sizeof ftv);
-      if (retlength != sizeof ftv)
+      errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
+      if (errno != 0)
        {
        {
-         remote_fileio_return_errno (-1);
+         remote_fileio_return_errno (remote, -1);
          return;
        }
     }
          return;
        }
     }
-  remote_fileio_return_success (ret);
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_isatty (char *buf)
+remote_fileio_func_isatty (remote_target *remote, char *buf)
 {
   long target_fd;
   int fd;
 {
   long target_fd;
   int fd;
@@ -1221,82 +1045,88 @@ remote_fileio_func_isatty (char *buf)
   /* Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
   /* Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
       return;
     }
-  remote_fio_no_longjmp = 1;
   fd = remote_fileio_map_fd ((int) target_fd);
   fd = remote_fileio_map_fd ((int) target_fd);
-  remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
-                               fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
+  int ret = fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT ? 1 : 0;
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
 }
 
 static void
-remote_fileio_func_system (char *buf)
+remote_fileio_func_system (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
 {
   CORE_ADDR ptrval;
-  int ret, length, retlength;
-  char *cmdline;
+  int ret, length;
+  char *cmdline = NULL;
 
 
-  /* Check if system(3) has been explicitely allowed using the
-     `set remote system-call-allowed 1' command.  If not, return
-     EPERM */
-  if (!remote_fio_system_call_allowed)
+  /* Parameter: Ptr to commandline / length incl. trailing zero */
+  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
     {
-      remote_fileio_reply (-1, FILEIO_EPERM);
+      remote_fileio_ioerror (remote);
       return;
     }
 
       return;
     }
 
-  /* Parameter: Ptr to commandline / length incl. trailing zero */
-  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
+  if (length)
     {
     {
-      remote_fileio_ioerror ();
-      return;
+      /* Request commandline using 'm' packet */
+      cmdline = (char *) alloca (length);
+      if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
+       {
+         remote_fileio_ioerror (remote);
+         return;
+       }
     }
     }
-  /* Request commandline using 'm' packet */
-  cmdline = alloca (length);
-  retlength = remote_read_bytes (ptrval, cmdline, length);
-  if (retlength != length)
+  
+  /* Check if system(3) has been explicitly allowed using the
+     `set remote system-call-allowed 1' command.  If length is 0,
+     indicating a NULL parameter to the system call, return zero to
+     indicate a shell is not available.  Otherwise fail with EPERM.  */
+  if (!remote_fio_system_call_allowed)
     {
     {
-      remote_fileio_ioerror ();
+      if (!length)
+       remote_fileio_return_success (remote, 0);
+      else
+       remote_fileio_reply (remote, -1, FILEIO_EPERM);
       return;
     }
 
       return;
     }
 
-  remote_fio_no_longjmp = 1;
   ret = system (cmdline);
 
   ret = system (cmdline);
 
-  if (ret == -1)
-    remote_fileio_return_errno (-1);
+  if (!length)
+    remote_fileio_return_success (remote, ret);
+  else if (ret == -1)
+    remote_fileio_return_errno (remote, -1);
   else
   else
-    remote_fileio_return_success (WEXITSTATUS (ret));
+    remote_fileio_return_success (remote, WEXITSTATUS (ret));
 }
 
 static struct {
 }
 
 static struct {
-  char *name;
-  void (*func)(char *);
+  const char *name;
+  void (*func)(remote_target *remote, char *);
 } remote_fio_func_map[] = {
 } 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
-do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
+static void
+do_remote_fileio_request (remote_target *remote, char *buf)
 {
 {
-  char *buf = buf_arg;
   char *c;
   int idx;
 
   char *c;
   int idx;
 
-  remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
+  quit_handler = remote_fileio_quit_handler;
 
   c = strchr (++buf, ',');
   if (c)
 
   c = strchr (++buf, ',');
   if (c)
@@ -1306,74 +1136,174 @@ do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
   for (idx = 0; remote_fio_func_map[idx].name; ++idx)
     if (!strcmp (remote_fio_func_map[idx].name, buf))
       break;
   for (idx = 0; remote_fio_func_map[idx].name; ++idx)
     if (!strcmp (remote_fio_func_map[idx].name, buf))
       break;
-  if (!remote_fio_func_map[idx].name)  /* ERROR: No such function. */
-    return RETURN_ERROR;
-  remote_fio_func_map[idx].func (c);
-  return 0;
+  if (!remote_fio_func_map[idx].name)
+    remote_fileio_reply (remote, -1, FILEIO_ENOSYS);
+  else
+    remote_fio_func_map[idx].func (remote, c);
 }
 
 }
 
+/* Close any open descriptors, and reinitialize the file mapping.  */
+
 void
 void
-remote_fileio_request (char *buf)
+remote_fileio_reset (void)
 {
 {
-  int ex;
+  int ix;
+
+  for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
+    {
+      int fd = remote_fio_data.fd_map[ix];
+
+      if (fd >= 0)
+       close (fd);
+    }
+  if (remote_fio_data.fd_map)
+    {
+      xfree (remote_fio_data.fd_map);
+      remote_fio_data.fd_map = NULL;
+      remote_fio_data.fd_map_size = 0;
+    }
+}
 
 
-  remote_fileio_sig_init ();
+/* 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.  */
 
 
-  remote_fio_ctrl_c_flag = 0;
-  remote_fio_no_longjmp = 0;
+void
+remote_fileio_request (remote_target *remote, char *buf, int ctrlc_pending_p)
+{
+  /* Save the previous quit handler, so we can restore it.  No need
+     for a cleanup since we catch all exceptions below.  Note that the
+     quit handler is also restored by remote_fileio_reply just before
+     pushing a packet.  */
+  remote_fileio_o_quit_handler = quit_handler;
 
 
-  ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
-                        NULL, 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.  */
+      set_quit_flag ();
+      remote_fileio_reply (remote, -1, FILEIO_EINTR);
     }
     }
+  else
+    {
+      try
+       {
+         do_remote_fileio_request (remote, buf);
+       }
+      catch (const gdb_exception &ex)
+       {
+         if (ex.reason == RETURN_QUIT)
+           remote_fileio_reply (remote, -1, FILEIO_EINTR);
+         else
+           remote_fileio_reply (remote, -1, FILEIO_EIO);
+       }
+    }
+
+  quit_handler = remote_fileio_o_quit_handler;
+}
+\f
+
+/* Unpack an fio_uint_t.  */
 
 
-  remote_fileio_sig_exit ();
+static unsigned int
+remote_fileio_to_host_uint (fio_uint_t fnum)
+{
+  return extract_unsigned_integer ((gdb_byte *) fnum, 4,
+                                  BFD_ENDIAN_BIG);
 }
 
 }
 
+/* Unpack an fio_ulong_t.  */
+
+static ULONGEST
+remote_fileio_to_host_ulong (fio_ulong_t fnum)
+{
+  return extract_unsigned_integer ((gdb_byte *) fnum, 8,
+                                  BFD_ENDIAN_BIG);
+}
+
+/* Unpack an fio_mode_t.  */
+
+static mode_t
+remote_fileio_to_host_mode (fio_mode_t fnum)
+{
+  return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
+                                    0);
+}
+
+/* Unpack an fio_time_t.  */
+
+static time_t
+remote_fileio_to_host_time (fio_time_t fnum)
+{
+  return remote_fileio_to_host_uint (fnum);
+}
+
+
+/* See remote-fileio.h.  */
+
+void
+remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
+{
+  memset (st, 0, sizeof (struct stat));
+
+  st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
+  st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
+  st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
+  st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
+  st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
+  st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
+  st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
+  st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+  st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
+#endif
+#if HAVE_STRUCT_STAT_ST_BLOCKS
+  st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
+#endif
+  st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
+  st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
+  st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
+}
+\f
+
 static void
 static void
-set_system_call_allowed (char *args, int from_tty)
+set_system_call_allowed (const char *args, int from_tty)
 {
   if (args)
     {
       char *arg_end;
       int val = strtoul (args, &arg_end, 10);
 {
   if (args)
     {
       char *arg_end;
       int val = strtoul (args, &arg_end, 10);
+
       if (*args && *arg_end == '\0')
         {
          remote_fio_system_call_allowed = !!val;
          return;
        }
     }
       if (*args && *arg_end == '\0')
         {
          remote_fio_system_call_allowed = !!val;
          return;
        }
     }
-  error ("Illegal argument for \"set remote system-call-allowed\" command");
+  error (_("Illegal argument for \"set remote system-call-allowed\" command"));
 }
 
 static void
 }
 
 static void
-show_system_call_allowed (char *args, int from_tty)
+show_system_call_allowed (const char *args, int from_tty)
 {
   if (args)
 {
   if (args)
-    error ("Garbage after \"show remote system-call-allowed\" command: `%s'", args);
+    error (_("Garbage after \"show remote "
+            "system-call-allowed\" command: `%s'"), args);
   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
                     remote_fio_system_call_allowed ? "" : "not ");
 }
 
 void
   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
                     remote_fio_system_call_allowed ? "" : "not ");
 }
 
 void
-initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
-                         struct cmd_list_element *remote_show_cmdlist)
+initialize_remote_fileio (struct cmd_list_element **remote_set_cmdlist,
+                         struct cmd_list_element **remote_show_cmdlist)
 {
   add_cmd ("system-call-allowed", no_class,
           set_system_call_allowed,
 {
   add_cmd ("system-call-allowed", no_class,
           set_system_call_allowed,
-          "Set if the host system(3) call is allowed for the target.\n",
-          &remote_set_cmdlist);
+          _("Set if the host system(3) call is allowed for the target."),
+          remote_set_cmdlist);
   add_cmd ("system-call-allowed", no_class,
           show_system_call_allowed,
   add_cmd ("system-call-allowed", no_class,
           show_system_call_allowed,
-          "Show if the host system(3) call is allowed for the target.\n",
-          &remote_show_cmdlist);
+          _("Show if the host system(3) call is allowed for the target."),
+          remote_show_cmdlist);
 }
 }
This page took 0.054419 seconds and 4 git commands to generate.