diff options
Diffstat (limited to 'src/ranlib.c')
-rw-r--r-- | src/ranlib.c | 50 |
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; } |