This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 1/3] bfd_fopen: read from stdin if filename == NULL
- From: Ahmad Fatoum <ahmad at a3f dot at>
- To: binutils at sourceware dot org
- Cc: Ahmad Fatoum <ahmad at a3f dot at>
- Date: Tue, 13 Feb 2018 10:25:57 +0100
- Subject: [PATCH 1/3] bfd_fopen: read from stdin if filename == NULL
- Authentication-results: sourceware.org; auth=none
- References: <20180213092559.56981-1-ahmad@a3f.at>
This is done by slurping stdin into a temporary file.
---
bfd/bfd-in2.h | 3 +++
bfd/bfd.c | 3 +++
bfd/opncls.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 42991e7848..597c2226bc 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6769,6 +6769,9 @@ struct bfd
/* The filename the application opened the BFD with. */
const char *filename;
+ /* If non-NULL, name of a temporary file that can be removed on destruction. */
+ const char *temp_filename;
+
/* A pointer to the target jump table. */
const struct bfd_target *xvec;
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 985c825c69..8fe07468e5 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -62,6 +62,9 @@ CODE_FRAGMENT
. {* The filename the application opened the BFD with. *}
. const char *filename;
.
+. {* If non-NULL, name of a temporary file that can be removed on destruction. *}
+. const char *temp_filename;
+.
. {* A pointer to the target jump table. *}
. const struct bfd_target *xvec;
.
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 16b568c8ab..5861cc2bd8 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -63,6 +63,8 @@ _bfd_new_bfd (void)
if (nbfd == NULL)
return NULL;
+ nbfd->temp_filename = NULL;
+
if (bfd_use_reserved_id)
{
nbfd->id = --bfd_reserved_id_counter;
@@ -128,6 +130,11 @@ _bfd_delete_bfd (bfd *abfd)
if (abfd->filename)
free ((char *) abfd->filename);
+ if (abfd->temp_filename)
+ {
+ remove (abfd->temp_filename);
+ XDELETEVEC ((char *) abfd->temp_filename);
+ }
free (abfd->arelt_data);
free (abfd);
}
@@ -173,8 +180,9 @@ DESCRIPTION
Open the file @var{filename} with the target @var{target}.
Return a pointer to the created BFD. If @var{fd} is not -1,
then <<fdopen>> is used to open the file; otherwise, <<fopen>>
- is used. @var{mode} is passed directly to <<fopen>> or
- <<fdopen>>.
+ is used. If @var{filename} is <<NULL>>, standard input is read
+ into a temporary file which is then opened.
+ @var{mode} is passed directly to <<fopen>> or <<fdopen>>.
Calls <<bfd_find_target>>, so @var{target} is interpreted as by
that function.
@@ -216,12 +224,53 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
#ifdef HAVE_FDOPEN
if (fd != -1)
- nbfd->iostream = fdopen (fd, mode);
+ {
+ nbfd->iostream = fdopen (fd, mode);
+ }
else
#endif
- nbfd->iostream = _bfd_real_fopen (filename, mode);
+ {
+ if (filename)
+ {
+ nbfd->iostream = _bfd_real_fopen (filename, mode);
+ }
+ else /* slurp in stdin */
+ {
+ FILE *fp;
+ size_t nbytes;
+ char buffer[256];
+ nbfd->temp_filename = make_temp_file (NULL);
+ fp = _bfd_real_fopen (nbfd->temp_filename, "w");
+ if (!fp)
+ goto fopen_fail;
+
+ while ((nbytes = fread (buffer, 1, sizeof (buffer), stdin)) > 0)
+ {
+ if (fwrite (buffer, 1, nbytes, fp) != nbytes)
+ break;
+ }
+
+ if (ferror (fp) || ferror (stdin))
+ {
+ bfd_set_input_error (nbfd, bfd_error_on_input);
+ fclose (fp);
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ filename = "<stdin>";
+ nbfd->iostream = _bfd_real_fopen (nbfd->temp_filename, mode);
+ fclose (fp);
+ if (remove (nbfd->temp_filename) == 0)
+ {
+ XDELETEVEC ((char *) nbfd->temp_filename);
+ nbfd->temp_filename = NULL;
+ }
+ }
+ }
if (nbfd->iostream == NULL)
{
+ fopen_fail:
bfd_set_error (bfd_error_system_call);
_bfd_delete_bfd (nbfd);
return NULL;
@@ -269,7 +318,9 @@ SYNOPSIS
DESCRIPTION
Open the file @var{filename} (using <<fopen>>) with the target
- @var{target}. Return a pointer to the created BFD.
+ @var{target}. If @var{filename} is <<NULL>>, standard input is
+ read into a temporary file which is then openend.
+ Return a pointer to the created BFD.
Calls <<bfd_find_target>>, so @var{target} is interpreted as by
that function.
@@ -304,8 +355,9 @@ SYNOPSIS
DESCRIPTION
<<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to
- <<fopen>>. It opens a BFD on a file already described by the
- @var{fd} supplied.
+ <<fopen>>. If @var{filename} is <<NULL>>, standard input is
+ read into a temporary file which is then openend.
+ It opens a BFD on a file already described by the @var{fd} supplied.
When the file is later <<bfd_close>>d, the file descriptor will
be closed. If the caller desires that this file descriptor be
--
2.16.1