svn commit: r368286 - in stable: 11/contrib/elftoolchain/elfcopy 12/contrib/elftoolchain/elfcopy
Dimitry Andric
dim at FreeBSD.org
Wed Dec 2 21:44:42 UTC 2020
Author: dim
Date: Wed Dec 2 21:44:41 2020
New Revision: 368286
URL: https://svnweb.freebsd.org/changeset/base/368286
Log:
MFC r367809:
When elftoolchain's objcopy (or strip) is rewriting a file in-place,
make it create the temporary file in the same directory as the source
file by default, instead of always using $TMPDIR or /tmp. If creating
that file fails because the directory is not writable, also fallback to
$TMPDIR or /tmp.
This has also been submitted upstream as:
https://sourceforge.net/p/elftoolchain/tickets/597/
Reported by: cem
PR: 250872
Modified:
stable/12/contrib/elftoolchain/elfcopy/archive.c
stable/12/contrib/elftoolchain/elfcopy/elfcopy.h
stable/12/contrib/elftoolchain/elfcopy/main.c
Directory Properties:
stable/12/ (props changed)
Changes in other areas also in this revision:
Modified:
stable/11/contrib/elftoolchain/elfcopy/archive.c
stable/11/contrib/elftoolchain/elfcopy/elfcopy.h
stable/11/contrib/elftoolchain/elfcopy/main.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/12/contrib/elftoolchain/elfcopy/archive.c
==============================================================================
--- stable/12/contrib/elftoolchain/elfcopy/archive.c Wed Dec 2 21:39:54 2020 (r368285)
+++ stable/12/contrib/elftoolchain/elfcopy/archive.c Wed Dec 2 21:44:41 2020 (r368286)
@@ -68,7 +68,7 @@ process_ar_obj(struct elfcopy *ecp, struct ar_obj *obj
int fd;
/* Output to a temporary file. */
- create_tempfile(&tempfile, &fd);
+ create_tempfile(NULL, &tempfile, &fd);
if ((ecp->eout = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL)
errx(EXIT_FAILURE, "elf_begin() failed: %s",
elf_errmsg(-1));
Modified: stable/12/contrib/elftoolchain/elfcopy/elfcopy.h
==============================================================================
--- stable/12/contrib/elftoolchain/elfcopy/elfcopy.h Wed Dec 2 21:39:54 2020 (r368285)
+++ stable/12/contrib/elftoolchain/elfcopy/elfcopy.h Wed Dec 2 21:44:41 2020 (r368286)
@@ -298,7 +298,7 @@ void create_scn(struct elfcopy *_ecp);
void create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn);
void create_symtab(struct elfcopy *_ecp);
void create_symtab_data(struct elfcopy *_ecp);
-void create_tempfile(char **_fn, int *_fd);
+void create_tempfile(const char *_src, char **_fn, int *_fd);
void finalize_external_symtab(struct elfcopy *_ecp);
void free_elf(struct elfcopy *_ecp);
void free_sec_act(struct elfcopy *_ecp);
Modified: stable/12/contrib/elftoolchain/elfcopy/main.c
==============================================================================
--- stable/12/contrib/elftoolchain/elfcopy/main.c Wed Dec 2 21:39:54 2020 (r368285)
+++ stable/12/contrib/elftoolchain/elfcopy/main.c Wed Dec 2 21:44:41 2020 (r368286)
@@ -512,44 +512,57 @@ free_elf(struct elfcopy *ecp)
/* Create a temporary file. */
void
-create_tempfile(char **fn, int *fd)
+create_tempfile(const char *src, char **fn, int *fd)
{
+ static const char _TEMPDIR[] = "/tmp/";
+ static const char _TEMPFILE[] = "ecp.XXXXXXXX";
const char *tmpdir;
- char *cp, *tmpf;
- size_t tlen, plen;
+ char *tmpf;
+ size_t tlen, slen, plen;
-#define _TEMPFILE "ecp.XXXXXXXX"
-#define _TEMPFILEPATH "/tmp/ecp.XXXXXXXX"
-
if (fn == NULL || fd == NULL)
return;
- /* Repect TMPDIR environment variable. */
- tmpdir = getenv("TMPDIR");
- if (tmpdir != NULL && *tmpdir != '\0') {
- tlen = strlen(tmpdir);
- plen = strlen(_TEMPFILE);
- tmpf = malloc(tlen + plen + 2);
+ for (;;) {
+ if (src == NULL) {
+ /* Respect TMPDIR environment variable. */
+ tmpdir = getenv("TMPDIR");
+ if (tmpdir == NULL || *tmpdir == '\0')
+ tmpdir = _TEMPDIR;
+ tlen = strlen(tmpdir);
+ slen = tmpdir[tlen - 1] == '/' ? 0 : 1;
+ } else {
+ /* Create temporary file relative to source file. */
+ if ((tmpdir = strrchr(src, '/')) == NULL) {
+ /* No path, only use a template filename. */
+ tlen = 0;
+ } else {
+ /* Append the template after the slash. */
+ tlen = ++tmpdir - src;
+ tmpdir = src;
+ }
+ slen = 0;
+ }
+ plen = strlen(_TEMPFILE) + 1;
+ tmpf = malloc(tlen + slen + plen);
if (tmpf == NULL)
err(EXIT_FAILURE, "malloc failed");
- strncpy(tmpf, tmpdir, tlen);
- cp = &tmpf[tlen - 1];
- if (*cp++ != '/')
- *cp++ = '/';
- strncpy(cp, _TEMPFILE, plen);
- cp[plen] = '\0';
- } else {
- tmpf = strdup(_TEMPFILEPATH);
- if (tmpf == NULL)
- err(EXIT_FAILURE, "strdup failed");
+ if (tlen > 0)
+ memcpy(tmpf, tmpdir, tlen);
+ if (slen > 0)
+ tmpf[tlen] = '/';
+ /* Copy template filename including NUL terminator. */
+ memcpy(tmpf + tlen + slen, _TEMPFILE, plen);
+ if ((*fd = mkstemp(tmpf)) != -1)
+ break;
+ if (errno != EACCES || src == NULL)
+ err(EXIT_FAILURE, "mkstemp %s failed", tmpf);
+ /* Permission denied, try again using TMPDIR or /tmp. */
+ free(tmpf);
+ src = NULL;
}
- if ((*fd = mkstemp(tmpf)) == -1)
- err(EXIT_FAILURE, "mkstemp %s failed", tmpf);
if (fchmod(*fd, 0644) == -1)
err(EXIT_FAILURE, "fchmod %s failed", tmpf);
*fn = tmpf;
-
-#undef _TEMPFILE
-#undef _TEMPFILEPATH
}
/*
@@ -571,16 +584,16 @@ copy_from_tempfile(const char *src, const char *dst, i
if (rename(src, dst) >= 0) {
*outfd = infd;
return (0);
- } else if (errno != EXDEV)
+ } else if (errno != EXDEV && errno != EACCES)
return (-1);
-
+
/*
* If the rename() failed due to 'src' and 'dst' residing in
* two different file systems, invoke a helper function in
* libelftc to do the copy.
*/
- if (unlink(dst) < 0)
+ if (errno != EACCES && unlink(dst) < 0)
return (-1);
}
@@ -630,7 +643,7 @@ create_file(struct elfcopy *ecp, const char *src, cons
err(EXIT_FAILURE, "fstat %s failed", src);
if (dst == NULL)
- create_tempfile(&tempfile, &ofd);
+ create_tempfile(src, &tempfile, &ofd);
else
if ((ofd = open(dst, O_RDWR|O_CREAT, 0755)) == -1)
err(EXIT_FAILURE, "open %s failed", dst);
@@ -663,7 +676,7 @@ create_file(struct elfcopy *ecp, const char *src, cons
if (ecp->oed == ELFDATANONE)
ecp->oed = ELFDATA2LSB;
}
- create_tempfile(&elftemp, &efd);
+ create_tempfile(src, &elftemp, &efd);
if ((ecp->eout = elf_begin(efd, ELF_C_WRITE, NULL)) == NULL)
errx(EXIT_FAILURE, "elf_begin() failed: %s",
elf_errmsg(-1));
@@ -723,7 +736,7 @@ create_file(struct elfcopy *ecp, const char *src, cons
tempfile);
free(tempfile);
}
- create_tempfile(&tempfile, &ofd0);
+ create_tempfile(src, &tempfile, &ofd0);
/*
More information about the svn-src-all
mailing list