Remove LIBS from two sim Makefiles
[deliverable/binutils-gdb.git] / binutils / rename.c
index 861c2b56d183b4f194bcc9afe65fd2e7150c3093..8826917c18c747c5d68e107c95b1ab0b79a62418 100644 (file)
 #include "bfd.h"
 #include "bucomm.h"
 
-#ifdef HAVE_GOOD_UTIME_H
-#include <utime.h>
-#elif defined HAVE_UTIMES
+#if defined HAVE_UTIMES
 #include <sys/time.h>
+#elif defined HAVE_GOOD_UTIME_H
+#include <utime.h>
 #endif
 
 /* The number of bytes to copy at once.  */
@@ -86,6 +86,80 @@ simple_copy (int fromfd, const char *to,
   return 0;
 }
 
+/* The following defines and inline functions are copied from gnulib.
+   FIXME: Use a gnulib import and stat-time.h instead.  */
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+# if defined TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC
+#  define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
+# else
+#  define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec)
+# endif
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec)
+#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec)
+#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC
+# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec)
+#endif
+
+static inline long int get_stat_atime_ns (struct stat const *) ATTRIBUTE_UNUSED;
+static inline long int get_stat_mtime_ns (struct stat const *) ATTRIBUTE_UNUSED;
+
+/* Return the nanosecond component of *ST's access time.  */
+static inline long int
+get_stat_atime_ns (struct stat const *st ATTRIBUTE_UNUSED)
+{
+# if defined STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_atim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+  return STAT_TIMESPEC_NS (st, st_atim);
+# else
+  return 0;
+# endif
+}
+
+/* Return the nanosecond component of *ST's data modification time.  */
+static inline long int
+get_stat_mtime_ns (struct stat const *st ATTRIBUTE_UNUSED)
+{
+# if defined STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_mtim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+  return STAT_TIMESPEC_NS (st, st_mtim);
+# else
+  return 0;
+# endif
+}
+
+/* Return *ST's access time.  */
+static inline struct timespec
+get_stat_atime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_atim);
+#else
+  struct timespec t;
+  t.tv_sec = st->st_atime;
+  t.tv_nsec = get_stat_atime_ns (st);
+  return t;
+#endif
+}
+
+/* Return *ST's data modification time.  */
+static inline struct timespec
+get_stat_mtime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_mtim);
+#else
+  struct timespec t;
+  t.tv_sec = st->st_mtime;
+  t.tv_nsec = get_stat_mtime_ns (st);
+  return t;
+#endif
+}
+/* End FIXME.  */
+
 /* Set the times of the file DESTINATION to be the same as those in
    STATBUF.  */
 
@@ -93,20 +167,25 @@ void
 set_times (const char *destination, const struct stat *statbuf)
 {
   int result;
-#ifdef HAVE_GOOD_UTIME_H
-  struct utimbuf tb;
-
-  tb.actime = statbuf->st_atime;
-  tb.modtime = statbuf->st_mtime;
-  result = utime (destination, &tb);
+#if defined HAVE_UTIMENSAT
+  struct timespec times[2];
+  times[0] = get_stat_atime (statbuf);
+  times[1] = get_stat_mtime (statbuf);
+  result = utimensat (AT_FDCWD, destination, times, 0);
 #elif defined HAVE_UTIMES
   struct timeval tv[2];
 
   tv[0].tv_sec = statbuf->st_atime;
-  tv[0].tv_usec = 0;
+  tv[0].tv_usec = get_stat_atime_ns (statbuf) / 1000;
   tv[1].tv_sec = statbuf->st_mtime;
-  tv[1].tv_usec = 0;
+  tv[1].tv_usec = get_stat_mtime_ns (statbuf) / 1000;
   result = utimes (destination, tv);
+#elif defined HAVE_GOOD_UTIME_H
+  struct utimbuf tb;
+
+  tb.actime = statbuf->st_atime;
+  tb.modtime = statbuf->st_mtime;
+  result = utime (destination, &tb);
 #else
   long tb[2];
 
@@ -127,18 +206,21 @@ set_times (const char *destination, const struct stat *statbuf)
 
 int
 smart_rename (const char *from, const char *to, int fromfd,
-             struct stat *target_stat, bfd_boolean preserve_dates)
+             struct stat *target_stat, bool preserve_dates)
 {
-  int ret;
+  int ret = 0;
 
-  ret = simple_copy (fromfd, to, target_stat);
-  if (ret != 0)
-    non_fatal (_("unable to copy file '%s'; reason: %s"),
-              to, strerror (errno));
+  if (to != from)
+    {
+      ret = simple_copy (fromfd, to, target_stat);
+      if (ret != 0)
+       non_fatal (_("unable to copy file '%s'; reason: %s"),
+                  to, strerror (errno));
+      unlink (from);
+    }
 
   if (preserve_dates)
     set_times (to, target_stat);
-  unlink (from);
 
   return ret;
 }
This page took 0.0237 seconds and 4 git commands to generate.