diff options
author | Alan Modra <amodra@gmail.com> | 2021-02-01 02:04:41 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-02-03 13:30:28 +1030 |
commit | 95b91a043aeaeb546d2fea556d84a2de1e917770 (patch) | |
tree | f4d1b89f8cbd5afa631d7110b49dec23546cb25e /binutils/arsup.c | |
parent | 6955136728a68365bbb5e6e1327dff1654b2a0ca (diff) | |
download | gdb-95b91a043aeaeb546d2fea556d84a2de1e917770.zip gdb-95b91a043aeaeb546d2fea556d84a2de1e917770.tar.gz gdb-95b91a043aeaeb546d2fea556d84a2de1e917770.tar.bz2 |
pr27270 and pr27284, ar segfaults and wrong file mode
PR 27270
PR 27284
PR 26945
* ar.c: Don't include libbfd.h.
(write_archive): Replace xmalloc+strcpy with xstrdup. Use
bfd_stat rather than fstat on iostream. Move stat and fd tests
outside of _WIN32 ifdef. Delete skip_stat variable.
* 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. Move stat output
of _WIN32 ifdef.
* objcopy.c: Don't include libbfd.h.
(copy_file): Use bfd_stat.
Diffstat (limited to 'binutils/arsup.c')
-rw-r--r-- | binutils/arsup.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/binutils/arsup.c b/binutils/arsup.c index 837011b..a60629f 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,10 +343,9 @@ ar_save (void) } else { - char *ofilename = xstrdup (bfd_get_filename (obfd)); bfd_boolean skip_stat = FALSE; struct stat target_stat; - int ofd = -1; + int ofd = real_ofd; if (deterministic > 0) obfd->flags |= BFD_DETERMINISTIC_OUTPUT; @@ -355,17 +353,31 @@ ar_save (void) #if !defined (_WIN32) || defined (__CYGWIN32__) /* It's OK to fail; at worst it will result in SMART_RENAME using a slow copy fallback to write the output. */ - ofd = dup (fileno ((FILE *) obfd->iostream)); - if (lstat (real_name, &target_stat) != 0) - skip_stat = TRUE; + ofd = dup (ofd); #endif - bfd_close (obfd); - smart_rename (ofilename, real_name, ofd, + if (lstat (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_stat (obfd, &target_stat) != 0) + skip_stat = TRUE; + if (obfd != NULL) + { + bfd_set_format (obfd, bfd_archive); + bfd_close (obfd); + } + } + + smart_rename (temp_name, real_name, ofd, skip_stat ? NULL : &target_stat, 0); obfd = 0; - free (ofilename); + free (temp_name); + free (real_name); } } |