From patchwork Fri Jun 7 06:20:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Orgad Shaneh X-Patchwork-Id: 33044 Received: (qmail 110487 invoked by alias); 7 Jun 2019 06:21:09 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 110479 invoked by uid 89); 7 Jun 2019 06:21:09 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=xstrdup, sk:gdb_til, 1986-2019, 19862019 X-HELO: mail-wm1-f65.google.com Received: from mail-wm1-f65.google.com (HELO mail-wm1-f65.google.com) (209.85.128.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 07 Jun 2019 06:21:05 +0000 Received: by mail-wm1-f65.google.com with SMTP id t5so691261wmh.3 for ; Thu, 06 Jun 2019 23:21:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=H/DaoveGk15MUZMTUsPGUQsFerqxC+p4xdk3ArR3KzI=; b=E05AJFdx6ufeNq3L6HHZXtFhILSffZPvQ0D8X5ihzaRpuk2EEEQ7fFFasy1Q2ocBHE C6aQqnYtXHGyNb3A9aYw6I06jGI3rLSJfdqf0jBjFYuMHukwCfNbHVaektw6+yKb3fXS iakgWxJLDm1qiQufg6BSiGKfdxk+TRogwrs6gYPras0CTMOC7CFWfDgZFYEb4M8/34iq wT8OpWDNNhC2mvAks9GQaXb5GGJaLM2oeIFUB/1fb+pO46YnqzFbQKFKj558LYiRynOx +qjaCNuGLduGN23jfEqyEFcZHGp4nXGByAEcG92/NQeJ2YZVWYoDjDfwG9KY4RpCBLzj o9qg== Return-Path: Received: from junior.corp.audiocodes.com ([164.138.127.164]) by smtp.gmail.com with ESMTPSA id o1sm1017969wre.76.2019.06.06.23.21.01 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 06 Jun 2019 23:21:02 -0700 (PDT) From: orgads@gmail.com To: gdb-patches@sourceware.org Cc: Orgad Shaneh Subject: [PATCH] Fix cache dir resolving on Windows Date: Fri, 7 Jun 2019 09:20:49 +0300 Message-Id: <20190607062049.7503-1-orgads@gmail.com> In-Reply-To: <20190603193716.4861-1-orgads@gmail.com> References: <20190603193716.4861-1-orgads@gmail.com> MIME-Version: 1.0 From: Orgad Shaneh ... when not running from MSYS environment, and HOME is not set. --- gdb/common/pathstuff.c | 584 +++++++++++++++++++++-------------------- 1 file changed, 294 insertions(+), 290 deletions(-) diff --git a/gdb/common/pathstuff.c b/gdb/common/pathstuff.c index 2b1669a5b9..33fa5bbb4d 100644 --- a/gdb/common/pathstuff.c +++ b/gdb/common/pathstuff.c @@ -1,290 +1,294 @@ -/* Path manipulation routines for GDB and gdbserver. - - Copyright (C) 1986-2019 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 "pathstuff.h" -#include "host-defs.h" -#include "filenames.h" -#include "gdb_tilde_expand.h" - -#ifdef USE_WIN32API -#include -#endif - -/* See common/pathstuff.h. */ - -gdb::unique_xmalloc_ptr -gdb_realpath (const char *filename) -{ -/* On most hosts, we rely on canonicalize_file_name to compute - the FILENAME's realpath. - - But the situation is slightly more complex on Windows, due to some - versions of GCC which were reported to generate paths where - backlashes (the directory separator) were doubled. For instance: - c:\\some\\double\\slashes\\dir - ... instead of ... - c:\some\double\slashes\dir - Those double-slashes were getting in the way when comparing paths, - for instance when trying to insert a breakpoint as follow: - (gdb) b c:/some/double/slashes/dir/foo.c:4 - No source file named c:/some/double/slashes/dir/foo.c:4. - (gdb) b c:\some\double\slashes\dir\foo.c:4 - No source file named c:\some\double\slashes\dir\foo.c:4. - To prevent this from happening, we need this function to always - strip those extra backslashes. While canonicalize_file_name does - perform this simplification, it only works when the path is valid. - Since the simplification would be useful even if the path is not - valid (one can always set a breakpoint on a file, even if the file - does not exist locally), we rely instead on GetFullPathName to - perform the canonicalization. */ - -#if defined (_WIN32) - { - char buf[MAX_PATH]; - DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL); - - /* The file system is case-insensitive but case-preserving. - So it is important we do not lowercase the path. Otherwise, - we might not be able to display the original casing in a given - path. */ - if (len > 0 && len < MAX_PATH) - return gdb::unique_xmalloc_ptr (xstrdup (buf)); - } -#else - { - char *rp = canonicalize_file_name (filename); - - if (rp != NULL) - return gdb::unique_xmalloc_ptr (rp); - } -#endif - - /* This system is a lost cause, just dup the buffer. */ - return gdb::unique_xmalloc_ptr (xstrdup (filename)); -} - -/* See common/pathstuff.h. */ - -gdb::unique_xmalloc_ptr -gdb_realpath_keepfile (const char *filename) -{ - const char *base_name = lbasename (filename); - char *dir_name; - char *result; - - /* Extract the basename of filename, and return immediately - a copy of filename if it does not contain any directory prefix. */ - if (base_name == filename) - return gdb::unique_xmalloc_ptr (xstrdup (filename)); - - dir_name = (char *) alloca ((size_t) (base_name - filename + 2)); - /* Allocate enough space to store the dir_name + plus one extra - character sometimes needed under Windows (see below), and - then the closing \000 character. */ - strncpy (dir_name, filename, base_name - filename); - dir_name[base_name - filename] = '\000'; - -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* We need to be careful when filename is of the form 'd:foo', which - is equivalent of d:./foo, which is totally different from d:/foo. */ - if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') - { - dir_name[2] = '.'; - dir_name[3] = '\000'; - } -#endif - - /* Canonicalize the directory prefix, and build the resulting - filename. If the dirname realpath already contains an ending - directory separator, avoid doubling it. */ - gdb::unique_xmalloc_ptr path_storage = gdb_realpath (dir_name); - const char *real_path = path_storage.get (); - if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) - result = concat (real_path, base_name, (char *) NULL); - else - result = concat (real_path, SLASH_STRING, base_name, (char *) NULL); - - return gdb::unique_xmalloc_ptr (result); -} - -/* See common/pathstuff.h. */ - -gdb::unique_xmalloc_ptr -gdb_abspath (const char *path) -{ - gdb_assert (path != NULL && path[0] != '\0'); - - if (path[0] == '~') - return gdb_tilde_expand_up (path); - - if (IS_ABSOLUTE_PATH (path)) - return gdb::unique_xmalloc_ptr (xstrdup (path)); - - /* Beware the // my son, the Emacs barfs, the botch that catch... */ - return gdb::unique_xmalloc_ptr - (concat (current_directory, - IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) - ? "" : SLASH_STRING, - path, (char *) NULL)); -} - -/* See common/pathstuff.h. */ - -const char * -child_path (const char *parent, const char *child) -{ - /* The child path must start with the parent path. */ - size_t parent_len = strlen (parent); - if (filename_ncmp (parent, child, parent_len) != 0) - return NULL; - - /* The parent path must be a directory and the child must contain at - least one component underneath the parent. */ - const char *child_component; - if (IS_DIR_SEPARATOR (parent[parent_len - 1])) - { - /* The parent path ends in a directory separator, so it is a - directory. The first child component starts after the common - prefix. */ - child_component = child + parent_len; - } - else - { - /* The parent path does not end in a directory separator. The - first character in the child after the common prefix must be - a directory separator. - - Note that CHILD must hold at least parent_len characters for - filename_ncmp to return zero. If the character at parent_len - is nul due to CHILD containing the same path as PARENT, the - IS_DIR_SEPARATOR check will fail here. */ - if (!IS_DIR_SEPARATOR (child[parent_len])) - return NULL; - - /* The first child component starts after the separator after the - common prefix. */ - child_component = child + parent_len + 1; - } - - /* The child must contain at least one non-separator character after - the parent. */ - while (*child_component != '\0') - { - if (!IS_DIR_SEPARATOR (*child_component)) - return child_component; - - child_component++; - } - return NULL; -} - -/* See common/pathstuff.h. */ - -bool -contains_dir_separator (const char *path) -{ - for (; *path != '\0'; path++) - { - if (IS_DIR_SEPARATOR (*path)) - return true; - } - - return false; -} - -/* See common/pathstuff.h. */ - -std::string -get_standard_cache_dir () -{ -#ifdef __APPLE__ -#define HOME_CACHE_DIR "Library/Caches" -#else -#define HOME_CACHE_DIR ".cache" -#endif - -#ifndef __APPLE__ - const char *xdg_cache_home = getenv ("XDG_CACHE_HOME"); - if (xdg_cache_home != NULL) - { - /* Make sure the path is absolute and tilde-expanded. */ - gdb::unique_xmalloc_ptr abs (gdb_abspath (xdg_cache_home)); - return string_printf ("%s/gdb", abs.get ()); - } -#endif - - const char *home = getenv ("HOME"); - if (home != NULL) - { - /* Make sure the path is absolute and tilde-expanded. */ - gdb::unique_xmalloc_ptr abs (gdb_abspath (home)); - return string_printf ("%s/" HOME_CACHE_DIR "/gdb", abs.get ()); - } - - return {}; -} - -/* See common/pathstuff.h. */ - -std::string -get_standard_temp_dir () -{ -#ifdef WIN32 - const char *tmp = getenv ("TMP"); - if (tmp != nullptr) - return tmp; - - tmp = getenv ("TEMP"); - if (tmp != nullptr) - return tmp; - - error (_("Couldn't find temp dir path, both TMP and TEMP are unset.")); - -#else - const char *tmp = getenv ("TMPDIR"); - if (tmp != nullptr) - return tmp; - - return "/tmp"; -#endif -} - -/* See common/pathstuff.h. */ - -const char * -get_shell () -{ - const char *ret = getenv ("SHELL"); - if (ret == NULL) - ret = "/bin/sh"; - - return ret; -} - -/* See common/pathstuff.h. */ - -gdb::char_vector -make_temp_filename (const std::string &f) -{ - gdb::char_vector filename_temp (f.length () + 8); - strcpy (filename_temp.data (), f.c_str ()); - strcat (filename_temp.data () + f.size (), "-XXXXXX"); - return filename_temp; -} +/* Path manipulation routines for GDB and gdbserver. + + Copyright (C) 1986-2019 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 "pathstuff.h" +#include "host-defs.h" +#include "filenames.h" +#include "gdb_tilde_expand.h" + +#ifdef USE_WIN32API +#include +#endif + +/* See common/pathstuff.h. */ + +gdb::unique_xmalloc_ptr +gdb_realpath (const char *filename) +{ +/* On most hosts, we rely on canonicalize_file_name to compute + the FILENAME's realpath. + + But the situation is slightly more complex on Windows, due to some + versions of GCC which were reported to generate paths where + backlashes (the directory separator) were doubled. For instance: + c:\\some\\double\\slashes\\dir + ... instead of ... + c:\some\double\slashes\dir + Those double-slashes were getting in the way when comparing paths, + for instance when trying to insert a breakpoint as follow: + (gdb) b c:/some/double/slashes/dir/foo.c:4 + No source file named c:/some/double/slashes/dir/foo.c:4. + (gdb) b c:\some\double\slashes\dir\foo.c:4 + No source file named c:\some\double\slashes\dir\foo.c:4. + To prevent this from happening, we need this function to always + strip those extra backslashes. While canonicalize_file_name does + perform this simplification, it only works when the path is valid. + Since the simplification would be useful even if the path is not + valid (one can always set a breakpoint on a file, even if the file + does not exist locally), we rely instead on GetFullPathName to + perform the canonicalization. */ + +#if defined (_WIN32) + { + char buf[MAX_PATH]; + DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL); + + /* The file system is case-insensitive but case-preserving. + So it is important we do not lowercase the path. Otherwise, + we might not be able to display the original casing in a given + path. */ + if (len > 0 && len < MAX_PATH) + return gdb::unique_xmalloc_ptr (xstrdup (buf)); + } +#else + { + char *rp = canonicalize_file_name (filename); + + if (rp != NULL) + return gdb::unique_xmalloc_ptr (rp); + } +#endif + + /* This system is a lost cause, just dup the buffer. */ + return gdb::unique_xmalloc_ptr (xstrdup (filename)); +} + +/* See common/pathstuff.h. */ + +gdb::unique_xmalloc_ptr +gdb_realpath_keepfile (const char *filename) +{ + const char *base_name = lbasename (filename); + char *dir_name; + char *result; + + /* Extract the basename of filename, and return immediately + a copy of filename if it does not contain any directory prefix. */ + if (base_name == filename) + return gdb::unique_xmalloc_ptr (xstrdup (filename)); + + dir_name = (char *) alloca ((size_t) (base_name - filename + 2)); + /* Allocate enough space to store the dir_name + plus one extra + character sometimes needed under Windows (see below), and + then the closing \000 character. */ + strncpy (dir_name, filename, base_name - filename); + dir_name[base_name - filename] = '\000'; + +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* We need to be careful when filename is of the form 'd:foo', which + is equivalent of d:./foo, which is totally different from d:/foo. */ + if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') + { + dir_name[2] = '.'; + dir_name[3] = '\000'; + } +#endif + + /* Canonicalize the directory prefix, and build the resulting + filename. If the dirname realpath already contains an ending + directory separator, avoid doubling it. */ + gdb::unique_xmalloc_ptr path_storage = gdb_realpath (dir_name); + const char *real_path = path_storage.get (); + if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) + result = concat (real_path, base_name, (char *) NULL); + else + result = concat (real_path, SLASH_STRING, base_name, (char *) NULL); + + return gdb::unique_xmalloc_ptr (result); +} + +/* See common/pathstuff.h. */ + +gdb::unique_xmalloc_ptr +gdb_abspath (const char *path) +{ + gdb_assert (path != NULL && path[0] != '\0'); + + if (path[0] == '~') + return gdb_tilde_expand_up (path); + + if (IS_ABSOLUTE_PATH (path)) + return gdb::unique_xmalloc_ptr (xstrdup (path)); + + /* Beware the // my son, the Emacs barfs, the botch that catch... */ + return gdb::unique_xmalloc_ptr + (concat (current_directory, + IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) + ? "" : SLASH_STRING, + path, (char *) NULL)); +} + +/* See common/pathstuff.h. */ + +const char * +child_path (const char *parent, const char *child) +{ + /* The child path must start with the parent path. */ + size_t parent_len = strlen (parent); + if (filename_ncmp (parent, child, parent_len) != 0) + return NULL; + + /* The parent path must be a directory and the child must contain at + least one component underneath the parent. */ + const char *child_component; + if (IS_DIR_SEPARATOR (parent[parent_len - 1])) + { + /* The parent path ends in a directory separator, so it is a + directory. The first child component starts after the common + prefix. */ + child_component = child + parent_len; + } + else + { + /* The parent path does not end in a directory separator. The + first character in the child after the common prefix must be + a directory separator. + + Note that CHILD must hold at least parent_len characters for + filename_ncmp to return zero. If the character at parent_len + is nul due to CHILD containing the same path as PARENT, the + IS_DIR_SEPARATOR check will fail here. */ + if (!IS_DIR_SEPARATOR (child[parent_len])) + return NULL; + + /* The first child component starts after the separator after the + common prefix. */ + child_component = child + parent_len + 1; + } + + /* The child must contain at least one non-separator character after + the parent. */ + while (*child_component != '\0') + { + if (!IS_DIR_SEPARATOR (*child_component)) + return child_component; + + child_component++; + } + return NULL; +} + +/* See common/pathstuff.h. */ + +bool +contains_dir_separator (const char *path) +{ + for (; *path != '\0'; path++) + { + if (IS_DIR_SEPARATOR (*path)) + return true; + } + + return false; +} + +/* See common/pathstuff.h. */ + +std::string +get_standard_cache_dir () +{ +#ifdef __APPLE__ +#define HOME_CACHE_DIR "Library/Caches" +#else +#define HOME_CACHE_DIR ".cache" +#endif + +#ifndef __APPLE__ + const char *xdg_cache_home = getenv ("XDG_CACHE_HOME"); + if (xdg_cache_home != NULL) + { + /* Make sure the path is absolute and tilde-expanded. */ + gdb::unique_xmalloc_ptr abs (gdb_abspath (xdg_cache_home)); + return string_printf ("%s/gdb", abs.get ()); + } +#endif + + const char *home = getenv ("HOME"); +#ifdef _WIN32 + if (home == nullptr) + home = getenv ("APPDATA"); +#endif + if (home != NULL) + { + /* Make sure the path is absolute and tilde-expanded. */ + gdb::unique_xmalloc_ptr abs (gdb_abspath (home)); + return string_printf ("%s/" HOME_CACHE_DIR "/gdb", abs.get ()); + } + + return {}; +} + +/* See common/pathstuff.h. */ + +std::string +get_standard_temp_dir () +{ +#ifdef WIN32 + const char *tmp = getenv ("TMP"); + if (tmp != nullptr) + return tmp; + + tmp = getenv ("TEMP"); + if (tmp != nullptr) + return tmp; + + error (_("Couldn't find temp dir path, both TMP and TEMP are unset.")); + +#else + const char *tmp = getenv ("TMPDIR"); + if (tmp != nullptr) + return tmp; + + return "/tmp"; +#endif +} + +/* See common/pathstuff.h. */ + +const char * +get_shell () +{ + const char *ret = getenv ("SHELL"); + if (ret == NULL) + ret = "/bin/sh"; + + return ret; +} + +/* See common/pathstuff.h. */ + +gdb::char_vector +make_temp_filename (const std::string &f) +{ + gdb::char_vector filename_temp (f.length () + 8); + strcpy (filename_temp.data (), f.c_str ()); + strcat (filename_temp.data () + f.size (), "-XXXXXX"); + return filename_temp; +}