From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 39274 invoked by alias); 19 Sep 2017 04:28:57 -0000 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 Received: (qmail 39207 invoked by uid 89); 19 Sep 2017 04:28:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=yyyymmdd, UD:al, 12456, yyyy-mm-dd X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 19 Sep 2017 04:28:54 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2A5A7C047B77 for ; Tue, 19 Sep 2017 04:28:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2A5A7C047B77 Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=sergiodj@redhat.com Received: from psique.yyz.redhat.com (unused-10-15-17-193.yyz.redhat.com [10.15.17.193]) by smtp.corp.redhat.com (Postfix) with ESMTP id C653660619; Tue, 19 Sep 2017 04:28:52 +0000 (UTC) From: Sergio Durigan Junior To: GDB Patches Cc: Pedro Alves , Sergio Durigan Junior Subject: [PATCH v2 3/5] Introduce gdb_chdir Date: Tue, 19 Sep 2017 04:28:00 -0000 Message-Id: <20170919042842.9210-4-sergiodj@redhat.com> In-Reply-To: <20170919042842.9210-1-sergiodj@redhat.com> References: <20170912042325.14927-1-sergiodj@redhat.com> <20170919042842.9210-1-sergiodj@redhat.com> X-IsSubscribed: yes X-SW-Source: 2017-09/txt/msg00461.txt.bz2 In order to be able to change the inferior's directory before its execution, it is necessary to perform a tilde expansion of the directory provided by the user and then chdir into the resulting dir. This is what gdb_chdir does. Unfortunately it is not possible to use "tilde_expand" from readline because this is common code and gdbserver doesn't use readline. For that reason I decided to go with "glob" and its GNU extension, GLOB_TILDE. With the import of the "glob" module from gnulib, this is a no-brainer. gdb/ChangeLog: yyyy-mm-dd Sergio Durigan Junior * Makefile.in (SFILES): Add gdb_chdir.c. (HFILES_NO_SRCDIR): Add gdb_chdir.h. (COMMON_OBS): Add gdb_chdir.o. * cli/cli-cmds.c: Include "gdb_chdir.h". (cd_command): Use "gdb_chdir" instead of "tilde_expand plus chdir". * common/gdb_chdir.c: New file. * common/gdb_chdir.h: Likewise. gdb/gdbserver/ChangeLog: yyyy-mm-dd Sergio Durigan Junior * Makefile.in (SFILES): Add $(srcdir)/common/gdb_chdir.c. (OBS): Add gdb_chdir.o. --- gdb/Makefile.in | 3 ++ gdb/cli/cli-cmds.c | 20 +++++----- gdb/common/gdb_chdir.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/common/gdb_chdir.h | 26 +++++++++++++ gdb/gdbserver/Makefile.in | 2 + 5 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 gdb/common/gdb_chdir.c create mode 100644 gdb/common/gdb_chdir.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 9dfc117b2f..1f093e6c0f 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1245,6 +1245,7 @@ SFILES = \ common/filestuff.c \ common/format.c \ common/job-control.c \ + common/gdb_chdir.c \ common/gdb_vecs.c \ common/new-op.c \ common/print-utils.c \ @@ -1529,6 +1530,7 @@ HFILES_NO_SRCDIR = \ common/fileio.h \ common/format.h \ common/gdb_assert.h \ + common/gdb_chdir.h \ common/gdb_locale.h \ common/gdb_setjmp.h \ common/gdb_signals.h \ @@ -1734,6 +1736,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ frame-unwind.o \ gcore.o \ gdb_bfd.o \ + gdb_chdir.o \ gdb-dlfcn.o \ gdb_obstack.o \ gdb_regex.o \ diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 85d6d21113..653dd56a64 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -54,6 +54,8 @@ #include "tui/tui.h" /* For tui_active et.al. */ #endif +#include "gdb_chdir.h" + #include #include #include @@ -408,12 +410,7 @@ cd_command (char *dir, int from_tty) repeat might be useful but is more likely to be a mistake. */ dont_repeat (); - gdb::unique_xmalloc_ptr dir_holder - (tilde_expand (dir != NULL ? dir : "~")); - dir = dir_holder.get (); - - if (chdir (dir) < 0) - perror_with_name (dir); + gdb_chdir (dir != NULL ? dir : "~"); #ifdef HAVE_DOS_BASED_FILE_SYSTEM /* There's too much mess with DOSish names like "d:", "d:.", @@ -436,20 +433,21 @@ cd_command (char *dir, int from_tty) len--; } - dir_holder.reset (savestring (dir, len)); - if (IS_ABSOLUTE_PATH (dir_holder.get ())) + std::string newdir = std::string (dir, len); + const char *newdir_str = newdir.c_str (); + if (IS_ABSOLUTE_PATH (newdir_str)) { xfree (current_directory); - current_directory = dir_holder.release (); + current_directory = xstrdup (newdir_str); } else { if (IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])) - current_directory = concat (current_directory, dir_holder.get (), + current_directory = concat (current_directory, newdir_str, (char *) NULL); else current_directory = concat (current_directory, SLASH_STRING, - dir_holder.get (), (char *) NULL); + newdir_str, (char *) NULL); } /* Now simplify any occurrences of `.' and `..' in the pathname. */ diff --git a/gdb/common/gdb_chdir.c b/gdb/common/gdb_chdir.c new file mode 100644 index 0000000000..6eebeb2d02 --- /dev/null +++ b/gdb/common/gdb_chdir.c @@ -0,0 +1,96 @@ +/* chdir(2) wrapper for GDB and gdbserver. + + Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "common-defs.h" +#include "gdb_chdir.h" +#include + +/* RAII-style class wrapping "glob". */ + +class gdb_glob +{ +public: + /* Construct a "gdb_glob" object by calling "glob" with the provided + parameters. This function can throw if "glob" fails. */ + gdb_glob (const char *pattern, int flags, + int (*errfunc) (const char *epath, int eerrno)) + { + int ret = glob (pattern, flags, errfunc, &m_glob); + + if (ret != 0) + { + if (ret == GLOB_NOMATCH) + error (_("Could not find a match for '%s'."), pattern); + else + error (_("glob could not process pattern '%s'."), + pattern); + } + } + + /* Destroy the object and free M_GLOB. */ + ~gdb_glob () + { + globfree (&m_glob); + } + + /* Return the GL_PATHC component of M_GLOB. */ + int + pathc () const + { + return m_glob.gl_pathc; + } + + /* Return the GL_PATHV component of M_GLOB. */ + char ** + pathv () const + { + return m_glob.gl_pathv; + } + +private: + /* The actual glob object we're dealing with. */ + glob_t m_glob; +}; + +/* Perform path expansion (i.e., tilde expansion) on DIR, and return + the full path. */ + +static std::string +gdb_tilde_expand (const char *dir) +{ + gdb_glob glob (dir, GLOB_TILDE | GLOB_TILDE_CHECK | GLOB_ONLYDIR, NULL); + + gdb_assert (glob.pathc () > 0); + /* "glob" may return more than one match to the path provided by the + user, but we are only interested in the first match. */ + std::string expanded_dir = glob.pathv ()[0]; + + return expanded_dir; +} + +/* See gdb_chdir.h. */ + +void +gdb_chdir (const char *dir) +{ + std::string expanded_dir = gdb_tilde_expand (dir); + + if (chdir (expanded_dir.c_str ()) < 0) + perror_with_name (expanded_dir.c_str ()); +} diff --git a/gdb/common/gdb_chdir.h b/gdb/common/gdb_chdir.h new file mode 100644 index 0000000000..5e6253e3b5 --- /dev/null +++ b/gdb/common/gdb_chdir.h @@ -0,0 +1,26 @@ +/* chdir(2) wrapper for GDB and gdbserver. + + Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef HAVE_GDB_CHDIR_H +#define HAVE_GDB_CHDIR_H + +/* Perform a "chdir" to DIR, doing the proper tilde expansion before. */ +extern void gdb_chdir (const char *dir); + +#endif /* ! HAVE_GDB_CHDIR_H */ diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 1bbe515629..ecd12a7dcc 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -205,6 +205,7 @@ SFILES = \ $(srcdir)/common/fileio.c \ $(srcdir)/common/filestuff.c \ $(srcdir)/common/job-control.c \ + $(srcdir)/common/gdb_chdir.c \ $(srcdir)/common/gdb_vecs.c \ $(srcdir)/common/new-op.c \ $(srcdir)/common/print-utils.c \ @@ -247,6 +248,7 @@ OBS = \ fileio.o \ filestuff.o \ format.o \ + gdb_chdir.o \ gdb_vecs.o \ hostio.o \ inferiors.o \ -- 2.13.3