PR 14072
[deliverable/binutils-gdb.git] / binutils / ar.c
index 6320a28ddcb4e3c8a78217ea95ec336a0dcc885c..13637f40c7315ec0fef3e258f344a8c82dad69a6 100644 (file)
@@ -1,6 +1,6 @@
 /* ar.c - Archive modify and extract.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -37,7 +37,6 @@
 #include "filenames.h"
 #include "binemul.h"
 #include "plugin.h"
-#include <sys/stat.h>
 
 #ifdef __GO32___
 #define EXT_NAME_LEN 3         /* Bufflen of addition to name if it's MS-DOS.  */
@@ -97,7 +96,7 @@ int write_armap = 0;
 /* Operate in deterministic mode: write zero for timestamps, uids,
    and gids for archive members and the archive symbol table, and write
    consistent file modes.  */
-int deterministic = 0;
+int deterministic = -1;                        /* Determinism indeterminate.  */
 
 /* Nonzero means it's the name of an existing member; position new or moved
    files with respect to this one.  */
@@ -276,7 +275,20 @@ usage (int help)
   fprintf (s, _(" command specific modifiers:\n"));
   fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
   fprintf (s, _("  [b]          - put file(s) before [member-name] (same as [i])\n"));
-  fprintf (s, _("  [D]          - use zero for timestamps and uids/gids\n"));
+  if (DEFAULT_AR_DETERMINISTIC)
+    {
+      fprintf (s, _("\
+  [D]          - use zero for timestamps and uids/gids (default)\n"));
+      fprintf (s, _("\
+  [U]          - use actual timestamps and uids/gids\n"));
+    }
+  else
+    {
+      fprintf (s, _("\
+  [D]          - use zero for timestamps and uids/gids\n"));
+      fprintf (s, _("\
+  [U]          - use actual timestamps and uids/gids (default)\n"));
+    }
   fprintf (s, _("  [N]          - use instance [count] of name\n"));
   fprintf (s, _("  [f]          - truncate inserted file names\n"));
   fprintf (s, _("  [P]          - use full path names when matching\n"));
@@ -322,6 +334,14 @@ ranlib_usage (int help)
   fprintf (s, _("\
   --plugin <name>              Load the specified plugin\n"));
 #endif
+  if (DEFAULT_AR_DETERMINISTIC)
+    fprintf (s, _("\
+  -D                           Use zero for symbol map timestamp (default)\n\
+  -U                           Use an actual symbol map timestamp\n"));
+  else
+    fprintf (s, _("\
+  -D                           Use zero for symbol map timestamp\n\
+  -U                           Use actual symbol map timestamp (default)\n"));
   fprintf (s, _("\
   -t                           Update the archive's symbol map timestamp\n\
   -h --help                    Print this help message\n\
@@ -433,7 +453,7 @@ decode_options (int argc, char **argv)
       argv = new_argv;
     }
 
-  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoVsSuvabiMNfPTD",
+  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoVsSuvabiMNfPTDU",
                           long_options, NULL)) != EOF)
     {
       switch (c)
@@ -530,6 +550,9 @@ decode_options (int argc, char **argv)
         case 'D':
           deterministic = TRUE;
           break;
+        case 'U':
+          deterministic = FALSE;
+          break;
        case OPTION_PLUGIN:
 #if BFD_SUPPORTS_PLUGINS
          plugin_target = "plugin";
@@ -552,6 +575,15 @@ decode_options (int argc, char **argv)
   return &argv[optind];
 }
 
+/* If neither -D nor -U was not specified explicitly,
+   then use the configured default.  */
+static void
+default_deterministic (void)
+{
+  if (deterministic < 0)
+    deterministic = DEFAULT_AR_DETERMINISTIC;
+}
+
 static void
 ranlib_main (int argc, char **argv)
 {
@@ -559,10 +591,16 @@ ranlib_main (int argc, char **argv)
   bfd_boolean touch = FALSE;
   int c;
 
-  while ((c = getopt_long (argc, argv, "hHvVt", long_options, NULL)) != EOF)
+  while ((c = getopt_long (argc, argv, "DhHUvVt", long_options, NULL)) != EOF)
     {
       switch (c)
         {
+       case 'D':
+         deterministic = TRUE;
+         break;
+        case 'U':
+          deterministic = FALSE;
+          break;
        case 'h':
        case 'H':
          show_help = 1;
@@ -574,18 +612,31 @@ ranlib_main (int argc, char **argv)
        case 'V':
          show_version = 1;
          break;
-        }
+
+         /* PR binutils/13493: Support plugins.  */
+       case OPTION_PLUGIN:
+#if BFD_SUPPORTS_PLUGINS
+         plugin_target = "plugin";
+         bfd_plugin_set_plugin (optarg);
+#else
+         fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
+         xexit (1);
+#endif
+         break;
+       }
     }
 
   if (argc < 2)
     ranlib_usage (0);
 
   if (show_help)
