summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog18
-rw-r--r--gdb/config.in3
-rwxr-xr-xgdb/configure2
-rw-r--r--gdb/configure.ac2
-rw-r--r--gdb/doc/ChangeLog6
-rw-r--r--gdb/doc/gdb.texinfo14
-rw-r--r--gdb/gdbserver/ChangeLog5
-rw-r--r--gdb/gdbserver/hostio.c33
-rw-r--r--gdb/inf-child.c34
-rw-r--r--gdb/remote.c43
-rw-r--r--gdb/target.c27
-rw-r--r--gdb/target.h10
12 files changed, 195 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 65cfb170968..db22bf33d78 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,21 @@
+2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * configure.ac [AC_CHECK_FUNCS]: Check for readlink.
+ * config.in, configure: Regenerate.
+
+ * target.h (struct target_ops): Add to_fileio_readlink.
+ (target_fileio_readlink): Add prototype.
+ * target.c (target_fileio_readlink): New function.
+
+ * inf-child.c: Conditionally include <sys/param.h>.
+ (inf_child_fileio_readlink): New function.
+ (inf_child_target): Install it.
+
+ * remote.c (PACKET_vFile_readlink): New enum value.
+ (remote_hostio_readlink): New function.
+ (init_remote_ops): Install it.
+ (_initialize_remote): Handle vFile:readlink packet type.
+
2012-01-20 Pedro Alves <palves@redhat.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
diff --git a/gdb/config.in b/gdb/config.in
index 540234fbb2a..bae17635a33 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -474,6 +474,9 @@
/* Define to 1 if wcwidth is declared even after undefining macros. */
#undef HAVE_RAW_DECL_WCWIDTH
+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
diff --git a/gdb/configure b/gdb/configure
index 5dd99fbc9fd..920c7160eb8 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -12932,7 +12932,7 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
fi
for ac_func in canonicalize_file_name realpath getrusage getuid getgid \
- pipe poll pread pread64 pwrite resize_term \
+ pipe poll pread pread64 pwrite readlink resize_term \
sbrk setpgid setpgrp setsid \
sigaction sigprocmask sigsetmask socketpair syscall \
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
diff --git a/gdb/configure.ac b/gdb/configure.ac
index aca96b8ce34..6f9a42cfd1b 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1064,7 +1064,7 @@ AC_FUNC_ALLOCA
AC_FUNC_MMAP
AC_FUNC_VFORK
AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid getgid \
- pipe poll pread pread64 pwrite resize_term \
+ pipe poll pread pread64 pwrite readlink resize_term \
sbrk setpgid setpgrp setsid \
sigaction sigprocmask sigsetmask socketpair syscall \
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index e5a0dacee77..99bc8817c7b 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,9 @@
+2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * gdb.texinfo (Remote Configuration): Document
+ "set remote hostio-readlink-packet" command.
+ (General Query Packets): Document vFile:readlink packet.
+
2012-01-16 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Specify Location): Document relative file name
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 49db18933bd..20b0b67c20a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17455,6 +17455,10 @@ are:
@tab @code{vFile:unlink}
@tab @code{remote delete}
+@item @code{hostio-readlink-packet}
+@tab @code{vFile:readlink}
+@tab Host I/O
+
@item @code{noack-packet}
@tab @code{QStartNoAckMode}
@tab Packet acknowledgment
@@ -36205,6 +36209,16 @@ error occurred.
Delete the file at @var{pathname} on the target. Return 0,
or -1 if an error occurs. @var{pathname} is a string.
+@item vFile:readlink: @var{filename}
+Read value of symbolic link @var{filename} on the target. Return
+the number of bytes read, or -1 if an error occurs.
+
+The data read should be returned as a binary attachment on success.
+If zero bytes were read, the response should include an empty binary
+attachment (i.e.@: a trailing semicolon). The return value is the
+number of target bytes read; the binary attachment may be longer if
+some characters were escaped.
+
@end table
@node Interrupts
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 72f02861bd7..0cb67da17b4 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * hostio.c (handle_readlink): New function.
+ (handle_vFile): Call it to handle "vFile:readlink" packets.
+
2012-01-20 Pedro Alves <palves@redhat.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
diff --git a/gdb/gdbserver/hostio.c b/gdb/gdbserver/hostio.c
index b1508ec3bab..34e4fa8e09e 100644
--- a/gdb/gdbserver/hostio.c
+++ b/gdb/gdbserver/hostio.c
@@ -456,6 +456,37 @@ handle_unlink (char *own_buf)
hostio_reply (own_buf, ret);
}
+static void
+handle_readlink (char *own_buf, int *new_packet_len)
+{
+ 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);
+}
+
/* Handle all the 'F' file transfer packets. */
int
@@ -471,6 +502,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;
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index 0dda3315187..22718248b13 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -29,6 +29,9 @@
#include "inf-child.h"
#include "gdb/fileio.h"
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h> /* for MAXPATHLEN */
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -299,6 +302,36 @@ inf_child_fileio_unlink (const char *filename, int *target_errno)
return ret;
}
+/* Read value of symbolic link FILENAME on the target. Return a
+ null-terminated string allocated via xmalloc, or NULL if an error
+ occurs (and set *TARGET_ERRNO). */
+static char *
+inf_child_fileio_readlink (const char *filename, int *target_errno)
+{
+ /* We support readlink only on systems that also provide a compile-time
+ maximum path length (MAXPATHLEN), at least for now. */
+#if defined (HAVE_READLINK) && defined (MAXPATHLEN)
+ char buf[MAXPATHLEN];
+ int len;
+ char *ret;
+
+ len = readlink (filename, buf, sizeof buf);
+ if (len < 0)
+ {
+ *target_errno = inf_child_errno_to_fileio_error (errno);
+ return NULL;
+ }
+
+ ret = xmalloc (len + 1);
+ memcpy (ret, buf, len);
+ ret[len] = '\0';
+ return ret;
+#else
+ *target_errno = FILEIO_ENOSYS;
+ return NULL;
+#endif
+}
+
struct target_ops *
inf_child_target (void)
@@ -336,6 +369,7 @@ inf_child_target (void)
t->to_fileio_pread = inf_child_fileio_pread;
t->to_fileio_close = inf_child_fileio_close;
t->to_fileio_unlink = inf_child_fileio_unlink;
+ t->to_fileio_readlink = inf_child_fileio_readlink;
t->to_magic = OPS_MAGIC;
return t;
}
diff --git a/gdb/remote.c b/gdb/remote.c
index 89d491ee3be..f3485361797 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1238,6 +1238,7 @@ enum {
PACKET_vFile_pwrite,
PACKET_vFile_close,
PACKET_vFile_unlink,
+ PACKET_vFile_readlink,
PACKET_qXfer_auxv,
PACKET_qXfer_features,
PACKET_qXfer_libraries,
@@ -9358,6 +9359,44 @@ remote_hostio_unlink (const char *filename, int *remote_errno)
remote_errno, NULL, NULL);
}
+/* Read value of symbolic link FILENAME on the remote target. Return
+ a null-terminated string allocated via xmalloc, or NULL if an error
+ occurs (and set *REMOTE_ERRNO). */
+
+static char *
+remote_hostio_readlink (const char *filename, int *remote_errno)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *p = rs->buf;
+ char *attachment;
+ int left = get_remote_packet_size ();
+ int len, attachment_len;
+ int read_len;
+ char *ret;
+
+ remote_buffer_add_string (&p, &left, "vFile:readlink:");
+
+ remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
+ strlen (filename));
+
+ len = remote_hostio_send_command (p - rs->buf, PACKET_vFile_readlink,
+ remote_errno, &attachment,
+ &attachment_len);
+
+ if (len < 0)
+ return NULL;
+
+ ret = xmalloc (len + 1);
+
+ read_len = remote_unescape_input (attachment, attachment_len,
+ ret, len);
+ if (read_len != len)
+ error (_("Readlink returned %d, but %d bytes."), len, read_len);
+
+ ret[len] = '\0';
+ return ret;
+}
+
static int
remote_fileio_errno_to_host (int errnum)
{
@@ -10679,6 +10718,7 @@ Specify the serial device it is connected to\n\
remote_ops.to_fileio_pread = remote_hostio_pread;
remote_ops.to_fileio_close = remote_hostio_close;
remote_ops.to_fileio_unlink = remote_hostio_unlink;
+ remote_ops.to_fileio_readlink = remote_hostio_readlink;
remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
remote_ops.to_trace_init = remote_trace_init;
@@ -11177,6 +11217,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_unlink],
"vFile:unlink", "hostio-unlink", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_readlink],
+ "vFile:readlink", "hostio-readlink", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_vAttach],
"vAttach", "attach", 0);
diff --git a/gdb/target.c b/gdb/target.c
index 595c2ced6c3..32260e10df2 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3318,6 +3318,33 @@ target_fileio_unlink (const char *filename, int *target_errno)
return -1;
}
+/* Read value of symbolic link FILENAME on the target. Return a
+ null-terminated string allocated via xmalloc, or NULL if an error
+ occurs (and set *TARGET_ERRNO). */
+char *
+target_fileio_readlink (const char *filename, int *target_errno)
+{
+ struct target_ops *t;
+
+ for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ {
+ if (t->to_fileio_readlink != NULL)
+ {
+ char *ret = t->to_fileio_readlink (filename, target_errno);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_fileio_readlink (%s) = %s (%d)\n",
+ filename, ret? ret : "(nil)",
+ ret? 0 : *target_errno);
+ return ret;
+ }
+ }
+
+ *target_errno = FILEIO_ENOSYS;
+ return NULL;
+}
+
static void
target_fileio_close_cleanup (void *opaque)
{
diff --git a/gdb/target.h b/gdb/target.h
index 4bbf4de88d1..e1deb5ef33e 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -709,6 +709,11 @@ struct target_ops
occurs (and set *TARGET_ERRNO). */
int (*to_fileio_unlink) (const char *filename, int *target_errno);
+ /* Read value of symbolic link FILENAME on the target. Return a
+ null-terminated string allocated via xmalloc, or NULL if an error
+ occurs (and set *TARGET_ERRNO). */
+ char *(*to_fileio_readlink) (const char *filename, int *target_errno);
+
/* Tracepoint-related operations. */
@@ -1546,6 +1551,11 @@ extern int target_fileio_close (int fd, int *target_errno);
occurs (and set *TARGET_ERRNO). */
extern int target_fileio_unlink (const char *filename, int *target_errno);
+/* Read value of symbolic link FILENAME on the target. Return a
+ null-terminated string allocated via xmalloc, or NULL if an error
+ occurs (and set *TARGET_ERRNO). */
+extern char *target_fileio_readlink (const char *filename, int *target_errno);
+
/* Read target file FILENAME. The return value will be -1 if the transfer
fails or is not supported; 0 if the object is empty; or the length
of the object otherwise. If a positive value is returned, a