mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 01:28:46 +00:00
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.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user