-    usage (1);
+    ranlib_usage (1);
 
   if (show_version)
     print_version ("ranlib");
 
+  default_deterministic ();
+
   arg_index = optind;
 
   while (arg_index < argc)
@@ -695,8 +746,14 @@ main (int argc, char **argv)
       if (newer_only && operation != replace)
        fatal (_("`u' is only meaningful with the `r' option."));
 
-      if (newer_only && deterministic)
-       fatal (_("`u' is not meaningful with the `D' option."));
+      if (newer_only && deterministic > 0)
+        fatal (_("`u' is not meaningful with the `D' option."));
+
+      if (newer_only && deterministic < 0 && DEFAULT_AR_DETERMINISTIC)
+        non_fatal (_("\
+`u' modifier ignored since `D' is the default (see `U')"));
+
+      default_deterministic ();
 
       if (postype != pos_default)
        posname = argv[arg_index++];
@@ -745,11 +802,17 @@ main (int argc, char **argv)
          break;
 
        case move:
-         if (files != NULL)
-           move_members (arch, files);
-         else
-           output_filename = NULL;
-         break;
+         /* PR 12558: Creating and moving at the same time does
+            not make sense.  Just create the archive instead.  */
+         if (! silent_create)
+           {
+             if (files != NULL)
+               move_members (arch, files);
+             else
+               output_filename = NULL;
+             break;
+           }
+         /* Fall through.  */
 
        case replace:
        case quick_append:
@@ -809,9 +872,9 @@ open_inarch (const char *archive_filename, const char *file)
          return NULL;
        }
 
-      /* Try to figure out the target to use for the archive from the
-         first object on the list.  */
-      if (file != NULL)
+      /* If the target isn't set, try to figure out the target to use
+        for the archive from the first object on the list.  */
+      if (target == NULL && file != NULL)
        {
          bfd *obj;
 
@@ -1025,7 +1088,7 @@ write_archive (bfd *iarch)
   new_name = make_tempname (old_name);
 
   if (new_name == NULL)
-    bfd_fatal ("could not create temporary file whilst writing archive");
+    bfd_fatal (_("could not create temporary file whilst writing archive"));
 
   output_filename = new_name;
 
@@ -1069,6 +1132,7 @@ write_archive (bfd *iarch)
 
   if (smart_rename (new_name, old_name, 0) != 0)
     xexit (1);
+  free (old_name);
 }
 
 /* Return a pointer to the pointer to the entry which should be rplacd'd
@@ -1185,9 +1249,8 @@ delete_members (bfd *arch, char **files_to_delete)
 static void
 move_members (bfd *arch, char **files_to_move)
 {
-  bfd **after_bfd;             /* New entries go after this one.  */
-  bfd **current_ptr_ptr;       /* cdr pointer into contents.  */
-  const char *tmp = NULL;
+  bfd **after_bfd;             /* New entries go after this one */
+  bfd **current_ptr_ptr;       /* cdr pointer into contents */
 
   for (; *files_to_move; ++files_to_move)
     {
@@ -1195,11 +1258,8 @@ move_members (bfd *arch, char **files_to_move)
       while (*current_ptr_ptr)
        {
          bfd *current_ptr = *current_ptr_ptr;
-
-         if (tmp != NULL)
-           free ((char *) tmp);
-         tmp = normalize (*files_to_move, arch);
-         if (FILENAME_CMP (tmp, current_ptr->filename) == 0)
+         if (FILENAME_CMP (normalize (*files_to_move, arch),
+                           current_ptr->filename) == 0)
            {
              /* Move this file to the end of the list - first cut from
                 where it is.  */
@@ -1223,13 +1283,10 @@ move_members (bfd *arch, char **files_to_move)
       /* xgettext:c-format */
       fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
 
-    next_file:
-      ;
+    next_file:;
     }
 
   write_archive (arch);
-  if (tmp != NULL)
-    free ((char *) tmp);
 }
 
 /* Ought to default to replacing in place, but this is existing practice!  */
@@ -1365,6 +1422,9 @@ ranlib_touch (const char *archname)
     /* xgettext:c-format */
     fatal (_("%s: no archive map to update"), archname);
 
+  if (deterministic)
+    arch->flags |= BFD_DETERMINISTIC_OUTPUT;
+
   bfd_update_armap_timestamp (arch);
 
   if (! bfd_close (arch))
This page took 0.032193 seconds and 4 git commands to generate.