Home | History | Annotate | Line # | Download | only in gdbsupport
      1 /* Path manipulation routines for GDB and gdbserver.
      2 
      3    Copyright (C) 1986-2024 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #ifndef GDBSUPPORT_PATHSTUFF_H
     21 #define GDBSUPPORT_PATHSTUFF_H
     22 
     23 #include "gdbsupport/byte-vector.h"
     24 #include "gdbsupport/array-view.h"
     25 
     26 #include <sys/types.h>
     27 #include <sys/stat.h>
     28 #include <unistd.h>
     29 #include <array>
     30 
     31 /* Path utilities.  */
     32 
     33 /* String containing the current directory (what getwd would return).  */
     34 extern char *current_directory;
     35 
     36 /* Return the real path of FILENAME, expanding all the symbolic links.
     37 
     38    Contrary to "gdb_abspath", this function does not use
     39    CURRENT_DIRECTORY for path expansion.  Instead, it relies on the
     40    current working directory (CWD) of GDB or gdbserver.  */
     41 
     42 extern gdb::unique_xmalloc_ptr<char> gdb_realpath (const char *filename);
     43 
     44 /* Return a copy of FILENAME, with its directory prefix canonicalized
     45    by gdb_realpath.  */
     46 
     47 extern std::string gdb_realpath_keepfile (const char *filename);
     48 
     49 /* Return PATH in absolute form, performing tilde-expansion if necessary.
     50    PATH cannot be NULL or the empty string.
     51    This does not resolve symlinks however, use gdb_realpath for that.
     52 
     53    Contrary to "gdb_realpath", this function uses CWD for the path
     54    expansion.  This may lead to scenarios the current working
     55    directory is different than CWD.
     56 
     57    If CWD is NULL, this function returns a copy of PATH.  */
     58 
     59 extern std::string gdb_abspath (const char *path,
     60 				const char *cwd = current_directory);
     61 
     62 /* Overload of gdb_abspath which takes std::string.  */
     63 
     64 static inline std::string
     65 gdb_abspath (const std::string &path)
     66 {
     67   return gdb_abspath (path.c_str ());
     68 }
     69 
     70 /* Overload of gdb_abspath which takes gdb::unique_xmalloc_ptr<char>.  */
     71 
     72 static inline std::string
     73 gdb_abspath (const gdb::unique_xmalloc_ptr<char> &path)
     74 {
     75   return gdb_abspath (path.get ());
     76 }
     77 
     78 /* If the path in CHILD is a child of the path in PARENT, return a
     79    pointer to the first component in the CHILD's pathname below the
     80    PARENT.  Otherwise, return NULL.  */
     81 
     82 extern const char *child_path (const char *parent, const char *child);
     83 
     84 /* Join elements in PATHS into a single path.
     85 
     86    The first element can be absolute or relative.  Only a single directory
     87    separator will be placed between elements of PATHS, if one element ends
     88    with a directory separator, or an element starts with a directory
     89    separator, then these will be collapsed into a single separator.  */
     90 
     91 extern std::string path_join (gdb::array_view<const char *> paths);
     92 
     93 /* Same as the above, but accept paths as distinct parameters.  */
     94 
     95 template<typename ...Args>
     96 std::string
     97 path_join (Args... paths)
     98 {
     99   /* It doesn't make sense to join less than two paths.  */
    100   static_assert (sizeof... (Args) >= 2);
    101 
    102   std::array<const char *, sizeof... (Args)> path_array
    103     { paths... };
    104 
    105   return path_join (gdb::array_view<const char *> (path_array));
    106 }
    107 
    108 /* Return whether PATH contains a directory separator character.  */
    109 
    110 extern bool contains_dir_separator (const char *path);
    111 
    112 /* Get the usual user cache directory for the current platform.
    113 
    114    On Linux, it follows the XDG Base Directory specification: use
    115    $XDG_CACHE_HOME/gdb if the XDG_CACHE_HOME environment variable is
    116    defined, otherwise $HOME/.cache.
    117 
    118    On macOS, it follows the local convention and uses
    119    ~/Library/Caches/gdb.
    120 
    121   The return value is absolute and tilde-expanded.  Return an empty
    122   string if neither XDG_CACHE_HOME (on Linux) or HOME are defined.  */
    123 
    124 extern std::string get_standard_cache_dir ();
    125 
    126 /* Get the usual temporary directory for the current platform.
    127 
    128    On Windows, this is the TMP or TEMP environment variable.
    129 
    130    On the rest, this is the TMPDIR environment variable, if defined, else /tmp.
    131 
    132    Throw an exception on error.  */
    133 
    134 extern std::string get_standard_temp_dir ();
    135 
    136 /* Get the usual user config directory for the current platform.
    137 
    138    On Linux, it follows the XDG Base Directory specification: use
    139    $XDG_CONFIG_HOME/gdb if the XDG_CONFIG_HOME environment variable is
    140    defined, otherwise $HOME/.config.
    141 
    142    On macOS, it follows the local convention and uses
    143    ~/Library/Preferences/gdb.
    144 
    145   The return value is absolute and tilde-expanded.  Return an empty
    146   string if neither XDG_CONFIG_HOME (on Linux) or HOME are defined.  */
    147 
    148 extern std::string get_standard_config_dir ();
    149 
    150 /* Look for FILENAME in the standard configuration directory as returned by
    151    GET_STANDARD_CONFIG_DIR and return the path to the file.  No check is
    152    performed that the file actually exists or not.
    153 
    154    If FILENAME begins with a '.' then the path returned will remove the
    155    leading '.' character, for example passing '.gdbinit' could return the
    156    path '/home/username/.config/gdb/gdbinit'.  */
    157 
    158 extern std::string get_standard_config_filename (const char *filename);
    159 
    160 /* Look for a file called NAME in either the standard config directory or
    161    in the users home directory.  If a suitable file is found then *BUF will
    162    be filled with the contents of a call to 'stat' on the found file,
    163    otherwise *BUF is undefined after this call.
    164 
    165    If NAME starts with a '.' character then, when looking in the standard
    166    config directory the file searched for has the '.' removed.  For
    167    example, if NAME is '.gdbinit' then on a Linux target GDB might look for
    168    '~/.config/gdb/gdbinit' and then '~/.gdbinit'.  */
    169 
    170 extern std::string find_gdb_home_config_file (const char *name,
    171 					      struct stat *buf);
    172 
    173 /* Return the file name of the user's shell.  Normally this comes from
    174    the SHELL environment variable.  */
    175 
    176 extern const char *get_shell ();
    177 
    178 /* Make a filename suitable to pass to mkstemp based on F (e.g.
    179    /tmp/foo -> /tmp/foo-XXXXXX).  */
    180 
    181 extern gdb::char_vector make_temp_filename (const std::string &f);
    182 
    183 #endif /* GDBSUPPORT_PATHSTUFF_H */
    184