From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23344 invoked by alias); 19 Jan 2012 10:02:29 -0000 Received: (qmail 23327 invoked by uid 22791); 19 Jan 2012 10:02:20 -0000 X-SWARE-Spam-Status: No, hits=0.3 required=5.0 tests=AWL,BAYES_00,MSGID_FROM_MTA_HEADER,TW_CP,TW_WC,T_RP_MATCHES_RCVD,URIBL_BLACK X-Spam-Check-By: sourceware.org Received: from e06smtp15.uk.ibm.com (HELO e06smtp15.uk.ibm.com) (195.75.94.111) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 19 Jan 2012 10:02:04 +0000 Received: from /spool/local by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 19 Jan 2012 10:02:03 -0000 Received: from d06nrmr1407.portsmouth.uk.ibm.com (9.149.38.185) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 19 Jan 2012 10:02:01 -0000 Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1407.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q0JA20vr2232446 for ; Thu, 19 Jan 2012 10:02:00 GMT Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q0JA1sdA016949 for ; Thu, 19 Jan 2012 03:01:54 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id q0JA1qU2016860 for ; Thu, 19 Jan 2012 03:01:53 -0700 Message-Id: <201201191001.q0JA1qU2016860@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Thu, 19 Jan 2012 11:01:52 +0100 Subject: [rfc v3][4/6] Readlink as file I/O target operation To: gdb-patches@sourceware.org Date: Thu, 19 Jan 2012 10:03:00 -0000 From: "Ulrich Weigand" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit x-cbid: 12011910-0342-0000-0000-000000AA4B80 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-01/txt/msg00690.txt.bz2 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. Index: gdb-head/gdb/gdbserver/hostio.c =================================================================== --- gdb-head.orig/gdb/gdbserver/hostio.c 2012-01-19 10:35:58.000000000 +0100 +++ gdb-head/gdb/gdbserver/hostio.c 2012-01-19 10:40:27.000000000 +0100 @@ -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_ 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; Index: gdb-head/gdb/inf-child.c =================================================================== --- gdb-head.orig/gdb/inf-child.c 2012-01-19 10:39:32.000000000 +0100 +++ gdb-head/gdb/inf-child.c 2012-01-19 10:40:27.000000000 +0100 @@ -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 *fil 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; } Index: gdb-head/gdb/remote.c =================================================================== --- gdb-head.orig/gdb/remote.c 2012-01-19 10:39:32.000000000 +0100 +++ gdb-head/gdb/remote.c 2012-01-19 10:40:27.000000000 +0100 @@ -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 *filena 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 connecte 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 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); Index: gdb-head/gdb/target.c =================================================================== --- gdb-head.orig/gdb/target.c 2012-01-19 10:39:32.000000000 +0100 +++ gdb-head/gdb/target.c 2012-01-19 10:40:27.000000000 +0100 @@ -3319,6 +3319,33 @@ target_fileio_unlink (const char *filena 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) { Index: gdb-head/gdb/target.h =================================================================== --- gdb-head.orig/gdb/target.h 2012-01-19 10:39:32.000000000 +0100 +++ gdb-head/gdb/target.h 2012-01-19 10:40:27.000000000 +0100 @@ -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, 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 Index: gdb-head/gdb/doc/gdb.texinfo =================================================================== --- gdb-head.orig/gdb/doc/gdb.texinfo 2012-01-19 10:38:32.000000000 +0100 +++ gdb-head/gdb/doc/gdb.texinfo 2012-01-19 10:40:27.000000000 +0100 @@ -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 Index: gdb-head/gdb/config.in =================================================================== --- gdb-head.orig/gdb/config.in 2012-01-19 10:39:32.000000000 +0100 +++ gdb-head/gdb/config.in 2012-01-19 10:40:27.000000000 +0100 @@ -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 Index: gdb-head/gdb/configure =================================================================== --- gdb-head.orig/gdb/configure 2012-01-19 10:40:05.000000000 +0100 +++ gdb-head/gdb/configure 2012-01-19 10:40:37.000000000 +0100 @@ -12932,7 +12932,7 @@ $as_echo "#define HAVE_WORKING_FORK 1" > 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 \ Index: gdb-head/gdb/configure.ac =================================================================== --- gdb-head.orig/gdb/configure.ac 2012-01-19 10:39:32.000000000 +0100 +++ gdb-head/gdb/configure.ac 2012-01-19 10:40:27.000000000 +0100 @@ -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 \ -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com