summaryrefslogtreecommitdiffstats
path: root/src/ranlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ranlib.c')
-rw-r--r--src/ranlib.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/src/ranlib.c b/src/ranlib.c
index b9083484..6e78671b 100644
--- a/src/ranlib.c
+++ b/src/ranlib.c
@@ -135,7 +135,7 @@ copy_content (Elf *elf, int newfd, off_t off, size_t n)
static int
handle_file (const char *fname)
{
- int fd = open (fname, O_RDONLY);
+ int fd = open (fname, O_RDONLY | O_BINARY);
if (fd == -1)
{
error (0, errno, gettext ("cannot open '%s'"), fname);
@@ -206,6 +206,9 @@ handle_file (const char *fname)
/* If the file contains no symbols we need not do anything. */
int status = 0;
+ char tmpfname[strlen (fname) + 7];
+ tmpfname[0] = '\0';
+
if (symtab.symsnamelen != 0
/* We have to rewrite the file also if it initially had an index
but now does not need one anymore. */
@@ -213,7 +216,6 @@ handle_file (const char *fname)
{
/* Create a new, temporary file in the same directory as the
original file. */
- char tmpfname[strlen (fname) + 7];
strcpy (stpcpy (tmpfname, fname), "XXXXXX");
int newfd = mkstemp (tmpfname);
if (unlikely (newfd == -1))
@@ -229,9 +231,9 @@ handle_file (const char *fname)
{
// XXX Use /prof/self/fd/%d ???
nonew_unlink:
- unlink (tmpfname);
if (newfd != -1)
close (newfd);
+ unlink (tmpfname);
goto nonew;
}
@@ -251,19 +253,23 @@ handle_file (const char *fname)
!= (ssize_t) symtab.symsofflen)
|| (write_retry (newfd, symtab.symsname,
symtab.symsnamelen)
- != (ssize_t) symtab.symsnamelen)))
+ != (ssize_t) symtab.symsnamelen))) ||
/* Even if the original file had content before the
symbol table, we write it in the correct order. */
- || (index_off > SARMAG
- && copy_content (arelf, newfd, SARMAG, index_off - SARMAG))
- || copy_content (arelf, newfd, rest_off, st.st_size - rest_off)
+ (index_off > SARMAG
+ && copy_content (arelf, newfd, SARMAG, index_off - SARMAG)) ||
+ copy_content (arelf, newfd, rest_off, st.st_size - rest_off) ||
+#if HAVE_DECL_FCHMOD
/* Set the mode of the new file to the same values the
original file has. */
- || fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ fchmod (newfd, st.st_mode & 07777) != 0 ||
+#endif
+ (
+#if HAVE_DECL_FCHOWN
/* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, fname) != 0))
+ ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
+#endif
+ close (newfd) != 0) || (newfd = -1, false))
goto nonew_unlink;
}
}
@@ -274,6 +280,28 @@ handle_file (const char *fname)
close (fd);
+ if (status == 0 && tmpfname[0])
+ {
+ char swapfname[strlen (fname) + 7];
+ strcpy (stpcpy (swapfname, fname), "XXXXXX");
+ mktemp (swapfname);
+ if (rename (fname, swapfname) != 0)
+ {
+ error (0, errno, gettext ("cannot move original file out of the way"));
+ status = 1;
+ }
+ if (rename (tmpfname, fname) != 0)
+ {
+ error (0, errno, gettext ("cannot move new file into place"));
+ if (rename (swapfname, fname) != 0)
+ error (0, errno, gettext ("cannot rescue original file"));
+ status = 1;
+ }
+ else
+ unlink (swapfname);
+ }
+
+ unlink (tmpfname);
return status;
}