Index: gdb/gdbserver/hostio.c |
diff --git a/gdb/gdbserver/hostio.c b/gdb/gdbserver/hostio.c |
index b1508ec3babb41bc00954722efb7629790d36ac1..72e334c414ce19ec5f042dda95575090d469c971 100644 |
--- a/gdb/gdbserver/hostio.c |
+++ b/gdb/gdbserver/hostio.c |
@@ -328,10 +328,15 @@ handle_pread (char *own_buf, int *new_packet_len) |
#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) |
{ |
@@ -376,10 +381,15 @@ handle_pwrite (char *own_buf, int packet_len) |
#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) |
{ |
@@ -456,6 +466,41 @@ handle_unlink (char *own_buf) |
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); |
+ 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 |
@@ -471,6 +516,8 @@ handle_vFile (char *own_buf, int packet_len, int *new_packet_len) |
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; |