mirror of
https://git.yoctoproject.org/poky
synced 2026-06-02 13:29:49 +00:00
binutils: Fix CVE-2021-20197
Source: git://sourceware.org/git/binutils-gdb.git Tracking -- https://sourceware.org/bugzilla/show_bug.cgi?id=26945 Backported upstream commit id d3edaa91d4cf7202ec14342410194841e2f67f12 and its dependent commits 8e03235147a9e774d3ba084e93c2da1aa94d1cec and 8b69e61d4be276bb862698aaafddc3e779d23c8f to binutils-2.36 source. Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8e03235147a9e774d3ba084e93c2da1aa94d1cec] Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d3edaa91d4cf7202ec14342410194841e2f67f12] Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8b69e61d4be276bb862698aaafddc3e779d23c8f] (From OE-Core rev: f5f831c3a76456bce543d42d0f14411b28770b45) Signed-off-by: Vinay Kumar <vinay.m.engg@gmail.com> Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
8d4748254e
commit
db00b0a059
@@ -41,5 +41,8 @@ SRC_URI = "\
|
|||||||
file://0014-Fix-rpath-in-libtool-when-sysroot-is-enabled.patch \
|
file://0014-Fix-rpath-in-libtool-when-sysroot-is-enabled.patch \
|
||||||
file://0015-sync-with-OE-libtool-changes.patch \
|
file://0015-sync-with-OE-libtool-changes.patch \
|
||||||
file://0016-Check-for-clang-before-checking-gcc-version.patch \
|
file://0016-Check-for-clang-before-checking-gcc-version.patch \
|
||||||
|
file://0001-CVE-2021-20197.patch \
|
||||||
|
file://0002-CVE-2021-20197.patch \
|
||||||
|
file://0003-CVE-2021-20197.patch \
|
||||||
"
|
"
|
||||||
S = "${WORKDIR}/git"
|
S = "${WORKDIR}/git"
|
||||||
|
|||||||
@@ -0,0 +1,201 @@
|
|||||||
|
From 8e03235147a9e774d3ba084e93c2da1aa94d1cec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Siddhesh Poyarekar <siddhesh@gotplt.org>
|
||||||
|
Date: Mon, 22 Feb 2021 20:45:50 +0530
|
||||||
|
Subject: [PATCH] binutils: Avoid renaming over existing files
|
||||||
|
|
||||||
|
Renaming over existing files needs additional care to restore
|
||||||
|
permissions and ownership, which may not always succeed.
|
||||||
|
Additionally, other properties of the file such as extended attributes
|
||||||
|
may be lost, making the operation flaky.
|
||||||
|
|
||||||
|
For predictable results, resort to rename() only if the file does not
|
||||||
|
exist, otherwise copy the file contents into the existing file. This
|
||||||
|
ensures that no additional tricks are needed to retain file
|
||||||
|
properties.
|
||||||
|
|
||||||
|
This also allows dropping of the redundant set_times on the tmpfile in
|
||||||
|
objcopy/strip since now we no longer rename over existing files.
|
||||||
|
|
||||||
|
binutils/
|
||||||
|
|
||||||
|
* ar.c (write_archive): Adjust call to SMART_RENAME.
|
||||||
|
* arsup.c (ar_save): Likewise.
|
||||||
|
* objcopy (strip_main): Don't set times on temporary file and
|
||||||
|
adjust call to SMART_RENAME.
|
||||||
|
(copy_main): Likewise.
|
||||||
|
* rename.c [!S_ISLNK]: Remove definitions.
|
||||||
|
(try_preserve_permissions): Remove function.
|
||||||
|
(smart_rename): Replace PRESERVE_DATES argument with
|
||||||
|
TARGET_STAT. Use rename system call only if TO does not exist.
|
||||||
|
* bucomm.h (smart_rename): Adjust declaration.
|
||||||
|
|
||||||
|
(cherry picked from commit 3685de750e6a091663a0abe42528cad29e960e35)
|
||||||
|
|
||||||
|
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8e03235147a9e774d3ba084e93c2da1aa94d1cec]
|
||||||
|
CVE: CVE-2021-20197
|
||||||
|
Signed-off-by: Vinay Kumar <vinay.m.engg@gmail.com>
|
||||||
|
---
|
||||||
|
binutils/ar.c | 2 +-
|
||||||
|
binutils/arsup.c | 2 +-
|
||||||
|
binutils/bucomm.h | 3 ++-
|
||||||
|
binutils/objcopy.c | 8 ++-----
|
||||||
|
binutils/rename.c | 55 +++++++++-------------------------------------
|
||||||
|
6 files changed, 29 insertions(+), 54 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/binutils/ar.c b/binutils/ar.c
|
||||||
|
index 45a34e3a6cf..3a91708b51c 100644
|
||||||
|
--- a/binutils/ar.c
|
||||||
|
+++ b/binutils/ar.c
|
||||||
|
@@ -1308,7 +1308,7 @@ write_archive (bfd *iarch)
|
||||||
|
/* We don't care if this fails; we might be creating the archive. */
|
||||||
|
bfd_close (iarch);
|
||||||
|
|
||||||
|
- if (smart_rename (new_name, old_name, 0) != 0)
|
||||||
|
+ if (smart_rename (new_name, old_name, NULL) != 0)
|
||||||
|
xexit (1);
|
||||||
|
free (old_name);
|
||||||
|
free (new_name);
|
||||||
|
diff --git a/binutils/arsup.c b/binutils/arsup.c
|
||||||
|
index 5403a0c5d74..0a1f63f6456 100644
|
||||||
|
--- a/binutils/arsup.c
|
||||||
|
+++ b/binutils/arsup.c
|
||||||
|
@@ -351,7 +351,7 @@ ar_save (void)
|
||||||
|
|
||||||
|
bfd_close (obfd);
|
||||||
|
|
||||||
|
- smart_rename (ofilename, real_name, 0);
|
||||||
|
+ smart_rename (ofilename, real_name, NULL);
|
||||||
|
obfd = 0;
|
||||||
|
free (ofilename);
|
||||||
|
}
|
||||||
|
diff --git a/binutils/bucomm.h b/binutils/bucomm.h
|
||||||
|
index 91f6a5b228f..aa7e33d8cd1 100644
|
||||||
|
--- a/binutils/bucomm.h
|
||||||
|
+++ b/binutils/bucomm.h
|
||||||
|
@@ -71,7 +71,8 @@ extern void print_version (const char *);
|
||||||
|
/* In rename.c. */
|
||||||
|
extern void set_times (const char *, const struct stat *);
|
||||||
|
|
||||||
|
-extern int smart_rename (const char *, const char *, int);
|
||||||
|
+extern int smart_rename (const char *, const char *, struct stat *);
|
||||||
|
+
|
||||||
|
|
||||||
|
/* In libiberty. */
|
||||||
|
void *xmalloc (size_t);
|
||||||
|
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
|
||||||
|
index eab3b6db585..07a872b5a80 100644
|
||||||
|
--- a/binutils/objcopy.c
|
||||||
|
+++ b/binutils/objcopy.c
|
||||||
|
@@ -4861,12 +4861,10 @@ strip_main (int argc, char *argv[])
|
||||||
|
output_target, NULL);
|
||||||
|
if (status == 0)
|
||||||
|
{
|
||||||
|
- if (preserve_dates)
|
||||||
|
- set_times (tmpname, &statbuf);
|
||||||
|
if (output_file != tmpname)
|
||||||
|
status = (smart_rename (tmpname,
|
||||||
|
output_file ? output_file : argv[i],
|
||||||
|
- preserve_dates) != 0);
|
||||||
|
+ preserve_dates ? &statbuf : NULL) != 0);
|
||||||
|
if (status == 0)
|
||||||
|
status = hold_status;
|
||||||
|
}
|
||||||
|
@@ -5931,11 +5929,9 @@ copy_main (int argc, char *argv[])
|
||||||
|
output_target, input_arch);
|
||||||
|
if (status == 0)
|
||||||
|
{
|
||||||
|
- if (preserve_dates)
|
||||||
|
- set_times (tmpname, &statbuf);
|
||||||
|
if (tmpname != output_filename)
|
||||||
|
status = (smart_rename (tmpname, input_filename,
|
||||||
|
- preserve_dates) != 0);
|
||||||
|
+ preserve_dates ? &statbuf : NULL) != 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
unlink_if_ordinary (tmpname);
|
||||||
|
diff --git a/binutils/rename.c b/binutils/rename.c
|
||||||
|
index 65ad5bf52c4..f471b45fd3f 100644
|
||||||
|
--- a/binutils/rename.c
|
||||||
|
+++ b/binutils/rename.c
|
||||||
|
@@ -122,20 +122,13 @@ set_times (const char *destination, const struct stat *statbuf)
|
||||||
|
non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifndef S_ISLNK
|
||||||
|
-#ifdef S_IFLNK
|
||||||
|
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||||
|
-#else
|
||||||
|
-#define S_ISLNK(m) 0
|
||||||
|
-#define lstat stat
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* Rename FROM to TO, copying if TO is a link.
|
||||||
|
- Return 0 if ok, -1 if error. */
|
||||||
|
+/* Rename FROM to TO, copying if TO exists. TARGET_STAT has the file status
|
||||||
|
+ that, if non-NULL, is used to fix up timestamps after rename. Return 0 if
|
||||||
|
+ ok, -1 if error. */
|
||||||
|
|
||||||
|
int
|
||||||
|
-smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED)
|
||||||
|
+smart_rename (const char *from, const char *to,
|
||||||
|
+ struct stat *target_stat ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
bfd_boolean exists;
|
||||||
|
struct stat s;
|
||||||
|
@@ -158,38 +151,10 @@ smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNU
|
||||||
|
unlink (from);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
- /* Use rename only if TO is not a symbolic link and has
|
||||||
|
- only one hard link, and we have permission to write to it. */
|
||||||
|
- if (! exists
|
||||||
|
- || (!S_ISLNK (s.st_mode)
|
||||||
|
- && S_ISREG (s.st_mode)
|
||||||
|
- && (s.st_mode & S_IWUSR)
|
||||||
|
- && s.st_nlink == 1)
|
||||||
|
- )
|
||||||
|
+ /* Avoid a full copy and use rename if TO does not exist. */
|
||||||
|
+ if (!exists)
|
||||||
|
{
|
||||||
|
- ret = rename (from, to);
|
||||||
|
- if (ret == 0)
|
||||||
|
- {
|
||||||
|
- if (exists)
|
||||||
|
- {
|
||||||
|
- /* Try to preserve the permission bits and ownership of
|
||||||
|
- TO. First get the mode right except for the setuid
|
||||||
|
- bit. Then change the ownership. Then fix the setuid
|
||||||
|
- bit. We do the chmod before the chown because if the
|
||||||
|
- chown succeeds, and we are a normal user, we won't be
|
||||||
|
- able to do the chmod afterward. We don't bother to
|
||||||
|
- fix the setuid bit first because that might introduce
|
||||||
|
- a fleeting security problem, and because the chown
|
||||||
|
- will clear the setuid bit anyhow. We only fix the
|
||||||
|
- setuid bit if the chown succeeds, because we don't
|
||||||
|
- want to introduce an unexpected setuid file owned by
|
||||||
|
- the user running objcopy. */
|
||||||
|
- chmod (to, s.st_mode & 0777);
|
||||||
|
- if (chown (to, s.st_uid, s.st_gid) >= 0)
|
||||||
|
- chmod (to, s.st_mode & 07777);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
+ if ((ret = rename (from, to)) != 0)
|
||||||
|
{
|
||||||
|
/* We have to clean up here. */
|
||||||
|
non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
|
||||||
|
@@ -202,8 +167,8 @@ smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNU
|
||||||
|
if (ret != 0)
|
||||||
|
non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
|
||||||
|
|
||||||
|
- if (preserve_dates)
|
||||||
|
- set_times (to, &s);
|
||||||
|
+ if (target_stat != NULL)
|
||||||
|
+ set_times (to, target_stat);
|
||||||
|
unlink (from);
|
||||||
|
}
|
||||||
|
#endif /* _WIN32 && !__CYGWIN32__ */
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
From d3edaa91d4cf7202ec14342410194841e2f67f12 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Modra <amodra@gmail.com>
|
||||||
|
Date: Fri, 26 Feb 2021 11:30:32 +1030
|
||||||
|
Subject: [PATCH] Reinstate various pieces backed out from smart_rename changes
|
||||||
|
|
||||||
|
In the interests of a stable release various last minute smart_rename
|
||||||
|
patches were backed out of the 2.36 branch. The main reason to
|
||||||
|
reinstate some of those backed out changes here is to make necessary
|
||||||
|
followup fixes to commit 8e03235147a9 simple cherry-picks from
|
||||||
|
mainline. A secondary reason is that ar -M support isn't fixed for
|
||||||
|
pr26945 without this patch.
|
||||||
|
|
||||||
|
PR 26945
|
||||||
|
* ar.c: Don't include libbfd.h.
|
||||||
|
(write_archive): Replace xmalloc+strcpy with xstrdup.
|
||||||
|
* arsup.c (temp_name, real_ofd): New static variables.
|
||||||
|
(ar_open): Use make_tempname and bfd_fdopenw.
|
||||||
|
(ar_save): Adjust to suit ar_open changes.
|
||||||
|
* objcopy.c: Don't include libbfd.h.
|
||||||
|
* rename.c: Rename and reorder variables.
|
||||||
|
|
||||||
|
(cherry picked from commit 95b91a043aeaeb546d2fea556d84a2de1e917770)
|
||||||
|
|
||||||
|
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d3edaa91d4cf7202ec14342410194841e2f67f12]
|
||||||
|
CVE: CVE-2021-20197
|
||||||
|
Signed-off-by: Vinay Kumar <vinay.m.engg@gmail.com>
|
||||||
|
---
|
||||||
|
binutils/ar.c | 4 +---
|
||||||
|
binutils/arsup.c | 37 +++++++++++++++++++++++++------------
|
||||||
|
binutils/objcopy.c | 1 -
|
||||||
|
binutils/rename.c | 6 +++---
|
||||||
|
5 files changed, 42 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/binutils/ar.c b/binutils/ar.c
|
||||||
|
index 3a91708b51c..44df48c5c67 100644
|
||||||
|
--- a/binutils/ar.c
|
||||||
|
+++ b/binutils/ar.c
|
||||||
|
@@ -25,7 +25,6 @@
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "bfd.h"
|
||||||
|
-#include "libbfd.h"
|
||||||
|
#include "libiberty.h"
|
||||||
|
#include "progress.h"
|
||||||
|
#include "getopt.h"
|
||||||
|
@@ -1255,8 +1254,7 @@ write_archive (bfd *iarch)
|
||||||
|
bfd *contents_head = iarch->archive_next;
|
||||||
|
int ofd = -1;
|
||||||
|
|
||||||
|
- old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
|
||||||
|
- strcpy (old_name, bfd_get_filename (iarch));
|
||||||
|
+ old_name = xstrdup (bfd_get_filename (iarch));
|
||||||
|
new_name = make_tempname (old_name, &ofd);
|
||||||
|
|
||||||
|
if (new_name == NULL)
|
||||||
|
diff --git a/binutils/arsup.c b/binutils/arsup.c
|
||||||
|
index 0a1f63f6456..f7ce8f0bc82 100644
|
||||||
|
--- a/binutils/arsup.c
|
||||||
|
+++ b/binutils/arsup.c
|
||||||
|
@@ -42,6 +42,8 @@ extern int deterministic;
|
||||||
|
|
||||||
|
static bfd *obfd;
|
||||||
|
static char *real_name;
|
||||||
|
+static char *temp_name;
|
||||||
|
+static int real_ofd;
|
||||||
|
static FILE *outfile;
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -149,27 +151,24 @@ maybequit (void)
|
||||||
|
void
|
||||||
|
ar_open (char *name, int t)
|
||||||
|
{
|
||||||
|
- char *tname;
|
||||||
|
- const char *bname = lbasename (name);
|
||||||
|
- real_name = name;
|
||||||
|
+ real_name = xstrdup (name);
|
||||||
|
+ temp_name = make_tempname (real_name, &real_ofd);
|
||||||
|
|
||||||
|
- /* Prepend tmp- to the beginning, to avoid file-name clashes after
|
||||||
|
- truncation on filesystems with limited namespaces (DOS). */
|
||||||
|
- if (asprintf (&tname, "%.*stmp-%s", (int) (bname - name), name, bname) == -1)
|
||||||
|
+ if (temp_name == NULL)
|
||||||
|
{
|
||||||
|
- fprintf (stderr, _("%s: Can't allocate memory for temp name (%s)\n"),
|
||||||
|
+ fprintf (stderr, _("%s: Can't open temporary file (%s)\n"),
|
||||||
|
program_name, strerror(errno));
|
||||||
|
maybequit ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- obfd = bfd_openw (tname, NULL);
|
||||||
|
+ obfd = bfd_fdopenw (temp_name, NULL, real_ofd);
|
||||||
|
|
||||||
|
if (!obfd)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: Can't open output archive %s\n"),
|
||||||
|
- program_name, tname);
|
||||||
|
+ program_name, temp_name);
|
||||||
|
|
||||||
|
maybequit ();
|
||||||
|
}
|
||||||
|
@@ -344,16 +343,30 @@ ar_save (void)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- char *ofilename = xstrdup (bfd_get_filename (obfd));
|
||||||
|
+ struct stat target_stat;
|
||||||
|
|
||||||
|
if (deterministic > 0)
|
||||||
|
obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
|
||||||
|
|
||||||
|
bfd_close (obfd);
|
||||||
|
|
||||||
|
- smart_rename (ofilename, real_name, NULL);
|
||||||
|
+ if (stat (real_name, &target_stat) != 0)
|
||||||
|
+ {
|
||||||
|
+ /* The temp file created in ar_open has mode 0600 as per mkstemp.
|
||||||
|
+ Create the real empty output file here so smart_rename will
|
||||||
|
+ update the mode according to the process umask. */
|
||||||
|
+ obfd = bfd_openw (real_name, NULL);
|
||||||
|
+ if (obfd != NULL)
|
||||||
|
+ {
|
||||||
|
+ bfd_set_format (obfd, bfd_archive);
|
||||||
|
+ bfd_close (obfd);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ smart_rename (temp_name, real_name, NULL);
|
||||||
|
obfd = 0;
|
||||||
|
- free (ofilename);
|
||||||
|
+ free (temp_name);
|
||||||
|
+ free (real_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
|
||||||
|
index 07a872b5a80..73aa8bc2514 100644
|
||||||
|
--- a/binutils/objcopy.c
|
||||||
|
+++ b/binutils/objcopy.c
|
||||||
|
@@ -20,7 +20,6 @@
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "bfd.h"
|
||||||
|
-#include "libbfd.h"
|
||||||
|
#include "progress.h"
|
||||||
|
#include "getopt.h"
|
||||||
|
#include "libiberty.h"
|
||||||
|
diff --git a/binutils/rename.c b/binutils/rename.c
|
||||||
|
index f471b45fd3f..2ff092ee22b 100644
|
||||||
|
--- a/binutils/rename.c
|
||||||
|
+++ b/binutils/rename.c
|
||||||
|
@@ -130,11 +130,11 @@ int
|
||||||
|
smart_rename (const char *from, const char *to,
|
||||||
|
struct stat *target_stat ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
- bfd_boolean exists;
|
||||||
|
- struct stat s;
|
||||||
|
int ret = 0;
|
||||||
|
+ struct stat to_stat;
|
||||||
|
+ bfd_boolean exists;
|
||||||
|
|
||||||
|
- exists = lstat (to, &s) == 0;
|
||||||
|
+ exists = lstat (to, &to_stat) == 0;
|
||||||
|
|
||||||
|
#if defined (_WIN32) && !defined (__CYGWIN32__)
|
||||||
|
/* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
From 8b69e61d4be276bb862698aaafddc3e779d23c8f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Modra <amodra@gmail.com>
|
||||||
|
Date: Tue, 23 Feb 2021 09:37:39 +1030
|
||||||
|
Subject: [PATCH] PR27456, lstat in rename.c on MinGW
|
||||||
|
|
||||||
|
PR 27456
|
||||||
|
* rename.c: Tidy throughout.
|
||||||
|
(smart_rename): Always copy. Remove windows specific code.
|
||||||
|
|
||||||
|
(cherry picked from commit cca8873dd5a6015d5557ea44bc1ea9c252435a29)
|
||||||
|
|
||||||
|
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8b69e61d4be276bb862698aaafddc3e779d23c8f]
|
||||||
|
CVE: CVE-2021-20197
|
||||||
|
Signed-off-by: Vinay Kumar <vinay.m.engg@gmail.com>
|
||||||
|
---
|
||||||
|
binutils/rename.c | 111 ++++++++++++++-------------------------------
|
||||||
|
2 files changed, 40 insertions(+), 76 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/binutils/rename.c b/binutils/rename.c
|
||||||
|
index 2ff092ee22b..72a9323d72c 100644
|
||||||
|
--- a/binutils/rename.c
|
||||||
|
+++ b/binutils/rename.c
|
||||||
|
@@ -24,14 +24,9 @@
|
||||||
|
|
||||||
|
#ifdef HAVE_GOOD_UTIME_H
|
||||||
|
#include <utime.h>
|
||||||
|
-#else /* ! HAVE_GOOD_UTIME_H */
|
||||||
|
-#ifdef HAVE_UTIMES
|
||||||
|
+#elif defined HAVE_UTIMES
|
||||||
|
#include <sys/time.h>
|
||||||
|
-#endif /* HAVE_UTIMES */
|
||||||
|
-#endif /* ! HAVE_GOOD_UTIME_H */
|
||||||
|
-
|
||||||
|
-#if ! defined (_WIN32) || defined (__CYGWIN32__)
|
||||||
|
-static int simple_copy (const char *, const char *);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/* The number of bytes to copy at once. */
|
||||||
|
#define COPY_BUF 8192
|
||||||
|
@@ -82,7 +77,6 @@ simple_copy (const char *from, const char *to)
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
-#endif /* __CYGWIN32__ or not _WIN32 */
|
||||||
|
|
||||||
|
/* Set the times of the file DESTINATION to be the same as those in
|
||||||
|
STATBUF. */
|
||||||
|
@@ -91,87 +85,52 @@ 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);
|
||||||
|
-#else /* ! HAVE_GOOD_UTIME_H */
|
||||||
|
-#ifndef HAVE_UTIMES
|
||||||
|
- long tb[2];
|
||||||
|
-
|
||||||
|
- tb[0] = statbuf->st_atime;
|
||||||
|
- tb[1] = statbuf->st_mtime;
|
||||||
|
- result = utime (destination, tb);
|
||||||
|
-#else /* HAVE_UTIMES */
|
||||||
|
- struct timeval tv[2];
|
||||||
|
-
|
||||||
|
- tv[0].tv_sec = statbuf->st_atime;
|
||||||
|
- tv[0].tv_usec = 0;
|
||||||
|
- tv[1].tv_sec = statbuf->st_mtime;
|
||||||
|
- tv[1].tv_usec = 0;
|
||||||
|
- result = utimes (destination, tv);
|
||||||
|
-#endif /* HAVE_UTIMES */
|
||||||
|
-#endif /* ! HAVE_GOOD_UTIME_H */
|
||||||
|
- }
|
||||||
|
+ struct utimbuf tb;
|
||||||
|
+
|
||||||
|
+ tb.actime = statbuf->st_atime;
|
||||||
|
+ tb.modtime = statbuf->st_mtime;
|
||||||
|
+ result = utime (destination, &tb);
|
||||||
|
+#elif defined HAVE_UTIMES
|
||||||
|
+ struct timeval tv[2];
|
||||||
|
+
|
||||||
|
+ tv[0].tv_sec = statbuf->st_atime;
|
||||||
|
+ tv[0].tv_usec = 0;
|
||||||
|
+ tv[1].tv_sec = statbuf->st_mtime;
|
||||||
|
+ tv[1].tv_usec = 0;
|
||||||
|
+ result = utimes (destination, tv);
|
||||||
|
+#else
|
||||||
|
+ long tb[2];
|
||||||
|
+
|
||||||
|
+ tb[0] = statbuf->st_atime;
|
||||||
|
+ tb[1] = statbuf->st_mtime;
|
||||||
|
+ result = utime (destination, tb);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Rename FROM to TO, copying if TO exists. TARGET_STAT has the file status
|
||||||
|
- that, if non-NULL, is used to fix up timestamps after rename. Return 0 if
|
||||||
|
- ok, -1 if error. */
|
||||||
|
+/* Copy FROM to TO. TARGET_STAT has the file status that, if non-NULL,
|
||||||
|
+ is used to fix up timestamps. Return 0 if ok, -1 if error.
|
||||||
|
+ At one time this function renamed files, but file permissions are
|
||||||
|
+ tricky to update given the number of different schemes used by
|
||||||
|
+ various systems. So now we just copy. */
|
||||||
|
|
||||||
|
int
|
||||||
|
smart_rename (const char *from, const char *to,
|
||||||
|
- struct stat *target_stat ATTRIBUTE_UNUSED)
|
||||||
|
+ struct stat *target_stat)
|
||||||
|
{
|
||||||
|
- int ret = 0;
|
||||||
|
- struct stat to_stat;
|
||||||
|
- bfd_boolean exists;
|
||||||
|
-
|
||||||
|
- exists = lstat (to, &to_stat) == 0;
|
||||||
|
-
|
||||||
|
-#if defined (_WIN32) && !defined (__CYGWIN32__)
|
||||||
|
- /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
|
||||||
|
- fail instead. Also, chown is not present. */
|
||||||
|
-
|
||||||
|
- if (exists)
|
||||||
|
- remove (to);
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
- ret = rename (from, to);
|
||||||
|
+ ret = simple_copy (from, to);
|
||||||
|
if (ret != 0)
|
||||||
|
- {
|
||||||
|
- /* We have to clean up here. */
|
||||||
|
- non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
|
||||||
|
- unlink (from);
|
||||||
|
- }
|
||||||
|
-#else
|
||||||
|
- /* Avoid a full copy and use rename if TO does not exist. */
|
||||||
|
- if (!exists)
|
||||||
|
- {
|
||||||
|
- if ((ret = rename (from, to)) != 0)
|
||||||
|
- {
|
||||||
|
- /* We have to clean up here. */
|
||||||
|
- non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
|
||||||
|
- unlink (from);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- ret = simple_copy (from, to);
|
||||||
|
- if (ret != 0)
|
||||||
|
- non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
|
||||||
|
+ non_fatal (_("unable to copy file '%s'; reason: %s"),
|
||||||
|
+ to, strerror (errno));
|
||||||
|
|
||||||
|
- if (target_stat != NULL)
|
||||||
|
- set_times (to, target_stat);
|
||||||
|
- unlink (from);
|
||||||
|
- }
|
||||||
|
-#endif /* _WIN32 && !__CYGWIN32__ */
|
||||||
|
+ if (target_stat != NULL)
|
||||||
|
+ set_times (to, target_stat);
|
||||||
|
+ unlink (from);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
Reference in New Issue
Block a user