2012-03-05 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / gdb / remote-fileio.c
index 22311ba186e380cc0b7a1db3e8231cef659785c0..ee43dd686e0cfa055b0a3d2852214256a902c996 100644 (file)
@@ -1,7 +1,6 @@
 /* Remote File-I/O communications
 
-   Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,7 +17,7 @@
    You should have received a copy of the GNU General Public License
    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 "gdb_string.h"
 #include "exceptions.h"
 #include "remote-fileio.h"
 #include "event-loop.h"
+#include "target.h"
+#include "filenames.h"
 
 #include <fcntl.h>
 #include <sys/time.h>
 #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>
 
@@ -100,6 +101,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;
 }
@@ -141,7 +143,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
-   binary mode. */
+   binary mode.  */
 #ifdef O_BINARY
   hflags |= O_BINARY;
 #endif
@@ -380,7 +382,7 @@ remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
   return 0;
 }
 
-/* Convert to big endian */
+/* Convert to big endian */
 static void
 remote_fileio_to_be (LONGEST num, char *buf, int bytes)
 {
@@ -425,7 +427,7 @@ remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
 {
   LONGEST blksize;
 
-  /* `st_dev' is set in the calling function */
+  /* `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);
@@ -568,8 +570,8 @@ remote_fileio_badfd (void)
 static void
 remote_fileio_return_errno (int retcode)
 {
-  remote_fileio_reply (retcode,
-                      retcode < 0 ? remote_fileio_errno_to_target (errno) : 0);
+  remote_fileio_reply (retcode, retcode < 0
+                      ? remote_fileio_errno_to_target (errno) : 0);
 }
 
 static void
@@ -578,36 +580,18 @@ remote_fileio_return_success (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, gdb_byte *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;
-}
-
 static void
 remote_fileio_func_open (char *buf)
 {
   CORE_ADDR ptrval;
-  int length, retlength;
+  int length;
   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))
     {
       remote_fileio_ioerror ();
@@ -628,10 +612,9 @@ remote_fileio_func_open (char *buf)
     }
   mode = remote_fileio_mode_to_host (num, 1);
 
-  /* Request pathname using 'm' packet */
+  /* Request pathname */
   pathname = alloca (length);
-  retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
-  if (retlength != length)
+  if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
     {
       remote_fileio_ioerror ();
       return;
@@ -639,7 +622,7 @@ remote_fileio_func_open (char *buf)
 
   /* 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))
@@ -800,7 +783,7 @@ remote_fileio_func_read (char *buf)
          {
            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;
          }
@@ -809,9 +792,9 @@ remote_fileio_func_read (char *buf)
 
   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)
@@ -828,7 +811,7 @@ remote_fileio_func_write (char *buf)
   long target_fd, num;
   LONGEST lnum;
   CORE_ADDR ptrval;
-  int fd, ret, retlength;
+  int fd, ret;
   gdb_byte *buffer;
   size_t length;
 
@@ -860,8 +843,7 @@ remote_fileio_func_write (char *buf)
   length = (size_t) num;
     
   buffer = (gdb_byte *) xmalloc (length);
-  retlength = remote_read_bytes (ptrval, buffer, length);
-  if (retlength != length)
+  if (target_read_memory (ptrval, buffer, length) != 0)
     {
       xfree (buffer);
       remote_fileio_ioerror ();
@@ -884,7 +866,8 @@ remote_fileio_func_write (char *buf)
       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;
     }
 
@@ -954,7 +937,7 @@ static void
 remote_fileio_func_rename (char *buf)
 {
   CORE_ADDR old_ptr, new_ptr;
-  int old_len, new_len, retlength;
+  int old_len, new_len;
   char *oldpath, *newpath;
   int ret, of, nf;
   struct stat ost, nst;
@@ -975,8 +958,7 @@ remote_fileio_func_rename (char *buf)
   
   /* Request oldpath using 'm' packet */
   oldpath = alloca (old_len);
-  retlength = remote_read_bytes (old_ptr, (gdb_byte *) oldpath, old_len);
-  if (retlength != old_len)
+  if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
     {
       remote_fileio_ioerror ();
       return;
@@ -984,14 +966,13 @@ remote_fileio_func_rename (char *buf)
   
   /* Request newpath using 'm' packet */
   newpath = alloca (new_len);
-  retlength = remote_read_bytes (new_ptr, (gdb_byte *) newpath, new_len);
-  if (retlength != new_len)
+  if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
     {
       remote_fileio_ioerror ();
       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))
@@ -1008,11 +989,11 @@ remote_fileio_func_rename (char *buf)
     {
       /* 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__
-      /* 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))
@@ -1021,15 +1002,17 @@ 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))
+                 if (IS_DIR_SEPARATOR (newfullpath[len])
+                     && !filename_ncmp (oldfullpath, newfullpath, len))
                    errno = EINVAL;
                  else
                    errno = EEXIST;
@@ -1048,7 +1031,7 @@ static void
 remote_fileio_func_unlink (char *buf)
 {
   CORE_ADDR ptrval;
-  int length, retlength;
+  int length;
   char *pathname;
   int ret;
   struct stat st;
@@ -1061,15 +1044,14 @@ remote_fileio_func_unlink (char *buf)
     }
   /* Request pathname using 'm' packet */
   pathname = alloca (length);
-  retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
-  if (retlength != length)
+  if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
     {
       remote_fileio_ioerror ();
       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))
     {
       remote_fileio_reply (-1, FILEIO_ENODEV);
@@ -1089,7 +1071,7 @@ static void
 remote_fileio_func_stat (char *buf)
 {
   CORE_ADDR statptr, nameptr;
-  int ret, namelength, retlength;
+  int ret, namelength;
   char *pathname;
   LONGEST lnum;
   struct stat st;
@@ -1112,8 +1094,7 @@ remote_fileio_func_stat (char *buf)
   
   /* Request pathname using 'm' packet */
   pathname = alloca (namelength);
-  retlength = remote_read_bytes (nameptr, (gdb_byte *) pathname, namelength);
-  if (retlength != namelength)
+  if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
     {
       remote_fileio_ioerror ();
       return;
@@ -1127,7 +1108,7 @@ remote_fileio_func_stat (char *buf)
       remote_fileio_return_errno (-1);
       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))
     {
       remote_fileio_reply (-1, FILEIO_EACCES);
@@ -1137,10 +1118,9 @@ remote_fileio_func_stat (char *buf)
     {
       remote_fileio_to_fio_stat (&st, &fst);
       remote_fileio_to_fio_uint (0, fst.fst_dev);
-      
-      retlength = remote_fileio_write_bytes (statptr,
-                                            (gdb_byte *) &fst, sizeof fst);
-      if (retlength != sizeof fst)
+
+      errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
+      if (errno != 0)
        {
          remote_fileio_return_errno (-1);
          return;
@@ -1184,20 +1164,15 @@ remote_fileio_func_fstat (char *buf)
   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
     {
       remote_fileio_to_fio_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;
 #ifdef HAVE_GETUID
       st.st_uid = getuid ();
-#else
-      st.st_uid = 0;
 #endif
 #ifdef HAVE_GETGID
       st.st_gid = getgid ();
-#else
-      st.st_gid = 0;
 #endif
-      st.st_rdev = 0;
-      st.st_size = 0;
 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
       st.st_blksize = 512;
 #endif
@@ -1222,8 +1197,8 @@ remote_fileio_func_fstat (char *buf)
     {
       remote_fileio_to_fio_stat (&st, &fst);
 
-      retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &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);
          return;
@@ -1248,13 +1223,13 @@ remote_fileio_func_gettimeofday (char *buf)
       return;
     }
   ptrval = (CORE_ADDR) lnum;
-  /* 2. Parameter: some pointer value... */
+  /* 2. Parameter: some pointer value...  */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
       remote_fileio_ioerror ();
       return;
     }
-  /* ...which has to be NULL */
+  /* ...which has to be NULL */
   if (lnum)
     {
       remote_fileio_reply (-1, FILEIO_EINVAL);
@@ -1274,8 +1249,8 @@ remote_fileio_func_gettimeofday (char *buf)
     {
       remote_fileio_to_fio_timeval (&tv, &ftv);
 
-      retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &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);
          return;
@@ -1320,8 +1295,7 @@ remote_fileio_func_system (char *buf)
     {
       /* Request commandline using 'm' packet */
       cmdline = alloca (length);
-      retlength = remote_read_bytes (ptrval, (gdb_byte *) cmdline, length);
-      if (retlength != length)
+      if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
        {
          remote_fileio_ioerror ();
          return;
@@ -1388,7 +1362,7 @@ 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;
-  if (!remote_fio_func_map[idx].name)  /* ERROR: No such function. */
+  if (!remote_fio_func_map[idx].name)  /* ERROR: No such function.  */
     return RETURN_ERROR;
   remote_fio_func_map[idx].func (c);
   return 0;
@@ -1416,8 +1390,8 @@ remote_fileio_reset (void)
     }
 }
 
-/* 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
+/* 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
@@ -1441,7 +1415,8 @@ remote_fileio_request (char *buf, int ctrlc_pending_p)
       remote_fio_ctrl_c_flag = 0;
       remote_fio_no_longjmp = 0;
 
-      ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
+      ex = catch_exceptions (current_uiout,
+                            do_remote_fileio_request, (void *)buf,
                             RETURN_MASK_ALL);
       switch (ex)
        {
@@ -1466,6 +1441,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;
@@ -1479,7 +1455,8 @@ static void
 show_system_call_allowed (char *args, int from_tty)
 {
   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 ");
 }
This page took 0.030227 seconds and 4 git commands to generate.