From b9e7b9c3de60f6aef716ac169d82418ea27d4331 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Fri, 20 Jan 2012 09:47:32 +0000 Subject: [PATCH] ChangeLog: * 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 . (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. doc/ChangeLog: * gdb.texinfo (Remote Configuration): Document "set remote hostio-readlink-packet" command. (General Query Packets): Document vFile:readlink packet. gdbserver/ChangeLog: * hostio.c (handle_readlink): New function. (handle_vFile): Call it to handle "vFile:readlink" packets. --- gdb/ChangeLog | 18 +++++++++++++++++ gdb/config.in | 3 +++ gdb/configure | 2 +- gdb/configure.ac | 2 +- gdb/doc/ChangeLog | 6 ++++++ gdb/doc/gdb.texinfo | 14 ++++++++++++++ gdb/gdbserver/ChangeLog | 5 +++++ gdb/gdbserver/hostio.c | 33 +++++++++++++++++++++++++++++++ gdb/inf-child.c | 34 ++++++++++++++++++++++++++++++++ gdb/remote.c | 43 +++++++++++++++++++++++++++++++++++++++++ gdb/target.c | 27 ++++++++++++++++++++++++++ gdb/target.h | 10 ++++++++++ 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 + + * 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 . + (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 Ulrich Weigand 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 + + * gdb.texinfo (Remote Configuration): Document + "set remote hostio-readlink-packet" command. + (General Query Packets): Document vFile:readlink packet. + 2012-01-16 Tom Tromey * 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 + + * hostio.c (handle_readlink): New function. + (handle_vFile): Call it to handle "vFile:readlink" packets. + 2012-01-20 Pedro Alves Ulrich Weigand 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 /* for MAXPATHLEN */ +#endif #include #include #include @@ -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 -- 2.30.2