/* Host file transfer support for gdbserver.
- Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2007-2013 Free Software Foundation, Inc.
Contributed by CodeSourcery.
if (escaped)
{
- free (data);
+ free (*data);
return -1;
}
#ifdef HAVE_PREAD
ret = pread (fd, data, len, offset);
#else
- ret = lseek (fd, offset, SEEK_SET);
- if (ret != -1)
- ret = read (fd, data, len);
+ ret = -1;
#endif
+ /* If we have no pread or it failed for this file, use lseek/read. */
+ if (ret == -1)
+ {
+ ret = lseek (fd, offset, SEEK_SET);
+ if (ret != -1)
+ ret = read (fd, data, len);
+ }
if (ret == -1)
{
#ifdef HAVE_PWRITE
ret = pwrite (fd, data, len, offset);
#else
- ret = lseek (fd, offset, SEEK_SET);
- if (ret != -1)
- ret = write (fd, data, len);
+ ret = -1;
#endif
+ /* If we have no pwrite or it failed for this file, use lseek/write. */
+ if (ret == -1)
+ {
+ ret = lseek (fd, offset, SEEK_SET);
+ if (ret != -1)
+ ret = write (fd, data, len);
+ }
if (ret == -1)
{
}
open_fd_p = &open_fds;
- while (*open_fd_p && (*open_fd_p)->fd != fd)
+ /* We know that fd is in the list, thanks to require_valid_fd. */
+ while ((*open_fd_p)->fd != fd)
open_fd_p = &(*open_fd_p)->next;
old_fd = *open_fd_p;
hostio_reply (own_buf, ret);
}
+static void
+handle_readlink (char *own_buf, int *new_packet_len)
+{
+#if defined (HAVE_READLINK)
+ char filename[PATH_MAX], linkname[PATH_MAX];
+ char *p;
+ int ret, bytes_sent;
+
+ p = own_buf + strlen ("vFile:readlink:");
+
+ if (require_filename (&p, filename)
+ || require_end (p))
+ {
+ hostio_packet_error (own_buf);
+ return;
+ }
+
+ ret = readlink (filename, linkname, sizeof (linkname) - 1);
+ if (ret == -1)
+ {
+ hostio_error (own_buf);
+ return;
+ }
+
+ bytes_sent = hostio_reply_with_data (own_buf, linkname, ret, new_packet_len);
+
+ /* If the response does not fit into a single packet, do not attempt
+ to return a partial response, but simply fail. */
+ if (bytes_sent < ret)
+ sprintf (own_buf, "F-1,%x", FILEIO_ENAMETOOLONG);
+#else /* ! HAVE_READLINK */
+ sprintf (own_buf, "F-1,%x", FILEIO_ENOSYS);
+#endif
+}
+
/* Handle all the 'F' file transfer packets. */
int
handle_close (own_buf);
else if (strncmp (own_buf, "vFile:unlink:", 13) == 0)
handle_unlink (own_buf);
+ else if (strncmp (own_buf, "vFile:readlink:", 15) == 0)
+ handle_readlink (own_buf, new_packet_len);
else
return 0;