From patchwork Fri Jan 20 18:14:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 6327 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id E144C23F8D for ; Fri, 20 Jan 2012 18:14:50 +0000 (UTC) Received: from mail-bk0-f52.google.com (mail-bk0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id CAEF2A18202 for ; Fri, 20 Jan 2012 18:14:50 +0000 (UTC) Received: by bkar19 with SMTP id r19so768534bka.11 for ; Fri, 20 Jan 2012 10:14:50 -0800 (PST) Received: by 10.204.10.73 with SMTP id o9mr6678015bko.99.1327083290483; Fri, 20 Jan 2012 10:14:50 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.82.144 with SMTP id ac16cs13092bkc; Fri, 20 Jan 2012 10:14:50 -0800 (PST) Received: by 10.213.19.210 with SMTP id c18mr7612806ebb.130.1327083289011; Fri, 20 Jan 2012 10:14:49 -0800 (PST) Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com. [195.75.94.109]) by mx.google.com with ESMTPS id c1si2345258eec.125.2012.01.20.10.14.48 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 20 Jan 2012 10:14:49 -0800 (PST) Received-SPF: pass (google.com: domain of uweigand@de.ibm.com designates 195.75.94.109 as permitted sender) client-ip=195.75.94.109; Authentication-Results: mx.google.com; spf=pass (google.com: domain of uweigand@de.ibm.com designates 195.75.94.109 as permitted sender) smtp.mail=uweigand@de.ibm.com Received: from /spool/local by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 20 Jan 2012 18:14:48 -0000 Received: from d06nrmr1407.portsmouth.uk.ibm.com (9.149.38.185) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 20 Jan 2012 18:14:46 -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 q0KIEkHo2535582 for ; Fri, 20 Jan 2012 18:14:46 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 q0KIEkHP032651 for ; Fri, 20 Jan 2012 11:14:46 -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 q0KIEiii032642 for ; Fri, 20 Jan 2012 11:14:44 -0700 Message-Id: <201201201814.q0KIEiii032642@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Fri, 20 Jan 2012 19:14:44 +0100 Subject: [rfc v4][4/6] Readlink as file I/O target operation To: patches@linaro.org Date: Fri, 20 Jan 2012 19:14:44 +0100 (CET) From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 x-cbid: 12012018-2966-0000-0000-000002FA81DE http://sourceware.org/ml/gdb-patches/2012-01/msg00689.html 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 \