+/* Set the data-directory parameter to NEW_DATADIR.
+ If NEW_DATADIR is not a directory then a warning is printed.
+ We don't signal an error for backward compatibility. */
+
+void
+set_gdb_data_directory (const char *new_datadir)
+{
+ struct stat st;
+
+ if (stat (new_datadir, &st) < 0)
+ {
+ int save_errno = errno;
+
+ fprintf_unfiltered (gdb_stderr, "Warning: ");
+ print_sys_errmsg (new_datadir, save_errno);
+ }
+ else if (!S_ISDIR (st.st_mode))
+ warning (_("%s is not a directory."), new_datadir);
+
+ xfree (gdb_datadir);
+ gdb_datadir = gdb_realpath (new_datadir);
+
+ /* gdb_realpath won't return an absolute path if the path doesn't exist,
+ but we still want to record an absolute path here. If the user entered
+ "../foo" and "../foo" doesn't exist then we'll record $(pwd)/../foo which
+ isn't canonical, but that's ok. */
+ if (!IS_ABSOLUTE_PATH (gdb_datadir))
+ {
+ char *abs_datadir = gdb_abspath (gdb_datadir);
+
+ xfree (gdb_datadir);
+ gdb_datadir = abs_datadir;
+ }
+}
+
+/* Relocate a file or directory. PROGNAME is the name by which gdb
+ was invoked (i.e., argv[0]). INITIAL is the default value for the
+ file or directory. FLAG is true if the value is relocatable, false
+ otherwise. Returns a newly allocated string; this may return NULL
+ under the same conditions as make_relative_prefix. */
+
+static char *
+relocate_path (const char *progname, const char *initial, int flag)
+{
+ if (flag)
+ return make_relative_prefix (progname, BINDIR, initial);
+ return xstrdup (initial);
+}
+
+/* Like relocate_path, but specifically checks for a directory.
+ INITIAL is relocated according to the rules of relocate_path. If
+ the result is a directory, it is used; otherwise, INITIAL is used.
+ The chosen directory is then canonicalized using lrealpath. This
+ function always returns a newly-allocated string. */
+
+char *
+relocate_gdb_directory (const char *initial, int flag)
+{
+ char *dir;
+
+ dir = relocate_path (gdb_program_name, initial, flag);
+ if (dir)
+ {
+ struct stat s;
+
+ if (*dir == '\0' || stat (dir, &s) != 0 || !S_ISDIR (s.st_mode))
+ {
+ xfree (dir);
+ dir = NULL;
+ }
+ }
+ if (!dir)
+ dir = xstrdup (initial);
+
+ /* Canonicalize the directory. */
+ if (*dir)
+ {
+ char *canon_sysroot = lrealpath (dir);
+
+ if (canon_sysroot)
+ {
+ xfree (dir);
+ dir = canon_sysroot;
+ }
+ }
+
+ return dir;
+}
+
+/* Compute the locations of init files that GDB should source and
+ return them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If
+ there is no system gdbinit (resp. home gdbinit and local gdbinit)
+ to be loaded, then SYSTEM_GDBINIT (resp. HOME_GDBINIT and
+ LOCAL_GDBINIT) is set to NULL. */
+static void
+get_init_files (const char **system_gdbinit,
+ const char **home_gdbinit,
+ const char **local_gdbinit)
+{
+ static const char *sysgdbinit = NULL;
+ static char *homeinit = NULL;
+ static const char *localinit = NULL;
+ static int initialized = 0;
+
+ if (!initialized)
+ {
+ struct stat homebuf, cwdbuf, s;
+ char *homedir;