This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] ar --output support
- From: "Fāng-ruì Sòng via binutils" <binutils at sourceware dot org>
- To: binutils at sourceware dot org
- Date: Fri, 25 Oct 2019 16:28:33 -0700
- Subject: [PATCH] ar --output support
- References: <CAFP8O3Kiu7iDAC9VRAoi_is_ECbh8CJ9h00oBBCS3BBgaW7fjA@mail.gmail.com>
- Reply-to: Fāng-ruì Sòng <maskray at google dot com>
https://sourceware.org/ml/binutils/2019-10/msg00186.html
> > There is a proposal https://reviews.llvm.org/D69418 that adds --output
> > to llvm-ar. --output specifies the output directory for the x (extract)
> > operation. Does GNU ar want to do the same?
>
> Yes. It would be very helpful for users if both versions of the tool
> behaved in the same way and supported the same options.
>
> Are you volunteering to submit a patch to add this behaviour ?
>
> (I ask because I am lazy/busy and if you are willing to do the work
> then that would be grand. But if not, then I will take on the task
> myself).
From 3ac9fced9ef5a4bca2cb8e2a0888240e9a93919e Mon Sep 17 00:00:00 2001
From: Fangrui Song <maskray@google.com>
Date: Fri, 25 Oct 2019 10:49:40 -0700
Subject: [PATCH] ar --output support
--output specifies the directory that files are extracted to.
---
binutils/ChangeLog | 8 ++++++
binutils/ar.c | 50 +++++++++++++++++++++++++++-----------
binutils/doc/binutils.texi | 7 +++++-
3 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 224ebeb04e..bff3c9a104 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,11 @@
+2019-10-25 Fangrui Song <maskray@google.com>
+
+ * ar.c (output_directory): New variable.
+ (decode_options): Handle --output.
+ (extract_file): Handle output_directory.
+ * doc/binutils.texi: Mention --output can extract files to a specified
+ directory.
+
2019-10-25 Nick Clifton <nickc@redhat.com>
* objcopy.c (struct merged_note_section): New structure. Used to
diff --git a/binutils/ar.c b/binutils/ar.c
index 38c54c9fa8..43c49b7af6 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -25,6 +25,7 @@
#include "sysdep.h"
#include "bfd.h"
+#include "libbfd.h"
#include "libiberty.h"
#include "progress.h"
#include "getopt.h"
@@ -141,6 +142,8 @@ static int show_version = 0;
static int show_help = 0;
+static const char *output_directory = NULL;
+
#if BFD_SUPPORTS_PLUGINS
static const char *plugin_target = "plugin";
#else
@@ -149,12 +152,14 @@ static const char *plugin_target = NULL;
static const char *target = NULL;
+#define OPTION_OUTPUT 200
#define OPTION_PLUGIN 201
#define OPTION_TARGET 202
static struct option long_options[] =
{
{"help", no_argument, &show_help, 1},
+ {"output", required_argument, NULL, OPTION_OUTPUT},
{"plugin", required_argument, NULL, OPTION_PLUGIN},
{"target", required_argument, NULL, OPTION_TARGET},
{"version", no_argument, &show_version, 1},
@@ -581,6 +586,9 @@ decode_options (int argc, char **argv)
case 'U':
deterministic = FALSE;
break;
+ case OPTION_OUTPUT:
+ output_directory = optarg;
+ break;
case OPTION_PLUGIN:
#if BFD_SUPPORTS_PLUGINS
bfd_plugin_set_plugin (optarg);
@@ -1050,6 +1058,19 @@ print_contents (bfd *abfd)
free (cbuf);
}
+static char *
+make_extracted_filename (bfd *abfd)
+{
+ const char *filename = bfd_get_filename (abfd);
+ if (!output_directory)
+ return strdup (filename);
+ char *pathbuf
+ = (char *)bfd_malloc (strlen (output_directory) + strlen (filename) + 2);
+ if (pathbuf)
+ sprintf (pathbuf, "%s/%s", output_directory, filename);
+ return pathbuf;
+}
+
/* Extract a member of the archive into its own file.
We defer opening the new file until after we have read a BUFSIZ chunk of the
@@ -1094,14 +1115,14 @@ extract_file (bfd *abfd)
if (size == 0)
{
/* Seems like an abstraction violation, eh? Well it's OK! */
- output_filename = bfd_get_filename (abfd);
+ output_filename = make_extracted_filename (abfd);
- ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
- if (ostream == NULL)
- {
- perror (bfd_get_filename (abfd));
+ if (output_filename == NULL
+ || (ostream = fopen (output_filename, FOPEN_WB)) == NULL)
+ {
+ perror (bfd_get_filename (abfd));
xexit (1);
- }
+ }
output_file = ostream;
}
@@ -1122,16 +1143,16 @@ extract_file (bfd *abfd)
if (ostream == NULL)
{
/* Seems like an abstraction violation, eh? Well it's OK! */
- output_filename = bfd_get_filename (abfd);
+ output_filename = make_extracted_filename (abfd);
- ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
- if (ostream == NULL)
- {
- perror (bfd_get_filename (abfd));
- xexit (1);
- }
+ if (output_filename == NULL
+ || (ostream = fopen (output_filename, FOPEN_WB)) == NULL)
+ {
+ perror (bfd_get_filename (abfd));
+ xexit (1);
+ }
- output_file = ostream;
+ output_file = ostream;
}
/* fwrite in mingw32 may return int instead of bfd_size_type. Cast
@@ -1146,6 +1167,7 @@ extract_file (bfd *abfd)
fclose (ostream);
output_file = NULL;
+ free ((char *)output_filename);
output_filename = NULL;
chmod (bfd_get_filename (abfd), buf.st_mode);
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 2edd7e1aa1..c27405585d 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -169,7 +169,7 @@ in the section entitled ``GNU Free Documentation License''.
@c man title ar create, modify, and extract from archives
@smallexample
-ar [-]@var{p}[@var{mod}] [@option{--plugin} @var{name}] [@option{--target} @var{bfdname}] [@var{relpos}] [@var{count}] @var{archive} [@var{member}@dots{}]
+ar [-]@var{p}[@var{mod}] [@option{--output} @var{directory}] [@option{--plugin} @var{name}] [@option{--target} @var{bfdname}] [@var{relpos}] [@var{count}] @var{archive} [@var{member}@dots{}]
ar -M [ <mri-script ]
@end smallexample
@@ -550,6 +550,11 @@ default for @sc{gnu} @command{ar}. @command{ar} does not support any
of the other @samp{-X} options; in particular, it does not support
@option{-X32} which is the default for AIX @command{ar}.
+@item --output @var{directory}
+@cindex output directory
+The optional command-line switch @option{--output @var{name}} causes
+@command{ar} to extract files to @var{directory}.
+
@item --plugin @var{name}
@cindex plugins
The optional command-line switch @option{--plugin @var{name}} causes
--
2.20.0