This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v12 18/32] Refactor openp() to return file_location
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Fri, 21 Aug 2015 23:22:37 +0200
- Subject: [PATCH v12 18/32] Refactor openp() to return file_location
- Authentication-results: sourceware.org; auth=none
- References: <20150821212006 dot 6673 dot 35100 dot stgit at host1 dot jankratochvil dot net>
Hi,
openp() remains as a backward compatibility wrapper around renamed
openp->openp_file().
Jan
gdb/ChangeLog
2015-08-19 Jan Kratochvil <jan.kratochvil@redhat.com>
* defs.h (enum openp_flags): Remove OPF_OPEN_RW_TMP, add
OPF_BFD_CANONICAL.
(openp_bfd, openp_file): Add prototypes.
* exec.c (exec_file_attach): Replace openp by openp_bfd calls.
* source.c (file_location_from_filename): Support OPF_BFD_CANONICAL.
(openp, openp_bfd): New functions.
(openp): Rename to ...
(openp_file): ... here, return file_location, remove filename_opened
parameter.
---
0 files changed
diff --git a/gdb/defs.h b/gdb/defs.h
index 8ee8b33..ac735c2 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -341,12 +341,20 @@ enum openp_flags
/* Ask for bfd * to be returned in file_location. */
OPF_IS_BFD = (1 << 2),
- /* Open the file in read/write mode if WRITE_FILES says so. */
- OPF_OPEN_RW_TMP = (1 << 3),
+ /* bfd_get_filename can be incorrect then, use only if you keep your
+ original filename separate from resulting bfd.
+ Returned file_location.filename is not canonicalized. */
+ OPF_BFD_CANONICAL = (1 << 3),
};
extern int openp (const char *, enum openp_flags, const char *, char **);
+extern bfd *openp_bfd (const char *path, enum openp_flags opts,
+ const char *string);
+
+extern struct file_location openp_file (const char *path, enum openp_flags opts,
+ const char *string);
+
extern int source_full_path_of (const char *, char **);
extern void mod_path (char *, char **);
diff --git a/gdb/exec.c b/gdb/exec.c
index e87d154..6dd2aa6 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -216,81 +216,32 @@ exec_file_attach (const char *filename, int from_tty)
}
else
{
- int load_via_target = 0;
- char *scratch_pathname, *canonical_pathname;
- int scratch_chan;
struct target_section *sections = NULL, *sections_end = NULL;
char **matching;
- if (is_target_filename (filename))
- {
- if (target_filesystem_is_local ())
- filename += strlen (TARGET_SYSROOT_PREFIX);
- else
- load_via_target = 1;
- }
-
- if (load_via_target)
+ exec_bfd = openp_bfd (getenv ("PATH"),
+ OPF_TRY_CWD_FIRST | OPF_BFD_CANONICAL, filename);
+#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
+ if (exec_bfd == NULL)
{
- /* gdb_bfd_fopen does not support "target:" filenames. */
- if (write_files)
- warning (_("writing into executable files is "
- "not supported for %s sysroots"),
- TARGET_SYSROOT_PREFIX);
+ char *exename = alloca (strlen (filename) + 5);
- scratch_pathname = xstrdup (filename);
- make_cleanup (xfree, scratch_pathname);
-
- scratch_chan = -1;
-
- canonical_pathname = scratch_pathname;
+ strcat (strcpy (exename, filename), ".exe");
+ exec_bfd = openp_bfd (getenv ("PATH"),
+ OPF_TRY_CWD_FIRST | OPF_BFD_CANONICAL, exename);
}
- else
- {
- scratch_chan = openp (getenv ("PATH"),
- OPF_TRY_CWD_FIRST | OPF_OPEN_RW_TMP,
- filename, &scratch_pathname);
-#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
- if (scratch_chan < 0)
- {
- char *exename = alloca (strlen (filename) + 5);
-
- strcat (strcpy (exename, filename), ".exe");
- scratch_chan = openp (getenv ("PATH"),
- OPF_TRY_CWD_FIRST | OPF_OPEN_RW_TMP,
- exename, &scratch_pathname);
- }
#endif
- if (scratch_chan < 0)
- perror_with_name (filename);
-
- make_cleanup (xfree, scratch_pathname);
-
- /* gdb_bfd_open (and its variants) prefers canonicalized
- pathname for better BFD caching. */
- canonical_pathname = gdb_realpath (scratch_pathname);
- make_cleanup (xfree, canonical_pathname);
- }
-
- if (write_files && !load_via_target)
- exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget,
- FOPEN_RUB, scratch_chan);
- else
- exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);
-
- if (!exec_bfd)
- {
- error (_("\"%s\": could not open as an executable file: %s."),
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
- }
+ if (exec_bfd == NULL)
+ error (_("\"%s\": could not open as an executable file: %s."),
+ filename, bfd_errmsg (bfd_get_error ()));
/* gdb_realpath_keepfile resolves symlinks on the local
filesystem and so cannot be used for "target:" files. */
gdb_assert (exec_filename == NULL);
- if (load_via_target)
+ if (is_target_filename (filename))
exec_filename = xstrdup (bfd_get_filename (exec_bfd));
else
- exec_filename = gdb_realpath_keepfile (scratch_pathname);
+ exec_filename = gdb_realpath_keepfile (filename);
if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
{
@@ -298,7 +249,7 @@ exec_file_attach (const char *filename, int from_tty)
it. */
exec_close ();
error (_("\"%s\": not in executable format: %s"),
- scratch_pathname,
+ filename,
gdb_bfd_errmsg (bfd_get_error (), matching));
}
@@ -308,7 +259,7 @@ exec_file_attach (const char *filename, int from_tty)
it. */
exec_close ();
error (_("\"%s\": can't find the file sections: %s"),
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ filename, bfd_errmsg (bfd_get_error ()));
}
exec_bfd_mtime = bfd_get_mtime (exec_bfd);
diff --git a/gdb/source.c b/gdb/source.c
index d06cc84..029c3b5 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -868,8 +868,21 @@ file_location_from_filename (const char *filename, enum openp_flags opts)
{
if (write_files)
file.abfd = gdb_bfd_fopen (filename, gnutarget, FOPEN_RUB, file.fd);
- else
+ else if ((opts & OPF_BFD_CANONICAL) == 0)
file.abfd = gdb_bfd_open (filename, gnutarget, file.fd);
+ else
+ {
+ char *canonical;
+
+ /* gdb_bfd_open (and its variants) prefers canonicalized
+ pathname for better BFD caching. */
+ struct cleanup *canonical_cleanup;
+
+ canonical = gdb_realpath (filename);
+ canonical_cleanup = make_cleanup (xfree, canonical);
+ file.abfd = gdb_bfd_open (canonical, gnutarget, file.fd);
+ do_cleanups (canonical_cleanup);
+ }
if ((opts & OPF_IS_BFD) != 0)
file.fd = -1;
else
@@ -944,35 +957,79 @@ filename_to_bfd (const char *filename)
OPF_IS_BFD));
}
-/* Open a file named STRING, searching path PATH (dir names sep by some char).
- You cannot use this function to create files.
-
- OPTS specifies the function behaviour in specific cases.
+/* Wrapper of openp_file returning filename string.
- FILENAME_OPENED must be non-null. Set it to a newly allocated string naming
- the actual file opened (this string will always start with a "/"). We
- have to take special pains to avoid doubling the "/" between the directory
- and the file, sigh! Emacs gets confuzzed by this when we print the
- source file name!!!
+ FILENAME_OPENED must be non-null. It is set to
+ file_location.filename returned from openp_file.
If a file is found, return the descriptor.
Otherwise, return -1, with errno set for the last name we tried to open. */
-/* >>>> This should only allow files of certain types,
- >>>> eg executable, non-directory. */
int
openp (const char *path, enum openp_flags opts, const char *string,
char **filename_opened)
{
+ struct file_location file;
+ int retval;
+
+ gdb_assert ((opts & OPF_IS_BFD) == 0);
+
+ file = openp_file (path, opts, string);
+ gdb_assert (file.abfd == NULL);
+ if (file.fd == -1)
+ {
+ int save_errno = file.file_errno;
+
+ gdb_assert (file.filename == NULL);
+ file_location_free (&file);
+ *filename_opened = NULL;
+ errno = save_errno;
+ return -1;
+ }
+ gdb_assert (file.filename != NULL);
+ *filename_opened = xstrdup (file.filename);
+ retval = file.fd;
+ file.fd = -1;
+ file_location_free (&file);
+ return retval;
+}
+
+/* Wrapper of openp_file returning bfd *. See file_location_to_bfd how
+ the function behaves in the case of failure. */
+
+bfd *
+openp_bfd (const char *path, enum openp_flags opts, const char *string)
+{
+ gdb_assert ((opts & OPF_IS_BFD) == 0);
+
+ return file_location_to_bfd (openp_file (path, opts | OPF_IS_BFD, string));
+}
+
+/* Open a file named STRING, searching path PATH (dir names sep by some char).
+ You cannot use this function to create files.
+
+ OPTS specifies the function behaviour in specific cases.
+
+ Call file_location_is_valid on returned file_location to check
+ whether this function has succeeded. */
+
+/* >>>> This should only allow files of certain types,
+ >>>> eg executable, non-directory. */
+
+struct file_location
+openp_file (const char *path, enum openp_flags opts, const char *string)
+{
int fd;
char *filename;
int alloclen;
VEC (char_ptr) *dir_vec;
struct cleanup *back_to;
- int ix, mode;
+ int ix;
char *dir;
+ struct file_location file;
gdb_assert (string != NULL);
+ gdb_assert ((opts & (OPF_IS_BFD | OPF_BFD_CANONICAL)) != OPF_BFD_CANONICAL);
/* A file with an empty name cannot possibly exist. Report a failure
without further checking.
@@ -983,16 +1040,13 @@ openp (const char *path, enum openp_flags opts, const char *string,
when the debugger is started with an empty argument. */
if (string[0] == '\0')
{
- errno = ENOENT;
- return -1;
+ file_location_enoent (&file);
+ return file;
}
if (!path)
path = ".";
- mode = (O_BINARY | (((opts & OPF_OPEN_RW_TMP) && write_files)
- ? O_RDWR : O_RDONLY));
-
if ((opts & OPF_TRY_CWD_FIRST) || IS_ABSOLUTE_PATH (string))
{
int i;
@@ -1001,20 +1055,19 @@ openp (const char *path, enum openp_flags opts, const char *string,
{
filename = alloca (strlen (string) + 1);
strcpy (filename, string);
- fd = gdb_open_cloexec (filename, mode, 0);
- if (fd >= 0)
- goto done;
- }
- else
- {
- filename = NULL;
- fd = -1;
+ file = file_location_from_filename (filename, opts);
+ if (file_location_is_valid (&file))
+ return file;
+ file_location_free (&file);
}
if (!(opts & OPF_SEARCH_IN_PATH))
for (i = 0; string[i]; i++)
if (IS_DIR_SEPARATOR (string[i]))
- goto done;
+ {
+ file_location_enoent (&file);
+ return file;
+ }
}
/* For dos paths, d:/foo -> /foo, and d:foo -> foo. */
@@ -1033,7 +1086,7 @@ openp (const char *path, enum openp_flags opts, const char *string,
filename = alloca (alloclen);
fd = -1;
- dir_vec = dirnames_to_char_ptr_vec (path);
+ dir_vec = dirnames_to_char_ptr_vec_target_exc (path);
back_to = make_cleanup_free_char_ptr_vec (dir_vec);
for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, dir); ++ix)
@@ -1097,23 +1150,22 @@ openp (const char *path, enum openp_flags opts, const char *string,
strcat (filename + len, SLASH_STRING);
strcat (filename, string);
- if (is_regular_file (filename))
+ if (is_target_filename (filename) || is_regular_file (filename))
{
- fd = gdb_open_cloexec (filename, mode, 0);
- if (fd >= 0)
- break;
+ file = file_location_from_filename (filename, opts);
+ if (file_location_is_valid (&file))
+ {
+ do_cleanups (back_to);
+ return file;
+ }
+ file_location_free (&file);
}
}
do_cleanups (back_to);
-done:
- if (fd < 0)
- *filename_opened = NULL;
- else
- *filename_opened = xstrdup (filename);
-
- return fd;
+ file_location_enoent (&file);
+ return file;
}